aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3191
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs115
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs29
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs56
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs45
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs86
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs37
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs378
19 files changed, 3235 insertions, 1042 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 47a9cdc..94fd940 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -305,6 +305,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
305 return null; 305 return null;
306 } 306 }
307 307
308 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
309 {
310 // Remove a specific script
311
312 // Remove dataserver events
313 m_Dataserver[engine].RemoveEvents(localID, itemID);
314
315 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
316 if (comms != null)
317 comms.DeleteListener(itemID);
318
319 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
320 xmlrpc.DeleteChannels(itemID);
321 xmlrpc.CancelSRDRequests(itemID);
322
323 // Remove Sensors
324 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
325
326 }
327
308 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 328 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
309 { 329 {
310 List<Object> data = new List<Object>(); 330 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..b5fa6de
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,116 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal TaskInventoryItem m_item;
63 internal bool m_CMFunctionsEnabled = false;
64
65 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
66 {
67 m_ScriptEngine = ScriptEngine;
68 m_host = host;
69 m_item = item;
70
71 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
72 m_CMFunctionsEnabled = true;
73 }
74
75 public override Object InitializeLifetimeService()
76 {
77 ILease lease = (ILease)base.InitializeLifetimeService();
78
79 if (lease.CurrentState == LeaseState.Initial)
80 {
81 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
82 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
83 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
84 }
85 return lease;
86 }
87
88 public Scene World
89 {
90 get { return m_ScriptEngine.World; }
91 }
92
93 public string cmDetectedCountry(int number)
94 {
95 m_host.AddScriptLPS(1);
96 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
97 if (detectedParams == null)
98 return String.Empty;
99 return detectedParams.Country;
100 }
101
102 public string cmGetAgentCountry(LSL_Key key)
103 {
104 if (!World.Permissions.IsGod(m_host.OwnerID))
105 return String.Empty;
106
107 UUID uuid;
108
109 if (!UUID.TryParse(key, out uuid))
110 return String.Empty;
111
112 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
113 return account.UserCountry;
114 }
115 }
116}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index ac74bf8..7cf193d 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;
@@ -66,6 +69,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
66using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 69using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
67using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 70using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
68using System.Reflection; 71using System.Reflection;
72using Timer = System.Timers.Timer;
69 73
70namespace OpenSim.Region.ScriptEngine.Shared.Api 74namespace OpenSim.Region.ScriptEngine.Shared.Api
71{ 75{
@@ -104,15 +108,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
104 protected int m_notecardLineReadCharsMax = 255; 108 protected int m_notecardLineReadCharsMax = 255;
105 protected int m_scriptConsoleChannel = 0; 109 protected int m_scriptConsoleChannel = 0;
106 protected bool m_scriptConsoleChannelEnabled = false; 110 protected bool m_scriptConsoleChannelEnabled = false;
111 protected bool m_debuggerSafe = false;
107 protected IUrlModule m_UrlModule = null; 112 protected IUrlModule m_UrlModule = null;
108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 113 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
109 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 114 new Dictionary<UUID, UserInfoCacheEntry>();
115 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
116
117// protected Timer m_ShoutSayTimer;
118 protected int m_SayShoutCount = 0;
119 DateTime m_lastSayShoutCheck;
120
121 private Dictionary<string, string> MovementAnimationsForLSL =
122 new Dictionary<string, string> {
123 {"FLY", "Flying"},
124 {"FLYSLOW", "FlyingSlow"},
125 {"HOVER_UP", "Hovering Up"},
126 {"HOVER_DOWN", "Hovering Down"},
127 {"HOVER", "Hovering"},
128 {"LAND", "Landing"},
129 {"FALLDOWN", "Falling Down"},
130 {"PREJUMP", "PreJumping"},
131 {"JUMP", "Jumping"},
132 {"STANDUP", "Standing Up"},
133 {"SOFT_LAND", "Soft Landing"},
134 {"STAND", "Standing"},
135 {"CROUCHWALK", "CrouchWalking"},
136 {"RUN", "Running"},
137 {"WALK", "Walking"},
138 {"CROUCH", "Crouching"},
139 {"TURNLEFT", "Turning Left"},
140 {"TURNRIGHT", "Turning Right"}
141 };
110 142
111 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
112 { 144 {
145/*
146 m_ShoutSayTimer = new Timer(1000);
147 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
148 m_ShoutSayTimer.AutoReset = true;
149 m_ShoutSayTimer.Start();
150*/
151 m_lastSayShoutCheck = DateTime.UtcNow;
152
113 m_ScriptEngine = ScriptEngine; 153 m_ScriptEngine = ScriptEngine;
114 m_host = host; 154 m_host = host;
115 m_item = item; 155 m_item = item;
156 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
116 157
117 LoadLimits(); // read script limits from config. 158 LoadLimits(); // read script limits from config.
118 159
@@ -172,6 +213,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
172 get { return m_ScriptEngine.World; } 213 get { return m_ScriptEngine.World; }
173 } 214 }
174 215
216 [DebuggerNonUserCode]
175 public void state(string newState) 217 public void state(string newState)
176 { 218 {
177 m_ScriptEngine.SetState(m_item.ItemID, newState); 219 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -181,6 +223,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
181 /// Reset the named script. The script must be present 223 /// Reset the named script. The script must be present
182 /// in the same prim. 224 /// in the same prim.
183 /// </summary> 225 /// </summary>
226 [DebuggerNonUserCode]
184 public void llResetScript() 227 public void llResetScript()
185 { 228 {
186 m_host.AddScriptLPS(1); 229 m_host.AddScriptLPS(1);
@@ -243,6 +286,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
243 } 286 }
244 } 287 }
245 288
289 public List<ScenePresence> GetLinkAvatars(int linkType)
290 {
291 List<ScenePresence> ret = new List<ScenePresence>();
292 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
293 return ret;
294
295 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
296
297 switch (linkType)
298 {
299 case ScriptBaseClass.LINK_SET:
300 return avs;
301
302 case ScriptBaseClass.LINK_ROOT:
303 return ret;
304
305 case ScriptBaseClass.LINK_ALL_OTHERS:
306 return avs;
307
308 case ScriptBaseClass.LINK_ALL_CHILDREN:
309 return avs;
310
311 case ScriptBaseClass.LINK_THIS:
312 return ret;
313
314 default:
315 if (linkType < 0)
316 return ret;
317
318 int partCount = m_host.ParentGroup.GetPartCount();
319
320 if (linkType <= partCount)
321 {
322 return ret;
323 }
324 else
325 {
326 linkType = linkType - partCount;
327 if (linkType > avs.Count)
328 {
329 return ret;
330 }
331 else
332 {
333 ret.Add(avs[linkType-1]);
334 return ret;
335 }
336 }
337 }
338 }
339
246 public List<SceneObjectPart> GetLinkParts(int linkType) 340 public List<SceneObjectPart> GetLinkParts(int linkType)
247 { 341 {
248 return GetLinkParts(m_host, linkType); 342 return GetLinkParts(m_host, linkType);
@@ -251,6 +345,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
251 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 345 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
252 { 346 {
253 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 347 List<SceneObjectPart> ret = new List<SceneObjectPart>();
348 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
349 return ret;
254 ret.Add(part); 350 ret.Add(part);
255 351
256 switch (linkType) 352 switch (linkType)
@@ -441,31 +537,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
441 537
442 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 538 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
443 539
444 /// <summary> 540 // Utility function for llRot2Euler
445 /// Convert an LSL rotation to a Euler vector. 541
446 /// </summary> 542 // normalize an angle between -PI and PI (-180 to +180 degrees)
447 /// <remarks> 543 protected double NormalizeAngle(double angle)
448 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
449 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
450 /// </remarks>
451 /// <param name="r"></param>
452 /// <returns></returns>
453 public LSL_Vector llRot2Euler(LSL_Rotation r)
454 { 544 {
455 m_host.AddScriptLPS(1); 545 if (angle > -Math.PI && angle < Math.PI)
546 return angle;
456 547
457 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 548 int numPis = (int)(Math.PI / angle);
458 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 549 double remainder = angle - Math.PI * numPis;
459 if (m == 0.0) return new LSL_Vector(); 550 if (numPis % 2 == 1)
460 double x = Math.Atan2(-v.y, v.z); 551 return Math.PI - angle;
461 double sin = v.x / m; 552 return remainder;
462 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 553 }
463 double y = Math.Asin(sin);
464 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
465 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)));
466 double z = Math.Atan2(v.y, v.x);
467 554
468 return new LSL_Vector(x, y, z); 555 public LSL_Vector llRot2Euler(LSL_Rotation q1)
556 {
557 m_host.AddScriptLPS(1);
558 LSL_Vector eul = new LSL_Vector();
559
560 double sqw = q1.s*q1.s;
561 double sqx = q1.x*q1.x;
562 double sqy = q1.z*q1.z;
563 double sqz = q1.y*q1.y;
564 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
565 double test = q1.x*q1.z + q1.y*q1.s;
566 if (test > 0.4999*unit) { // singularity at north pole
567 eul.z = 2 * Math.Atan2(q1.x,q1.s);
568 eul.y = Math.PI/2;
569 eul.x = 0;
570 return eul;
571 }
572 if (test < -0.4999*unit) { // singularity at south pole
573 eul.z = -2 * Math.Atan2(q1.x,q1.s);
574 eul.y = -Math.PI/2;
575 eul.x = 0;
576 return eul;
577 }
578 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
579 eul.y = Math.Asin(2*test/unit);
580 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
581 return eul;
469 } 582 }
470 583
471 /* From wiki: 584 /* From wiki:
@@ -518,18 +631,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
518 m_host.AddScriptLPS(1); 631 m_host.AddScriptLPS(1);
519 632
520 double x,y,z,s; 633 double x,y,z,s;
521 634 v.x *= 0.5;
522 double c1 = Math.Cos(v.x * 0.5); 635 v.y *= 0.5;
523 double c2 = Math.Cos(v.y * 0.5); 636 v.z *= 0.5;
524 double c3 = Math.Cos(v.z * 0.5); 637 double c1 = Math.Cos(v.x);
525 double s1 = Math.Sin(v.x * 0.5); 638 double c2 = Math.Cos(v.y);
526 double s2 = Math.Sin(v.y * 0.5); 639 double c1c2 = c1 * c2;
527 double s3 = Math.Sin(v.z * 0.5); 640 double s1 = Math.Sin(v.x);
528 641 double s2 = Math.Sin(v.y);
529 x = s1 * c2 * c3 + c1 * s2 * s3; 642 double s1s2 = s1 * s2;
530 y = c1 * s2 * c3 - s1 * c2 * s3; 643 double c1s2 = c1 * s2;
531 z = s1 * s2 * c3 + c1 * c2 * s3; 644 double s1c2 = s1 * c2;
532 s = c1 * c2 * c3 - s1 * s2 * s3; 645 double c3 = Math.Cos(v.z);
646 double s3 = Math.Sin(v.z);
647
648 x = s1c2 * c3 + c1s2 * s3;
649 y = c1s2 * c3 - s1c2 * s3;
650 z = s1s2 * c3 + c1c2 * s3;
651 s = c1c2 * c3 - s1s2 * s3;
533 652
534 return new LSL_Rotation(x, y, z, s); 653 return new LSL_Rotation(x, y, z, s);
535 } 654 }
@@ -667,77 +786,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
667 { 786 {
668 //A and B should both be normalized 787 //A and B should both be normalized
669 m_host.AddScriptLPS(1); 788 m_host.AddScriptLPS(1);
670 LSL_Rotation rotBetween; 789 /* This method is more accurate than the SL one, and thus causes problems
671 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 790 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
672 // continue calculation. 791
673 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 792 double dotProduct = LSL_Vector.Dot(a, b);
793 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
794 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
795 double angle = Math.Acos(dotProduct / magProduct);
796 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
797 double s = Math.Sin(angle / 2);
798
799 double x = axis.x * s;
800 double y = axis.y * s;
801 double z = axis.z * s;
802 double w = Math.Cos(angle / 2);
803
804 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
805 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
806
807 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
808 */
809
810 // This method mimics the 180 errors found in SL
811 // See www.euclideanspace.com... angleBetween
812 LSL_Vector vec_a = a;
813 LSL_Vector vec_b = b;
814
815 // Eliminate zero length
816 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
817 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
818 if (vec_a_mag < 0.00001 ||
819 vec_b_mag < 0.00001)
674 { 820 {
675 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 821 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
676 } 822 }
677 else 823
824 // Normalize
825 vec_a = llVecNorm(vec_a);
826 vec_b = llVecNorm(vec_b);
827
828 // Calculate axis and rotation angle
829 LSL_Vector axis = vec_a % vec_b;
830 LSL_Float cos_theta = vec_a * vec_b;
831
832 // Check if parallel
833 if (cos_theta > 0.99999)
678 { 834 {
679 a = LSL_Vector.Norm(a); 835 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
680 b = LSL_Vector.Norm(b); 836 }
681 double dotProduct = LSL_Vector.Dot(a, b); 837
682 // There are two degenerate cases possible. These are for vectors 180 or 838 // Check if anti-parallel
683 // 0 degrees apart. These have to be detected and handled individually. 839 else if (cos_theta < -0.99999)
684 // 840 {
685 // Check for vectors 180 degrees apart. 841 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
686 // A dot product of -1 would mean the angle between vectors is 180 degrees. 842 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
687 if (dotProduct < -0.9999999f) 843 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
688 { 844 }
689 // First assume X axis is orthogonal to the vectors. 845 else // other rotation
690 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 846 {
691 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 847 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
692 // Check for near zero vector. A very small non-zero number here will create 848 axis = llVecNorm(axis);
693 // a rotation in an undesired direction. 849 double x, y, z, s, t;
694 if (LSL_Vector.Mag(orthoVector) > 0.0001) 850 s = Math.Cos(theta);
695 { 851 t = Math.Sin(theta);
696 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 852 x = axis.x * t;
697 } 853 y = axis.y * t;
698 // If the magnitude of the vector was near zero, then assume the X axis is not 854 z = axis.z * t;
699 // orthogonal and use the Z axis instead. 855 return new LSL_Rotation(x,y,z,s);
700 else
701 {
702 // Set 180 z rotation.
703 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
704 }
705 }
706 // Check for parallel vectors.
707 // A dot product of 1 would mean the angle between vectors is 0 degrees.
708 else if (dotProduct > 0.9999999f)
709 {
710 // Set zero rotation.
711 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
712 }
713 else
714 {
715 // All special checks have been performed so get the axis of rotation.
716 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
717 // Quarternion s value is the length of the unit vector + dot product.
718 double qs = 1.0 + dotProduct;
719 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
720 // Normalize the rotation.
721 double mag = LSL_Rotation.Mag(rotBetween);
722 // We shouldn't have to worry about a divide by zero here. The qs value will be
723 // non-zero because we already know if we're here, then the dotProduct is not -1 so
724 // qs will not be zero. Also, we've already handled the input vectors being zero so the
725 // crossProduct vector should also not be zero.
726 rotBetween.x = rotBetween.x / mag;
727 rotBetween.y = rotBetween.y / mag;
728 rotBetween.z = rotBetween.z / mag;
729 rotBetween.s = rotBetween.s / mag;
730 // Check for undefined values and set zero rotation if any found. This code might not actually be required
731 // any longer since zero vectors are checked for at the top.
732 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
733 {
734 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
735 }
736 }
737 } 856 }
738 return rotBetween;
739 } 857 }
740 858
741 public void llWhisper(int channelID, string text) 859 public void llWhisper(int channelID, string text)
742 { 860 {
743 m_host.AddScriptLPS(1); 861 m_host.AddScriptLPS(1);
@@ -753,10 +871,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
753 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 871 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
754 } 872 }
755 873
874 private void CheckSayShoutTime()
875 {
876 DateTime now = DateTime.UtcNow;
877 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
878 {
879 m_lastSayShoutCheck = now;
880 m_SayShoutCount = 0;
881 }
882 else
883 m_SayShoutCount++;
884 }
885
756 public void llSay(int channelID, string text) 886 public void llSay(int channelID, string text)
757 { 887 {
758 m_host.AddScriptLPS(1); 888 m_host.AddScriptLPS(1);
759 889
890 if (channelID == 0)
891// m_SayShoutCount++;
892 CheckSayShoutTime();
893
894 if (m_SayShoutCount >= 11)
895 ScriptSleep(2000);
896
760 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 897 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
761 { 898 {
762 Console.WriteLine(text); 899 Console.WriteLine(text);
@@ -779,6 +916,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
779 { 916 {
780 m_host.AddScriptLPS(1); 917 m_host.AddScriptLPS(1);
781 918
919 if (channelID == 0)
920// m_SayShoutCount++;
921 CheckSayShoutTime();
922
923 if (m_SayShoutCount >= 11)
924 ScriptSleep(2000);
925
782 if (text.Length > 1023) 926 if (text.Length > 1023)
783 text = text.Substring(0, 1023); 927 text = text.Substring(0, 1023);
784 928
@@ -810,22 +954,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
810 954
811 public void llRegionSayTo(string target, int channel, string msg) 955 public void llRegionSayTo(string target, int channel, string msg)
812 { 956 {
957 string error = String.Empty;
958
813 if (msg.Length > 1023) 959 if (msg.Length > 1023)
814 msg = msg.Substring(0, 1023); 960 msg = msg.Substring(0, 1023);
815 961
816 m_host.AddScriptLPS(1); 962 m_host.AddScriptLPS(1);
817 963
818 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
819 {
820 return;
821 }
822
823 UUID TargetID; 964 UUID TargetID;
824 UUID.TryParse(target, out TargetID); 965 UUID.TryParse(target, out TargetID);
825 966
826 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 967 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
827 if (wComm != null) 968 if (wComm != null)
828 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 969 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
970 LSLError(error);
829 } 971 }
830 972
831 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 973 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1081,10 +1223,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1081 return detectedParams.TouchUV; 1223 return detectedParams.TouchUV;
1082 } 1224 }
1083 1225
1226 [DebuggerNonUserCode]
1084 public virtual void llDie() 1227 public virtual void llDie()
1085 { 1228 {
1086 m_host.AddScriptLPS(1); 1229 m_host.AddScriptLPS(1);
1087 throw new SelfDeleteException(); 1230 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1088 } 1231 }
1089 1232
1090 public LSL_Float llGround(LSL_Vector offset) 1233 public LSL_Float llGround(LSL_Vector offset)
@@ -1155,6 +1298,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1155 1298
1156 public void llSetStatus(int status, int value) 1299 public void llSetStatus(int status, int value)
1157 { 1300 {
1301 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1302 return;
1158 m_host.AddScriptLPS(1); 1303 m_host.AddScriptLPS(1);
1159 1304
1160 int statusrotationaxis = 0; 1305 int statusrotationaxis = 0;
@@ -1178,6 +1323,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1178 if (!allow) 1323 if (!allow)
1179 return; 1324 return;
1180 1325
1326 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1327 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1328 return;
1329
1181 m_host.ScriptSetPhysicsStatus(true); 1330 m_host.ScriptSetPhysicsStatus(true);
1182 } 1331 }
1183 else 1332 else
@@ -1377,6 +1526,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1377 { 1526 {
1378 m_host.AddScriptLPS(1); 1527 m_host.AddScriptLPS(1);
1379 1528
1529 SetColor(m_host, color, face);
1530 }
1531
1532 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1533 {
1534 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1535 return;
1536
1537 Primitive.TextureEntry tex = part.Shape.Textures;
1538 Color4 texcolor;
1539 if (face >= 0 && face < GetNumberOfSides(part))
1540 {
1541 texcolor = tex.CreateFace((uint)face).RGBA;
1542 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1543 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1544 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1545 tex.FaceTextures[face].RGBA = texcolor;
1546 part.UpdateTextureEntry(tex.GetBytes());
1547 return;
1548 }
1549 else if (face == ScriptBaseClass.ALL_SIDES)
1550 {
1551 for (uint i = 0; i < GetNumberOfSides(part); i++)
1552 {
1553 if (tex.FaceTextures[i] != null)
1554 {
1555 texcolor = tex.FaceTextures[i].RGBA;
1556 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1557 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1558 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1559 tex.FaceTextures[i].RGBA = texcolor;
1560 }
1561 texcolor = tex.DefaultTexture.RGBA;
1562 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1563 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1564 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1565 tex.DefaultTexture.RGBA = texcolor;
1566 }
1567 part.UpdateTextureEntry(tex.GetBytes());
1568 return;
1569 }
1570
1380 if (face == ScriptBaseClass.ALL_SIDES) 1571 if (face == ScriptBaseClass.ALL_SIDES)
1381 face = SceneObjectPart.ALL_SIDES; 1572 face = SceneObjectPart.ALL_SIDES;
1382 1573
@@ -1385,6 +1576,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1385 1576
1386 public void SetTexGen(SceneObjectPart part, int face,int style) 1577 public void SetTexGen(SceneObjectPart part, int face,int style)
1387 { 1578 {
1579 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1580 return;
1581
1388 Primitive.TextureEntry tex = part.Shape.Textures; 1582 Primitive.TextureEntry tex = part.Shape.Textures;
1389 MappingType textype; 1583 MappingType textype;
1390 textype = MappingType.Default; 1584 textype = MappingType.Default;
@@ -1415,6 +1609,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1415 1609
1416 public void SetGlow(SceneObjectPart part, int face, float glow) 1610 public void SetGlow(SceneObjectPart part, int face, float glow)
1417 { 1611 {
1612 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1613 return;
1614
1418 Primitive.TextureEntry tex = part.Shape.Textures; 1615 Primitive.TextureEntry tex = part.Shape.Textures;
1419 if (face >= 0 && face < GetNumberOfSides(part)) 1616 if (face >= 0 && face < GetNumberOfSides(part))
1420 { 1617 {
@@ -1440,6 +1637,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1440 1637
1441 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1638 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1442 { 1639 {
1640 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1641 return;
1443 1642
1444 Shininess sval = new Shininess(); 1643 Shininess sval = new Shininess();
1445 1644
@@ -1490,6 +1689,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1490 1689
1491 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1690 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1492 { 1691 {
1692 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1693 return;
1694
1493 Primitive.TextureEntry tex = part.Shape.Textures; 1695 Primitive.TextureEntry tex = part.Shape.Textures;
1494 if (face >= 0 && face < GetNumberOfSides(part)) 1696 if (face >= 0 && face < GetNumberOfSides(part))
1495 { 1697 {
@@ -1550,13 +1752,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1550 m_host.AddScriptLPS(1); 1752 m_host.AddScriptLPS(1);
1551 1753
1552 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1754 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1553 1755 if (parts.Count > 0)
1554 foreach (SceneObjectPart part in parts) 1756 {
1555 SetAlpha(part, alpha, face); 1757 try
1758 {
1759 foreach (SceneObjectPart part in parts)
1760 SetAlpha(part, alpha, face);
1761 }
1762 finally
1763 {
1764 }
1765 }
1556 } 1766 }
1557 1767
1558 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1768 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1559 { 1769 {
1770 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1771 return;
1772
1560 Primitive.TextureEntry tex = part.Shape.Textures; 1773 Primitive.TextureEntry tex = part.Shape.Textures;
1561 Color4 texcolor; 1774 Color4 texcolor;
1562 if (face >= 0 && face < GetNumberOfSides(part)) 1775 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1609,7 +1822,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1609 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1822 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1610 float wind, float tension, LSL_Vector Force) 1823 float wind, float tension, LSL_Vector Force)
1611 { 1824 {
1612 if (part == null) 1825 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1613 return; 1826 return;
1614 1827
1615 if (flexi) 1828 if (flexi)
@@ -1643,7 +1856,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1643 /// <param name="falloff"></param> 1856 /// <param name="falloff"></param>
1644 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1857 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1645 { 1858 {
1646 if (part == null) 1859 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1647 return; 1860 return;
1648 1861
1649 if (light) 1862 if (light)
@@ -1676,11 +1889,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1676 Primitive.TextureEntry tex = part.Shape.Textures; 1889 Primitive.TextureEntry tex = part.Shape.Textures;
1677 Color4 texcolor; 1890 Color4 texcolor;
1678 LSL_Vector rgb = new LSL_Vector(); 1891 LSL_Vector rgb = new LSL_Vector();
1892 int nsides = GetNumberOfSides(part);
1893
1679 if (face == ScriptBaseClass.ALL_SIDES) 1894 if (face == ScriptBaseClass.ALL_SIDES)
1680 { 1895 {
1681 int i; 1896 int i;
1682 1897 for (i = 0; i < nsides; i++)
1683 for (i = 0 ; i < GetNumberOfSides(part); i++)
1684 { 1898 {
1685 texcolor = tex.GetFace((uint)i).RGBA; 1899 texcolor = tex.GetFace((uint)i).RGBA;
1686 rgb.x += texcolor.R; 1900 rgb.x += texcolor.R;
@@ -1688,14 +1902,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1688 rgb.z += texcolor.B; 1902 rgb.z += texcolor.B;
1689 } 1903 }
1690 1904
1691 rgb.x /= (float)GetNumberOfSides(part); 1905 float invnsides = 1.0f / (float)nsides;
1692 rgb.y /= (float)GetNumberOfSides(part); 1906
1693 rgb.z /= (float)GetNumberOfSides(part); 1907 rgb.x *= invnsides;
1908 rgb.y *= invnsides;
1909 rgb.z *= invnsides;
1694 1910
1695 return rgb; 1911 return rgb;
1696 } 1912 }
1697 1913 if (face >= 0 && face < nsides)
1698 if (face >= 0 && face < GetNumberOfSides(part))
1699 { 1914 {
1700 texcolor = tex.GetFace((uint)face).RGBA; 1915 texcolor = tex.GetFace((uint)face).RGBA;
1701 rgb.x = texcolor.R; 1916 rgb.x = texcolor.R;
@@ -1722,15 +1937,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1722 m_host.AddScriptLPS(1); 1937 m_host.AddScriptLPS(1);
1723 1938
1724 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1939 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1725 1940 if (parts.Count > 0)
1726 foreach (SceneObjectPart part in parts) 1941 {
1727 SetTexture(part, texture, face); 1942 try
1728 1943 {
1944 foreach (SceneObjectPart part in parts)
1945 SetTexture(part, texture, face);
1946 }
1947 finally
1948 {
1949 }
1950 }
1729 ScriptSleep(200); 1951 ScriptSleep(200);
1730 } 1952 }
1731 1953
1732 protected void SetTexture(SceneObjectPart part, string texture, int face) 1954 protected void SetTexture(SceneObjectPart part, string texture, int face)
1733 { 1955 {
1956 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1957 return;
1958
1734 UUID textureID = new UUID(); 1959 UUID textureID = new UUID();
1735 1960
1736 textureID = InventoryKey(texture, (int)AssetType.Texture); 1961 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1775,6 +2000,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1775 2000
1776 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2001 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1777 { 2002 {
2003 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2004 return;
2005
1778 Primitive.TextureEntry tex = part.Shape.Textures; 2006 Primitive.TextureEntry tex = part.Shape.Textures;
1779 if (face >= 0 && face < GetNumberOfSides(part)) 2007 if (face >= 0 && face < GetNumberOfSides(part))
1780 { 2008 {
@@ -1811,6 +2039,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1811 2039
1812 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2040 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1813 { 2041 {
2042 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2043 return;
2044
1814 Primitive.TextureEntry tex = part.Shape.Textures; 2045 Primitive.TextureEntry tex = part.Shape.Textures;
1815 if (face >= 0 && face < GetNumberOfSides(part)) 2046 if (face >= 0 && face < GetNumberOfSides(part))
1816 { 2047 {
@@ -1847,6 +2078,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1847 2078
1848 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2079 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1849 { 2080 {
2081 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2082 return;
2083
1850 Primitive.TextureEntry tex = part.Shape.Textures; 2084 Primitive.TextureEntry tex = part.Shape.Textures;
1851 if (face >= 0 && face < GetNumberOfSides(part)) 2085 if (face >= 0 && face < GetNumberOfSides(part))
1852 { 2086 {
@@ -2017,24 +2251,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2017 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2251 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2018 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2252 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2019 { 2253 {
2020 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2254 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2255 return;
2256
2021 LSL_Vector currentPos = GetPartLocalPos(part); 2257 LSL_Vector currentPos = GetPartLocalPos(part);
2258 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2022 2259
2023 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2024 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2025 2260
2026 if (part.ParentGroup.RootPart == part) 2261 if (part.ParentGroup.RootPart == part)
2027 { 2262 {
2028 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2029 targetPos.z = ground;
2030 SceneObjectGroup parent = part.ParentGroup; 2263 SceneObjectGroup parent = part.ParentGroup;
2031 parent.UpdateGroupPosition(!adjust ? targetPos : 2264 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2032 SetPosAdjust(currentPos, targetPos)); 2265 return;
2266 Util.FireAndForget(delegate(object x) {
2267 parent.UpdateGroupPosition((Vector3)toPos);
2268 });
2033 } 2269 }
2034 else 2270 else
2035 { 2271 {
2036 part.OffsetPosition = !adjust ? targetPos : 2272 part.OffsetPosition = (Vector3)toPos;
2037 SetPosAdjust(currentPos, targetPos);
2038 SceneObjectGroup parent = part.ParentGroup; 2273 SceneObjectGroup parent = part.ParentGroup;
2039 parent.HasGroupChanged = true; 2274 parent.HasGroupChanged = true;
2040 parent.ScheduleGroupForTerseUpdate(); 2275 parent.ScheduleGroupForTerseUpdate();
@@ -2067,13 +2302,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2067 else 2302 else
2068 { 2303 {
2069 if (part.ParentGroup.IsAttachment) 2304 if (part.ParentGroup.IsAttachment)
2070 {
2071 pos = part.AttachedPos; 2305 pos = part.AttachedPos;
2072 }
2073 else 2306 else
2074 {
2075 pos = part.AbsolutePosition; 2307 pos = part.AbsolutePosition;
2076 }
2077 } 2308 }
2078 2309
2079// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2310// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2113,25 +2344,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2113 2344
2114 protected void SetRot(SceneObjectPart part, Quaternion rot) 2345 protected void SetRot(SceneObjectPart part, Quaternion rot)
2115 { 2346 {
2116 part.UpdateRotation(rot); 2347 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2117 // Update rotation does not move the object in the physics scene if it's a linkset. 2348 return;
2118 2349
2119//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2350 bool isroot = (part == part.ParentGroup.RootPart);
2120// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2351 bool isphys;
2121 2352
2122 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2123 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2124 // It's perfectly okay when the object is not an active physical body though.
2125 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2126 // but only if the object is not physial and active. This is important for rotating doors.
2127 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2128 // scene
2129 PhysicsActor pa = part.PhysActor; 2353 PhysicsActor pa = part.PhysActor;
2130 2354
2131 if (pa != null && !pa.IsPhysical) 2355 // keep using physactor ideia of isphysical
2356 // it should be SOP ideia of that
2357 // not much of a issue with ubitODE
2358 if (pa != null && pa.IsPhysical)
2359 isphys = true;
2360 else
2361 isphys = false;
2362
2363 // SL doesn't let scripts rotate root of physical linksets
2364 if (isroot && isphys)
2365 return;
2366
2367 part.UpdateRotation(rot);
2368
2369 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2370 // so do a nasty update of parts positions if is a root part rotation
2371 if (isroot && pa != null) // with if above implies non physical root part
2132 { 2372 {
2133 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2373 part.ParentGroup.ResetChildPrimPhysicsPositions();
2134 } 2374 }
2375 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2376 {
2377 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2378 if (sittingavas.Count > 0)
2379 {
2380 foreach (ScenePresence av in sittingavas)
2381 {
2382 if (isroot || part.LocalId == av.ParentID)
2383 av.SendTerseUpdateToAllClients();
2384 }
2385 }
2386 }
2135 } 2387 }
2136 2388
2137 /// <summary> 2389 /// <summary>
@@ -2179,8 +2431,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2179 2431
2180 public LSL_Rotation llGetLocalRot() 2432 public LSL_Rotation llGetLocalRot()
2181 { 2433 {
2434 return GetPartLocalRot(m_host);
2435 }
2436
2437 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2438 {
2182 m_host.AddScriptLPS(1); 2439 m_host.AddScriptLPS(1);
2183 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2440 Quaternion rot = part.RotationOffset;
2441 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2184 } 2442 }
2185 2443
2186 public void llSetForce(LSL_Vector force, int local) 2444 public void llSetForce(LSL_Vector force, int local)
@@ -2260,16 +2518,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2260 m_host.ApplyImpulse(v, local != 0); 2518 m_host.ApplyImpulse(v, local != 0);
2261 } 2519 }
2262 2520
2521
2263 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2522 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2264 { 2523 {
2265 m_host.AddScriptLPS(1); 2524 m_host.AddScriptLPS(1);
2266 m_host.ApplyAngularImpulse(force, local != 0); 2525 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2267 } 2526 }
2268 2527
2269 public void llSetTorque(LSL_Vector torque, int local) 2528 public void llSetTorque(LSL_Vector torque, int local)
2270 { 2529 {
2271 m_host.AddScriptLPS(1); 2530 m_host.AddScriptLPS(1);
2272 m_host.SetAngularImpulse(torque, local != 0); 2531 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2273 } 2532 }
2274 2533
2275 public LSL_Vector llGetTorque() 2534 public LSL_Vector llGetTorque()
@@ -2286,20 +2545,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2286 llSetTorque(torque, local); 2545 llSetTorque(torque, local);
2287 } 2546 }
2288 2547
2548 public void llSetVelocity(LSL_Vector vel, int local)
2549 {
2550 m_host.AddScriptLPS(1);
2551 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2552 }
2553
2289 public LSL_Vector llGetVel() 2554 public LSL_Vector llGetVel()
2290 { 2555 {
2291 m_host.AddScriptLPS(1); 2556 m_host.AddScriptLPS(1);
2292 2557
2293 Vector3 vel; 2558 Vector3 vel = Vector3.Zero;
2294 2559
2295 if (m_host.ParentGroup.IsAttachment) 2560 if (m_host.ParentGroup.IsAttachment)
2296 { 2561 {
2297 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2562 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2298 vel = avatar.Velocity; 2563 if (avatar != null)
2564 vel = avatar.Velocity;
2299 } 2565 }
2300 else 2566 else
2301 { 2567 {
2302 vel = m_host.Velocity; 2568 vel = m_host.ParentGroup.RootPart.Velocity;
2303 } 2569 }
2304 2570
2305 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2571 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2311,10 +2577,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2311 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2577 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2312 } 2578 }
2313 2579
2580 public void llSetAngularVelocity(LSL_Vector avel, int local)
2581 {
2582 m_host.AddScriptLPS(1);
2583 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2584 }
2585
2314 public LSL_Vector llGetOmega() 2586 public LSL_Vector llGetOmega()
2315 { 2587 {
2316 m_host.AddScriptLPS(1); 2588 m_host.AddScriptLPS(1);
2317 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2589 Vector3 avel = m_host.AngularVelocity;
2590 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2318 } 2591 }
2319 2592
2320 public LSL_Float llGetTimeOfDay() 2593 public LSL_Float llGetTimeOfDay()
@@ -2840,16 +3113,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2840 new_group.RootPart.UUID.ToString()) }, 3113 new_group.RootPart.UUID.ToString()) },
2841 new DetectParams[0])); 3114 new DetectParams[0]));
2842 3115
2843 float groupmass = new_group.GetMass(); 3116 // do recoil
3117 SceneObjectGroup hostgrp = m_host.ParentGroup;
3118 if (hostgrp == null)
3119 return;
3120
3121 if (hostgrp.IsAttachment) // don't recoil avatars
3122 return;
2844 3123
2845 PhysicsActor pa = new_group.RootPart.PhysActor; 3124 PhysicsActor pa = new_group.RootPart.PhysActor;
2846 3125
2847 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3126 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2848 { 3127 {
2849 //Recoil. 3128 float groupmass = new_group.GetMass();
2850 llApplyImpulse(vel * groupmass, 0); 3129 vel *= -groupmass;
3130 llApplyImpulse(vel, 0);
2851 } 3131 }
2852 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3132 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3133 return;
3134
2853 }); 3135 });
2854 3136
2855 //ScriptSleep((int)((groupmass * velmag) / 10)); 3137 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2864,35 +3146,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2864 public void llLookAt(LSL_Vector target, double strength, double damping) 3146 public void llLookAt(LSL_Vector target, double strength, double damping)
2865 { 3147 {
2866 m_host.AddScriptLPS(1); 3148 m_host.AddScriptLPS(1);
2867 // Determine where we are looking from
2868 LSL_Vector from = llGetPos();
2869 3149
2870 // Work out the normalised vector from the source to the target 3150 // Get the normalized vector to the target
2871 LSL_Vector delta = llVecNorm(target - from); 3151 LSL_Vector d1 = llVecNorm(target - llGetPos());
2872 LSL_Vector angle = new LSL_Vector(0,0,0);
2873 3152
2874 // Calculate the yaw 3153 // Get the bearing (yaw)
2875 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3154 LSL_Vector a1 = new LSL_Vector(0,0,0);
2876 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3155 a1.z = llAtan2(d1.y, d1.x);
2877 3156
2878 // Calculate pitch 3157 // Get the elevation (pitch)
2879 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3158 LSL_Vector a2 = new LSL_Vector(0,0,0);
3159 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2880 3160
2881 // we need to convert from a vector describing 3161 LSL_Rotation r1 = llEuler2Rot(a1);
2882 // the angles of rotation in radians into rotation value 3162 LSL_Rotation r2 = llEuler2Rot(a2);
2883 LSL_Rotation rot = llEuler2Rot(angle); 3163 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2884
2885 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2886 // set the rotation of the object, copy that behavior
2887 PhysicsActor pa = m_host.PhysActor;
2888 3164
2889 if (strength == 0 || pa == null || !pa.IsPhysical) 3165 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2890 { 3166 {
2891 llSetRot(rot); 3167 // Do nothing if either value is 0 (this has been checked in SL)
3168 if (strength <= 0.0 || damping <= 0.0)
3169 return;
3170
3171 llSetRot(r3 * r2 * r1);
2892 } 3172 }
2893 else 3173 else
2894 { 3174 {
2895 m_host.StartLookAt(rot, (float)strength, (float)damping); 3175 if (strength == 0)
3176 {
3177 llSetRot(r3 * r2 * r1);
3178 return;
3179 }
3180
3181 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2896 } 3182 }
2897 } 3183 }
2898 3184
@@ -2938,17 +3224,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2938 } 3224 }
2939 else 3225 else
2940 { 3226 {
2941 if (m_host.IsRoot) 3227 // new SL always returns object mass
2942 { 3228// if (m_host.IsRoot)
3229// {
2943 return m_host.ParentGroup.GetMass(); 3230 return m_host.ParentGroup.GetMass();
2944 } 3231// }
2945 else 3232// else
2946 { 3233// {
2947 return m_host.GetMass(); 3234// return m_host.GetMass();
2948 } 3235// }
2949 } 3236 }
2950 } 3237 }
2951 3238
3239
3240 public LSL_Float llGetMassMKS()
3241 {
3242 return 100f * llGetMass();
3243 }
3244
2952 public void llCollisionFilter(string name, string id, int accept) 3245 public void llCollisionFilter(string name, string id, int accept)
2953 { 3246 {
2954 m_host.AddScriptLPS(1); 3247 m_host.AddScriptLPS(1);
@@ -2996,8 +3289,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2996 { 3289 {
2997 // Unregister controls from Presence 3290 // Unregister controls from Presence
2998 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3291 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2999 // Remove Take Control permission.
3000 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3001 } 3292 }
3002 } 3293 }
3003 } 3294 }
@@ -3023,7 +3314,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3023 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3314 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3024 3315
3025 if (attachmentsModule != null) 3316 if (attachmentsModule != null)
3026 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3317 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3027 else 3318 else
3028 return false; 3319 return false;
3029 } 3320 }
@@ -3053,9 +3344,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3053 { 3344 {
3054 m_host.AddScriptLPS(1); 3345 m_host.AddScriptLPS(1);
3055 3346
3056// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3057// return;
3058
3059 if (m_item.PermsGranter != m_host.OwnerID) 3347 if (m_item.PermsGranter != m_host.OwnerID)
3060 return; 3348 return;
3061 3349
@@ -3098,6 +3386,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3098 3386
3099 public void llInstantMessage(string user, string message) 3387 public void llInstantMessage(string user, string message)
3100 { 3388 {
3389 UUID result;
3390 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3391 {
3392 ShoutError("An invalid key was passed to llInstantMessage");
3393 ScriptSleep(2000);
3394 return;
3395 }
3396
3397
3101 m_host.AddScriptLPS(1); 3398 m_host.AddScriptLPS(1);
3102 3399
3103 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3400 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3112,14 +3409,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3112 UUID friendTransactionID = UUID.Random(); 3409 UUID friendTransactionID = UUID.Random();
3113 3410
3114 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3411 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3115 3412
3116 GridInstantMessage msg = new GridInstantMessage(); 3413 GridInstantMessage msg = new GridInstantMessage();
3117 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3414 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3118 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3415 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3119 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3416 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3120// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3417// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3121// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3418// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3122 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3419// DateTime dt = DateTime.UtcNow;
3420//
3421// // Ticks from UtcNow, but make it look like local. Evil, huh?
3422// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3423//
3424// try
3425// {
3426// // Convert that to the PST timezone
3427// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3428// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3429// }
3430// catch
3431// {
3432// // No logging here, as it could be VERY spammy
3433// }
3434//
3435// // And make it look local again to fool the unix time util
3436// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3437
3438 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3439
3123 //if (client != null) 3440 //if (client != null)
3124 //{ 3441 //{
3125 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3442 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3133,12 +3450,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3133 msg.message = message.Substring(0, 1024); 3450 msg.message = message.Substring(0, 1024);
3134 else 3451 else
3135 msg.message = message; 3452 msg.message = message;
3136 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3453 msg.dialog = (byte)19; // MessageFromObject
3137 msg.fromGroup = false;// fromGroup; 3454 msg.fromGroup = false;// fromGroup;
3138 msg.offline = (byte)0; //offline; 3455 msg.offline = (byte)0; //offline;
3139 msg.ParentEstateID = 0; //ParentEstateID; 3456 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3140 msg.Position = new Vector3(m_host.AbsolutePosition); 3457 msg.Position = new Vector3(m_host.AbsolutePosition);
3141 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3458 msg.RegionID = World.RegionInfo.RegionID.Guid;
3142 msg.binaryBucket 3459 msg.binaryBucket
3143 = Util.StringToBytes256( 3460 = Util.StringToBytes256(
3144 "{0}/{1}/{2}/{3}", 3461 "{0}/{1}/{2}/{3}",
@@ -3166,7 +3483,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3166 } 3483 }
3167 3484
3168 emailModule.SendEmail(m_host.UUID, address, subject, message); 3485 emailModule.SendEmail(m_host.UUID, address, subject, message);
3169 llSleep(EMAIL_PAUSE_TIME); 3486 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3170 } 3487 }
3171 3488
3172 public void llGetNextEmail(string address, string subject) 3489 public void llGetNextEmail(string address, string subject)
@@ -3412,7 +3729,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3412 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3729 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3413 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3730 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3414 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3731 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3732 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3415 ScriptBaseClass.PERMISSION_ATTACH; 3733 ScriptBaseClass.PERMISSION_ATTACH;
3734
3416 } 3735 }
3417 else 3736 else
3418 { 3737 {
@@ -3447,11 +3766,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3447 3766
3448 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3767 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3449 { 3768 {
3450 lock (m_host.TaskInventory) 3769 m_host.TaskInventory.LockItemsForWrite(true);
3451 { 3770 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3452 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3771 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3453 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3772 m_host.TaskInventory.LockItemsForWrite(false);
3454 }
3455 3773
3456 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3774 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3457 "run_time_permissions", new Object[] { 3775 "run_time_permissions", new Object[] {
@@ -3494,11 +3812,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3494 3812
3495 if (!m_waitingForScriptAnswer) 3813 if (!m_waitingForScriptAnswer)
3496 { 3814 {
3497 lock (m_host.TaskInventory) 3815 m_host.TaskInventory.LockItemsForWrite(true);
3498 { 3816 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3499 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3817 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3500 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3818 m_host.TaskInventory.LockItemsForWrite(false);
3501 }
3502 3819
3503 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3820 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3504 m_waitingForScriptAnswer=true; 3821 m_waitingForScriptAnswer=true;
@@ -3527,14 +3844,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3527 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3844 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3528 llReleaseControls(); 3845 llReleaseControls();
3529 3846
3530 lock (m_host.TaskInventory) 3847 m_host.TaskInventory.LockItemsForWrite(true);
3531 { 3848 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3532 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3849 m_host.TaskInventory.LockItemsForWrite(false);
3533 } 3850
3534 3851 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3535 m_ScriptEngine.PostScriptEvent( 3852 "run_time_permissions", new Object[] {
3536 m_item.ItemID, 3853 new LSL_Integer(answer) },
3537 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3854 new DetectParams[0]));
3538 } 3855 }
3539 3856
3540 public LSL_String llGetPermissionsKey() 3857 public LSL_String llGetPermissionsKey()
@@ -3573,14 +3890,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3573 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3890 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3574 { 3891 {
3575 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3892 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3576 3893 if (parts.Count > 0)
3577 foreach (SceneObjectPart part in parts) 3894 {
3578 part.SetFaceColorAlpha(face, color, null); 3895 try
3896 {
3897 foreach (SceneObjectPart part in parts)
3898 part.SetFaceColorAlpha(face, color, null);
3899 }
3900 finally
3901 {
3902 }
3903 }
3579 } 3904 }
3580 3905
3581 public void llCreateLink(string target, int parent) 3906 public void llCreateLink(string target, int parent)
3582 { 3907 {
3583 m_host.AddScriptLPS(1); 3908 m_host.AddScriptLPS(1);
3909
3584 UUID targetID; 3910 UUID targetID;
3585 3911
3586 if (!UUID.TryParse(target, out targetID)) 3912 if (!UUID.TryParse(target, out targetID))
@@ -3686,10 +4012,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3686 // Restructuring Multiple Prims. 4012 // Restructuring Multiple Prims.
3687 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4013 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3688 parts.Remove(parentPrim.RootPart); 4014 parts.Remove(parentPrim.RootPart);
3689 foreach (SceneObjectPart part in parts) 4015 if (parts.Count > 0)
3690 { 4016 {
3691 parentPrim.DelinkFromGroup(part.LocalId, true); 4017 try
4018 {
4019 foreach (SceneObjectPart part in parts)
4020 {
4021 parentPrim.DelinkFromGroup(part.LocalId, true);
4022 }
4023 }
4024 finally
4025 {
4026 }
3692 } 4027 }
4028
3693 parentPrim.HasGroupChanged = true; 4029 parentPrim.HasGroupChanged = true;
3694 parentPrim.ScheduleGroupForFullUpdate(); 4030 parentPrim.ScheduleGroupForFullUpdate();
3695 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4031 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3698,12 +4034,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3698 { 4034 {
3699 SceneObjectPart newRoot = parts[0]; 4035 SceneObjectPart newRoot = parts[0];
3700 parts.Remove(newRoot); 4036 parts.Remove(newRoot);
3701 foreach (SceneObjectPart part in parts) 4037
4038 try
3702 { 4039 {
3703 // Required for linking 4040 foreach (SceneObjectPart part in parts)
3704 part.ClearUpdateSchedule(); 4041 {
3705 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4042 part.ClearUpdateSchedule();
4043 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4044 }
3706 } 4045 }
4046 finally
4047 {
4048 }
4049
4050
3707 newRoot.ParentGroup.HasGroupChanged = true; 4051 newRoot.ParentGroup.HasGroupChanged = true;
3708 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4052 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3709 } 4053 }
@@ -3723,6 +4067,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3723 public void llBreakAllLinks() 4067 public void llBreakAllLinks()
3724 { 4068 {
3725 m_host.AddScriptLPS(1); 4069 m_host.AddScriptLPS(1);
4070
4071 TaskInventoryItem item = m_item;
4072
4073 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4074 && !m_automaticLinkPermission)
4075 {
4076 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4077 return;
4078 }
4079
3726 SceneObjectGroup parentPrim = m_host.ParentGroup; 4080 SceneObjectGroup parentPrim = m_host.ParentGroup;
3727 if (parentPrim.AttachmentPoint != 0) 4081 if (parentPrim.AttachmentPoint != 0)
3728 return; // Fail silently if attached 4082 return; // Fail silently if attached
@@ -3742,25 +4096,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3742 public LSL_String llGetLinkKey(int linknum) 4096 public LSL_String llGetLinkKey(int linknum)
3743 { 4097 {
3744 m_host.AddScriptLPS(1); 4098 m_host.AddScriptLPS(1);
3745 List<UUID> keytable = new List<UUID>();
3746 // parse for sitting avatare-uuids
3747 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3748 {
3749 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3750 keytable.Add(presence.UUID);
3751 });
3752
3753 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3754 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3755 {
3756 return keytable[totalprims - linknum].ToString();
3757 }
3758
3759 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3760 {
3761 return m_host.UUID.ToString();
3762 }
3763
3764 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4099 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3765 if (part != null) 4100 if (part != null)
3766 { 4101 {
@@ -3768,6 +4103,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3768 } 4103 }
3769 else 4104 else
3770 { 4105 {
4106 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4107 {
4108 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4109
4110 if (linknum < 0)
4111 return UUID.Zero.ToString();
4112
4113 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4114 if (avatars.Count > linknum)
4115 {
4116 return avatars[linknum].UUID.ToString();
4117 }
4118 }
3771 return UUID.Zero.ToString(); 4119 return UUID.Zero.ToString();
3772 } 4120 }
3773 } 4121 }
@@ -3867,17 +4215,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3867 m_host.AddScriptLPS(1); 4215 m_host.AddScriptLPS(1);
3868 int count = 0; 4216 int count = 0;
3869 4217
3870 lock (m_host.TaskInventory) 4218 m_host.TaskInventory.LockItemsForRead(true);
4219 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3871 { 4220 {
3872 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4221 if (inv.Value.Type == type || type == -1)
3873 { 4222 {
3874 if (inv.Value.Type == type || type == -1) 4223 count = count + 1;
3875 {
3876 count = count + 1;
3877 }
3878 } 4224 }
3879 } 4225 }
3880 4226
4227 m_host.TaskInventory.LockItemsForRead(false);
3881 return count; 4228 return count;
3882 } 4229 }
3883 4230
@@ -3886,16 +4233,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3886 m_host.AddScriptLPS(1); 4233 m_host.AddScriptLPS(1);
3887 ArrayList keys = new ArrayList(); 4234 ArrayList keys = new ArrayList();
3888 4235
3889 lock (m_host.TaskInventory) 4236 m_host.TaskInventory.LockItemsForRead(true);
4237 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3890 { 4238 {
3891 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4239 if (inv.Value.Type == type || type == -1)
3892 { 4240 {
3893 if (inv.Value.Type == type || type == -1) 4241 keys.Add(inv.Value.Name);
3894 {
3895 keys.Add(inv.Value.Name);
3896 }
3897 } 4242 }
3898 } 4243 }
4244 m_host.TaskInventory.LockItemsForRead(false);
3899 4245
3900 if (keys.Count == 0) 4246 if (keys.Count == 0)
3901 { 4247 {
@@ -3933,7 +4279,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3933 if (item == null) 4279 if (item == null)
3934 { 4280 {
3935 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4281 llSay(0, String.Format("Could not find object '{0}'", inventory));
3936 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4282 return;
4283// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3937 } 4284 }
3938 4285
3939 UUID objId = item.ItemID; 4286 UUID objId = item.ItemID;
@@ -3961,33 +4308,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3961 return; 4308 return;
3962 } 4309 }
3963 } 4310 }
4311
3964 // destination is an avatar 4312 // destination is an avatar
3965 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4313 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3966 4314
3967 if (agentItem == null) 4315 if (agentItem == null)
3968 return; 4316 return;
3969 4317
3970 if (m_TransferModule != null) 4318 byte[] bucket = new byte[1];
3971 { 4319 bucket[0] = (byte)item.Type;
3972 byte[] bucket = new byte[] { (byte)item.Type }; 4320 //byte[] objBytes = agentItem.ID.GetBytes();
4321 //Array.Copy(objBytes, 0, bucket, 1, 16);
4322
4323 GridInstantMessage msg = new GridInstantMessage(World,
4324 m_host.OwnerID, m_host.Name, destId,
4325 (byte)InstantMessageDialog.TaskInventoryOffered,
4326 false, item.Name+". "+m_host.Name+" is located at "+
4327 World.RegionInfo.RegionName+" "+
4328 m_host.AbsolutePosition.ToString(),
4329 agentItem.ID, true, m_host.AbsolutePosition,
4330 bucket, true);
3973 4331
3974 GridInstantMessage msg = new GridInstantMessage(World, 4332 ScenePresence sp;
3975 m_host.UUID, m_host.Name + ", an object owned by " +
3976 resolveName(m_host.OwnerID) + ",", destId,
3977 (byte)InstantMessageDialog.TaskInventoryOffered,
3978 false, item.Name + "\n" + m_host.Name + " is located at " +
3979 World.RegionInfo.RegionName+" "+
3980 m_host.AbsolutePosition.ToString(),
3981 agentItem.ID, true, m_host.AbsolutePosition,
3982 bucket, true); // TODO: May actually send no timestamp
3983 4333
3984 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4334 if (World.TryGetScenePresence(destId, out sp))
4335 {
4336 sp.ControllingClient.SendInstantMessage(msg);
3985 } 4337 }
3986 4338 else
4339 {
4340 if (m_TransferModule != null)
4341 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4342 }
4343
4344 //This delay should only occur when giving inventory to avatars.
3987 ScriptSleep(3000); 4345 ScriptSleep(3000);
3988 } 4346 }
3989 } 4347 }
3990 4348
4349 [DebuggerNonUserCode]
3991 public void llRemoveInventory(string name) 4350 public void llRemoveInventory(string name)
3992 { 4351 {
3993 m_host.AddScriptLPS(1); 4352 m_host.AddScriptLPS(1);
@@ -4042,109 +4401,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4042 { 4401 {
4043 m_host.AddScriptLPS(1); 4402 m_host.AddScriptLPS(1);
4044 4403
4045 UUID uuid = (UUID)id; 4404 UUID uuid;
4046 PresenceInfo pinfo = null; 4405 if (UUID.TryParse(id, out uuid))
4047 UserAccount account;
4048
4049 UserInfoCacheEntry ce;
4050 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4051 { 4406 {
4052 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4407 PresenceInfo pinfo = null;
4053 if (account == null) 4408 UserAccount account;
4409
4410 UserInfoCacheEntry ce;
4411 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4054 { 4412 {
4055 m_userInfoCache[uuid] = null; // Cache negative 4413 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4056 return UUID.Zero.ToString(); 4414 if (account == null)
4057 } 4415 {
4416 m_userInfoCache[uuid] = null; // Cache negative
4417 return UUID.Zero.ToString();
4418 }
4058 4419
4059 4420
4060 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4421 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4061 if (pinfos != null && pinfos.Length > 0) 4422 if (pinfos != null && pinfos.Length > 0)
4062 {
4063 foreach (PresenceInfo p in pinfos)
4064 { 4423 {
4065 if (p.RegionID != UUID.Zero) 4424 foreach (PresenceInfo p in pinfos)
4066 { 4425 {
4067 pinfo = p; 4426 if (p.RegionID != UUID.Zero)
4427 {
4428 pinfo = p;
4429 }
4068 } 4430 }
4069 } 4431 }
4070 }
4071 4432
4072 ce = new UserInfoCacheEntry(); 4433 ce = new UserInfoCacheEntry();
4073 ce.time = Util.EnvironmentTickCount(); 4434 ce.time = Util.EnvironmentTickCount();
4074 ce.account = account; 4435 ce.account = account;
4075 ce.pinfo = pinfo; 4436 ce.pinfo = pinfo;
4076 } 4437 m_userInfoCache[uuid] = ce;
4077 else 4438 }
4078 { 4439 else
4079 if (ce == null) 4440 {
4080 return UUID.Zero.ToString(); 4441 if (ce == null)
4442 return UUID.Zero.ToString();
4081 4443
4082 account = ce.account; 4444 account = ce.account;
4083 pinfo = ce.pinfo; 4445 pinfo = ce.pinfo;
4084 } 4446 }
4085 4447
4086 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4448 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4087 {
4088 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4089 if (pinfos != null && pinfos.Length > 0)
4090 { 4449 {
4091 foreach (PresenceInfo p in pinfos) 4450 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4451 if (pinfos != null && pinfos.Length > 0)
4092 { 4452 {
4093 if (p.RegionID != UUID.Zero) 4453 foreach (PresenceInfo p in pinfos)
4094 { 4454 {
4095 pinfo = p; 4455 if (p.RegionID != UUID.Zero)
4456 {
4457 pinfo = p;
4458 }
4096 } 4459 }
4097 } 4460 }
4098 } 4461 else
4099 else 4462 pinfo = null;
4100 pinfo = null;
4101 4463
4102 ce.time = Util.EnvironmentTickCount(); 4464 ce.time = Util.EnvironmentTickCount();
4103 ce.pinfo = pinfo; 4465 ce.pinfo = pinfo;
4104 } 4466 }
4105 4467
4106 string reply = String.Empty; 4468 string reply = String.Empty;
4107 4469
4108 switch (data) 4470 switch (data)
4109 { 4471 {
4110 case 1: // DATA_ONLINE (0|1) 4472 case 1: // DATA_ONLINE (0|1)
4111 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4473 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4112 reply = "1"; 4474 reply = "1";
4113 else 4475 else
4114 reply = "0"; 4476 reply = "0";
4115 break; 4477 break;
4116 case 2: // DATA_NAME (First Last) 4478 case 2: // DATA_NAME (First Last)
4117 reply = account.FirstName + " " + account.LastName; 4479 reply = account.FirstName + " " + account.LastName;
4118 break; 4480 break;
4119 case 3: // DATA_BORN (YYYY-MM-DD) 4481 case 3: // DATA_BORN (YYYY-MM-DD)
4120 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4482 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4121 born = born.AddSeconds(account.Created); 4483 born = born.AddSeconds(account.Created);
4122 reply = born.ToString("yyyy-MM-dd"); 4484 reply = born.ToString("yyyy-MM-dd");
4123 break; 4485 break;
4124 case 4: // DATA_RATING (0,0,0,0,0,0) 4486 case 4: // DATA_RATING (0,0,0,0,0,0)
4125 reply = "0,0,0,0,0,0"; 4487 reply = "0,0,0,0,0,0";
4126 break; 4488 break;
4127 case 7: // DATA_USERLEVEL (integer) 4489 case 8: // DATA_PAYINFO (0|1|2|3)
4128 reply = account.UserLevel.ToString(); 4490 reply = "0";
4129 break; 4491 break;
4130 case 8: // DATA_PAYINFO (0|1|2|3) 4492 default:
4131 reply = "0"; 4493 return UUID.Zero.ToString(); // Raise no event
4132 break; 4494 }
4133 default:
4134 return UUID.Zero.ToString(); // Raise no event
4135 }
4136 4495
4137 UUID rq = UUID.Random(); 4496 UUID rq = UUID.Random();
4138 4497
4139 UUID tid = AsyncCommands. 4498 UUID tid = AsyncCommands.
4140 DataserverPlugin.RegisterRequest(m_host.LocalId, 4499 DataserverPlugin.RegisterRequest(m_host.LocalId,
4141 m_item.ItemID, rq.ToString()); 4500 m_item.ItemID, rq.ToString());
4142 4501
4143 AsyncCommands. 4502 AsyncCommands.
4144 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4503 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4145 4504
4146 ScriptSleep(100); 4505 ScriptSleep(100);
4147 return tid.ToString(); 4506 return tid.ToString();
4507 }
4508 else
4509 {
4510 ShoutError("Invalid UUID passed to llRequestAgentData.");
4511 }
4512 return "";
4148 } 4513 }
4149 4514
4150 public LSL_String llRequestInventoryData(string name) 4515 public LSL_String llRequestInventoryData(string name)
@@ -4201,13 +4566,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4201 if (UUID.TryParse(agent, out agentId)) 4566 if (UUID.TryParse(agent, out agentId))
4202 { 4567 {
4203 ScenePresence presence = World.GetScenePresence(agentId); 4568 ScenePresence presence = World.GetScenePresence(agentId);
4204 if (presence != null) 4569 if (presence != null && presence.PresenceType != PresenceType.Npc)
4205 { 4570 {
4571 // agent must not be a god
4572 if (presence.UserLevel >= 200) return;
4573
4206 // agent must be over the owners land 4574 // agent must be over the owners land
4207 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4575 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4208 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4576 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4209 { 4577 {
4210 World.TeleportClientHome(agentId, presence.ControllingClient); 4578 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4579 {
4580 // They can't be teleported home for some reason
4581 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4582 if (regionInfo != null)
4583 {
4584 World.RequestTeleportLocation(
4585 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4586 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4587 }
4588 }
4211 } 4589 }
4212 } 4590 }
4213 } 4591 }
@@ -4314,7 +4692,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4314 UUID av = new UUID(); 4692 UUID av = new UUID();
4315 if (!UUID.TryParse(agent,out av)) 4693 if (!UUID.TryParse(agent,out av))
4316 { 4694 {
4317 LSLError("First parameter to llDialog needs to be a key"); 4695 //LSLError("First parameter to llDialog needs to be a key");
4318 return; 4696 return;
4319 } 4697 }
4320 4698
@@ -4346,7 +4724,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4346 public void llCollisionSound(string impact_sound, double impact_volume) 4724 public void llCollisionSound(string impact_sound, double impact_volume)
4347 { 4725 {
4348 m_host.AddScriptLPS(1); 4726 m_host.AddScriptLPS(1);
4349 4727
4728 if(impact_sound == "")
4729 {
4730 m_host.CollisionSoundVolume = (float)impact_volume;
4731 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4732 m_host.CollisionSoundType = 0;
4733 return;
4734 }
4350 // TODO: Parameter check logic required. 4735 // TODO: Parameter check logic required.
4351 UUID soundId = UUID.Zero; 4736 UUID soundId = UUID.Zero;
4352 if (!UUID.TryParse(impact_sound, out soundId)) 4737 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4359,6 +4744,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4359 4744
4360 m_host.CollisionSound = soundId; 4745 m_host.CollisionSound = soundId;
4361 m_host.CollisionSoundVolume = (float)impact_volume; 4746 m_host.CollisionSoundVolume = (float)impact_volume;
4747 m_host.CollisionSoundType = 1;
4362 } 4748 }
4363 4749
4364 public LSL_String llGetAnimation(string id) 4750 public LSL_String llGetAnimation(string id)
@@ -4372,14 +4758,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4372 4758
4373 if (m_host.RegionHandle == presence.RegionHandle) 4759 if (m_host.RegionHandle == presence.RegionHandle)
4374 { 4760 {
4375 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4376
4377 if (presence != null) 4761 if (presence != null)
4378 { 4762 {
4379 AnimationSet currentAnims = presence.Animator.Animations; 4763 if (presence.SitGround)
4380 string currentAnimationState = String.Empty; 4764 return "Sitting on Ground";
4381 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4765 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4382 return currentAnimationState; 4766 return "Sitting";
4767
4768 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4769 string lslMovementAnimation;
4770
4771 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4772 return lslMovementAnimation;
4383 } 4773 }
4384 } 4774 }
4385 4775
@@ -4526,7 +4916,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4526 { 4916 {
4527 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4917 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4528 float distance_term = distance * distance * distance; // Script Energy 4918 float distance_term = distance * distance * distance; // Script Energy
4529 float pusher_mass = m_host.GetMass(); 4919 // use total object mass and not part
4920 float pusher_mass = m_host.ParentGroup.GetMass();
4530 4921
4531 float PUSH_ATTENUATION_DISTANCE = 17f; 4922 float PUSH_ATTENUATION_DISTANCE = 17f;
4532 float PUSH_ATTENUATION_SCALE = 5f; 4923 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4776,6 +5167,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4776 { 5167 {
4777 return item.AssetID.ToString(); 5168 return item.AssetID.ToString();
4778 } 5169 }
5170 m_host.TaskInventory.LockItemsForRead(false);
4779 5171
4780 return UUID.Zero.ToString(); 5172 return UUID.Zero.ToString();
4781 } 5173 }
@@ -4909,7 +5301,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4909 public LSL_Vector llGetCenterOfMass() 5301 public LSL_Vector llGetCenterOfMass()
4910 { 5302 {
4911 m_host.AddScriptLPS(1); 5303 m_host.AddScriptLPS(1);
4912 Vector3 center = m_host.GetGeometricCenter(); 5304 Vector3 center = m_host.GetCenterOfMass();
4913 return new LSL_Vector(center.X,center.Y,center.Z); 5305 return new LSL_Vector(center.X,center.Y,center.Z);
4914 } 5306 }
4915 5307
@@ -4928,14 +5320,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4928 { 5320 {
4929 m_host.AddScriptLPS(1); 5321 m_host.AddScriptLPS(1);
4930 5322
4931 if (src == null) 5323 return src.Length;
4932 {
4933 return 0;
4934 }
4935 else
4936 {
4937 return src.Length;
4938 }
4939 } 5324 }
4940 5325
4941 public LSL_Integer llList2Integer(LSL_List src, int index) 5326 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5006,7 +5391,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5006 else if (src.Data[index] is LSL_Float) 5391 else if (src.Data[index] is LSL_Float)
5007 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5392 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5008 else if (src.Data[index] is LSL_String) 5393 else if (src.Data[index] is LSL_String)
5009 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5394 {
5395 string str = ((LSL_String) src.Data[index]).m_string;
5396 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5397 if (m != Match.Empty)
5398 {
5399 str = m.Value;
5400 double d = 0.0;
5401 if (!Double.TryParse(str, out d))
5402 return 0.0;
5403
5404 return d;
5405 }
5406 return 0.0;
5407 }
5010 return Convert.ToDouble(src.Data[index]); 5408 return Convert.ToDouble(src.Data[index]);
5011 } 5409 }
5012 catch (FormatException) 5410 catch (FormatException)
@@ -5048,7 +5446,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5048 // for completion and should LSL_Key ever be implemented 5446 // for completion and should LSL_Key ever be implemented
5049 // as it's own struct 5447 // as it's own struct
5050 else if (!(src.Data[index] is LSL_String || 5448 else if (!(src.Data[index] is LSL_String ||
5051 src.Data[index] is LSL_Key)) 5449 src.Data[index] is LSL_Key ||
5450 src.Data[index] is String))
5052 { 5451 {
5053 return ""; 5452 return "";
5054 } 5453 }
@@ -5306,7 +5705,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5306 } 5705 }
5307 } 5706 }
5308 } 5707 }
5309 else { 5708 else
5709 {
5310 object[] array = new object[src.Length]; 5710 object[] array = new object[src.Length];
5311 Array.Copy(src.Data, 0, array, 0, src.Length); 5711 Array.Copy(src.Data, 0, array, 0, src.Length);
5312 result = new LSL_List(array); 5712 result = new LSL_List(array);
@@ -5413,7 +5813,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5413 public LSL_Integer llGetRegionAgentCount() 5813 public LSL_Integer llGetRegionAgentCount()
5414 { 5814 {
5415 m_host.AddScriptLPS(1); 5815 m_host.AddScriptLPS(1);
5416 return new LSL_Integer(World.GetRootAgentCount()); 5816
5817 int count = 0;
5818 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5819 count++;
5820 });
5821
5822 return new LSL_Integer(count);
5417 } 5823 }
5418 5824
5419 public LSL_Vector llGetRegionCorner() 5825 public LSL_Vector llGetRegionCorner()
@@ -5654,6 +6060,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5654 flags |= ScriptBaseClass.AGENT_AWAY; 6060 flags |= ScriptBaseClass.AGENT_AWAY;
5655 } 6061 }
5656 6062
6063 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6064 UUID[] anims = agent.Animator.GetAnimationArray();
6065 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6066 {
6067 flags |= ScriptBaseClass.AGENT_BUSY;
6068 }
6069
5657 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6070 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5658 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6071 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5659 { 6072 {
@@ -5701,6 +6114,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5701 flags |= ScriptBaseClass.AGENT_SITTING; 6114 flags |= ScriptBaseClass.AGENT_SITTING;
5702 } 6115 }
5703 6116
6117 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6118 {
6119 flags |= ScriptBaseClass.AGENT_MALE;
6120 }
6121
5704 return flags; 6122 return flags;
5705 } 6123 }
5706 6124
@@ -5848,9 +6266,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5848 6266
5849 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6267 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5850 6268
5851 foreach (SceneObjectPart part in parts) 6269 try
6270 {
6271 foreach (SceneObjectPart part in parts)
6272 {
6273 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6274 }
6275 }
6276 finally
5852 { 6277 {
5853 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5854 } 6278 }
5855 } 6279 }
5856 6280
@@ -5902,13 +6326,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5902 6326
5903 if (m_host.OwnerID == land.LandData.OwnerID) 6327 if (m_host.OwnerID == land.LandData.OwnerID)
5904 { 6328 {
5905 World.TeleportClientHome(agentID, presence.ControllingClient); 6329 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6330 presence.TeleportWithMomentum(pos, null);
6331 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5906 } 6332 }
5907 } 6333 }
5908 } 6334 }
5909 ScriptSleep(5000); 6335 ScriptSleep(5000);
5910 } 6336 }
5911 6337
6338 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6339 {
6340 return ParseString2List(str, separators, in_spacers, false);
6341 }
6342
5912 public LSL_Integer llOverMyLand(string id) 6343 public LSL_Integer llOverMyLand(string id)
5913 { 6344 {
5914 m_host.AddScriptLPS(1); 6345 m_host.AddScriptLPS(1);
@@ -5967,20 +6398,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5967 return agentSize; 6398 return agentSize;
5968 } 6399 }
5969 6400
5970 public LSL_Integer llSameGroup(string agent) 6401 public LSL_Integer llSameGroup(string id)
5971 { 6402 {
5972 m_host.AddScriptLPS(1); 6403 m_host.AddScriptLPS(1);
5973 UUID agentId = new UUID(); 6404 UUID uuid = new UUID();
5974 if (!UUID.TryParse(agent, out agentId)) 6405 if (!UUID.TryParse(id, out uuid))
5975 return new LSL_Integer(0);
5976 ScenePresence presence = World.GetScenePresence(agentId);
5977 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5978 return new LSL_Integer(0); 6406 return new LSL_Integer(0);
5979 IClientAPI client = presence.ControllingClient; 6407
5980 if (m_host.GroupID == client.ActiveGroupId) 6408 // Check if it's a group key
6409 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5981 return new LSL_Integer(1); 6410 return new LSL_Integer(1);
5982 else 6411
6412 // We got passed a UUID.Zero
6413 if (uuid == UUID.Zero)
5983 return new LSL_Integer(0); 6414 return new LSL_Integer(0);
6415
6416 // Handle the case where id names an avatar
6417 ScenePresence presence = World.GetScenePresence(uuid);
6418 if (presence != null)
6419 {
6420 if (presence.IsChildAgent)
6421 return new LSL_Integer(0);
6422
6423 IClientAPI client = presence.ControllingClient;
6424 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6425 return new LSL_Integer(1);
6426
6427 return new LSL_Integer(0);
6428 }
6429
6430 // Handle object case
6431 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6432 if (part != null)
6433 {
6434 // This will handle both deed and non-deed and also the no
6435 // group case
6436 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6437 return new LSL_Integer(1);
6438
6439 return new LSL_Integer(0);
6440 }
6441
6442 return new LSL_Integer(0);
5984 } 6443 }
5985 6444
5986 public void llUnSit(string id) 6445 public void llUnSit(string id)
@@ -6105,7 +6564,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6105 return m_host.ParentGroup.AttachmentPoint; 6564 return m_host.ParentGroup.AttachmentPoint;
6106 } 6565 }
6107 6566
6108 public LSL_Integer llGetFreeMemory() 6567 public virtual LSL_Integer llGetFreeMemory()
6109 { 6568 {
6110 m_host.AddScriptLPS(1); 6569 m_host.AddScriptLPS(1);
6111 // Make scripts designed for LSO happy 6570 // Make scripts designed for LSO happy
@@ -6222,7 +6681,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6222 SetParticleSystem(m_host, rules); 6681 SetParticleSystem(m_host, rules);
6223 } 6682 }
6224 6683
6225 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6684 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6685 {
6226 6686
6227 6687
6228 if (rules.Length == 0) 6688 if (rules.Length == 0)
@@ -6537,6 +6997,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6537 6997
6538 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6998 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6539 { 6999 {
7000 // LSL quaternions can normalize to 0, normal Quaternions can't.
7001 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7002 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7003
6540 part.SitTargetPosition = offset; 7004 part.SitTargetPosition = offset;
6541 part.SitTargetOrientation = rot; 7005 part.SitTargetOrientation = rot;
6542 part.ParentGroup.HasGroupChanged = true; 7006 part.ParentGroup.HasGroupChanged = true;
@@ -6692,13 +7156,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6692 UUID av = new UUID(); 7156 UUID av = new UUID();
6693 if (!UUID.TryParse(avatar,out av)) 7157 if (!UUID.TryParse(avatar,out av))
6694 { 7158 {
6695 LSLError("First parameter to llDialog needs to be a key"); 7159 //LSLError("First parameter to llDialog needs to be a key");
6696 return; 7160 return;
6697 } 7161 }
6698 if (buttons.Length < 1) 7162 if (buttons.Length < 1)
6699 { 7163 {
6700 LSLError("No less than 1 button can be shown"); 7164 buttons.Add("OK");
6701 return;
6702 } 7165 }
6703 if (buttons.Length > 12) 7166 if (buttons.Length > 12)
6704 { 7167 {
@@ -6715,7 +7178,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6715 } 7178 }
6716 if (buttons.Data[i].ToString().Length > 24) 7179 if (buttons.Data[i].ToString().Length > 24)
6717 { 7180 {
6718 LSLError("button label cannot be longer than 24 characters"); 7181 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6719 return; 7182 return;
6720 } 7183 }
6721 buts[i] = buttons.Data[i].ToString(); 7184 buts[i] = buttons.Data[i].ToString();
@@ -6782,9 +7245,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6782 return; 7245 return;
6783 } 7246 }
6784 7247
6785 // the rest of the permission checks are done in RezScript, so check the pin there as well 7248 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6786 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7249 if (dest != null)
7250 {
7251 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7252 {
7253 // the rest of the permission checks are done in RezScript, so check the pin there as well
7254 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6787 7255
7256 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7257 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7258 }
7259 }
6788 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7260 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6789 ScriptSleep(3000); 7261 ScriptSleep(3000);
6790 } 7262 }
@@ -6847,19 +7319,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6847 public LSL_String llMD5String(string src, int nonce) 7319 public LSL_String llMD5String(string src, int nonce)
6848 { 7320 {
6849 m_host.AddScriptLPS(1); 7321 m_host.AddScriptLPS(1);
6850 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7322 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6851 } 7323 }
6852 7324
6853 public LSL_String llSHA1String(string src) 7325 public LSL_String llSHA1String(string src)
6854 { 7326 {
6855 m_host.AddScriptLPS(1); 7327 m_host.AddScriptLPS(1);
6856 return Util.SHA1Hash(src).ToLower(); 7328 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6857 } 7329 }
6858 7330
6859 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7331 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6860 { 7332 {
6861 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7333 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6862 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7334 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7335 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7336 return shapeBlock;
6863 7337
6864 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7338 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6865 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7339 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6964,6 +7438,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6964 // Prim type box, cylinder and prism. 7438 // Prim type box, cylinder and prism.
6965 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) 7439 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)
6966 { 7440 {
7441 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7442 return;
7443
6967 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7444 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6968 ObjectShapePacket.ObjectDataBlock shapeBlock; 7445 ObjectShapePacket.ObjectDataBlock shapeBlock;
6969 7446
@@ -7017,6 +7494,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7017 // Prim type sphere. 7494 // Prim type sphere.
7018 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7495 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7019 { 7496 {
7497 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7498 return;
7499
7020 ObjectShapePacket.ObjectDataBlock shapeBlock; 7500 ObjectShapePacket.ObjectDataBlock shapeBlock;
7021 7501
7022 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7502 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7058,6 +7538,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7058 // Prim type torus, tube and ring. 7538 // Prim type torus, tube and ring.
7059 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) 7539 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)
7060 { 7540 {
7541 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7542 return;
7543
7061 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7544 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7062 ObjectShapePacket.ObjectDataBlock shapeBlock; 7545 ObjectShapePacket.ObjectDataBlock shapeBlock;
7063 7546
@@ -7193,6 +7676,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7193 // Prim type sculpt. 7676 // Prim type sculpt.
7194 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7677 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7195 { 7678 {
7679 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7680 return;
7681
7196 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7682 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7197 UUID sculptId; 7683 UUID sculptId;
7198 7684
@@ -7217,7 +7703,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7217 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7703 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7218 { 7704 {
7219 // default 7705 // default
7220 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7706 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7221 } 7707 }
7222 7708
7223 part.Shape.SetSculptProperties((byte)type, sculptId); 7709 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7234,48 +7720,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7234 ScriptSleep(200); 7720 ScriptSleep(200);
7235 } 7721 }
7236 7722
7237 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7723 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7238 { 7724 {
7239 m_host.AddScriptLPS(1); 7725 m_host.AddScriptLPS(1);
7240 7726
7241 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7727 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7242 7728
7243 ScriptSleep(200); 7729 ScriptSleep(200);
7244 } 7730 }
7245 7731
7246 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7732 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7247 { 7733 {
7248 m_host.AddScriptLPS(1); 7734 List<object> parts = new List<object>();
7735 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7736 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7737 foreach (SceneObjectPart p in prims)
7738 parts.Add(p);
7739 foreach (ScenePresence p in avatars)
7740 parts.Add(p);
7249 7741
7250 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7742 LSL_List remaining = null;
7743 uint rulesParsed = 0;
7744
7745 if (parts.Count > 0)
7746 {
7747 foreach (object part in parts)
7748 {
7749 if (part is SceneObjectPart)
7750 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7751 else
7752 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7753 }
7754
7755 while ((object)remaining != null && remaining.Length > 2)
7756 {
7757 linknumber = remaining.GetLSLIntegerItem(0);
7758 rules = remaining.GetSublist(1, -1);
7759 parts.Clear();
7760 prims = GetLinkParts(linknumber);
7761 avatars = GetLinkAvatars(linknumber);
7762 foreach (SceneObjectPart p in prims)
7763 parts.Add(p);
7764 foreach (ScenePresence p in avatars)
7765 parts.Add(p);
7766
7767 remaining = null;
7768 foreach (object part in parts)
7769 {
7770 if (part is SceneObjectPart)
7771 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7772 else
7773 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7774 }
7775 }
7776 }
7251 } 7777 }
7252 7778
7253 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7779 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7780 float material_density, float material_friction,
7781 float material_restitution, float material_gravity_modifier)
7254 { 7782 {
7255 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7783 ExtraPhysicsData physdata = new ExtraPhysicsData();
7784 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7785 physdata.Density = part.Density;
7786 physdata.Friction = part.Friction;
7787 physdata.Bounce = part.Bounciness;
7788 physdata.GravitationModifier = part.GravityModifier;
7256 7789
7257 LSL_List remaining = null; 7790 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7258 uint rulesParsed = 0; 7791 physdata.Density = material_density;
7792 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7793 physdata.Friction = material_friction;
7794 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7795 physdata.Bounce = material_restitution;
7796 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7797 physdata.GravitationModifier = material_gravity_modifier;
7259 7798
7260 foreach (SceneObjectPart part in parts) 7799 part.UpdateExtraPhysics(physdata);
7261 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7800 }
7262 7801
7263 while (remaining != null && remaining.Length > 2) 7802 public void llSetPhysicsMaterial(int material_bits,
7264 { 7803 float material_gravity_modifier, float material_restitution,
7265 linknumber = remaining.GetLSLIntegerItem(0); 7804 float material_friction, float material_density)
7266 rules = remaining.GetSublist(1, -1); 7805 {
7267 parts = GetLinkParts(linknumber); 7806 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7807 }
7268 7808
7269 foreach (SceneObjectPart part in parts) 7809 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7270 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7810 {
7811 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7812 llSetLinkPrimitiveParamsFast(linknumber, rules);
7813 ScriptSleep(200);
7814 }
7815
7816 // vector up using libomv (c&p from sop )
7817 // vector up rotated by r
7818 private Vector3 Zrot(Quaternion r)
7819 {
7820 double x, y, z, m;
7821
7822 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7823 if (Math.Abs(1.0 - m) > 0.000001)
7824 {
7825 m = 1.0 / Math.Sqrt(m);
7826 r.X *= (float)m;
7827 r.Y *= (float)m;
7828 r.Z *= (float)m;
7829 r.W *= (float)m;
7271 } 7830 }
7831
7832 x = 2 * (r.X * r.Z + r.Y * r.W);
7833 y = 2 * (-r.X * r.W + r.Y * r.Z);
7834 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7835
7836 return new Vector3((float)x, (float)y, (float)z);
7272 } 7837 }
7273 7838
7274 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7839 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7275 { 7840 {
7841 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7842 return null;
7843
7276 int idx = 0; 7844 int idx = 0;
7277 int idxStart = 0; 7845 int idxStart = 0;
7278 7846
7847 SceneObjectGroup parentgrp = part.ParentGroup;
7848
7279 bool positionChanged = false; 7849 bool positionChanged = false;
7280 LSL_Vector currentPosition = GetPartLocalPos(part); 7850 LSL_Vector currentPosition = GetPartLocalPos(part);
7281 7851
@@ -7300,8 +7870,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7300 return null; 7870 return null;
7301 7871
7302 v=rules.GetVector3Item(idx++); 7872 v=rules.GetVector3Item(idx++);
7303 positionChanged = true;
7304 currentPosition = GetSetPosTarget(part, v, currentPosition); 7873 currentPosition = GetSetPosTarget(part, v, currentPosition);
7874 positionChanged = true;
7305 7875
7306 break; 7876 break;
7307 case (int)ScriptBaseClass.PRIM_SIZE: 7877 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7578,7 +8148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7578 return null; 8148 return null;
7579 8149
7580 string ph = rules.Data[idx++].ToString(); 8150 string ph = rules.Data[idx++].ToString();
7581 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8151 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7582 8152
7583 break; 8153 break;
7584 8154
@@ -7596,12 +8166,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7596 part.ScriptSetPhysicsStatus(physics); 8166 part.ScriptSetPhysicsStatus(physics);
7597 break; 8167 break;
7598 8168
8169 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8170 if (remain < 1)
8171 return null;
8172
8173 int shape_type = rules.GetLSLIntegerItem(idx++);
8174
8175 ExtraPhysicsData physdata = new ExtraPhysicsData();
8176 physdata.Density = part.Density;
8177 physdata.Bounce = part.Bounciness;
8178 physdata.GravitationModifier = part.GravityModifier;
8179 physdata.PhysShapeType = (PhysShapeType)shape_type;
8180
8181 part.UpdateExtraPhysics(physdata);
8182
8183 break;
8184
8185 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8186 if (remain < 5)
8187 return null;
8188
8189 int material_bits = rules.GetLSLIntegerItem(idx++);
8190 float material_density = (float)rules.GetLSLFloatItem(idx++);
8191 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8192 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8193 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8194
8195 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8196
8197 break;
8198
7599 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8199 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7600 if (remain < 1) 8200 if (remain < 1)
7601 return null; 8201 return null;
7602 string temp = rules.Data[idx++].ToString(); 8202 string temp = rules.Data[idx++].ToString();
7603 8203
7604 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8204 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7605 8205
7606 break; 8206 break;
7607 8207
@@ -7675,7 +8275,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7675 if (part.ParentGroup.RootPart == part) 8275 if (part.ParentGroup.RootPart == part)
7676 { 8276 {
7677 SceneObjectGroup parent = part.ParentGroup; 8277 SceneObjectGroup parent = part.ParentGroup;
7678 parent.UpdateGroupPosition(currentPosition); 8278 Util.FireAndForget(delegate(object x) {
8279 parent.UpdateGroupPosition(currentPosition);
8280 });
7679 } 8281 }
7680 else 8282 else
7681 { 8283 {
@@ -7720,10 +8322,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7720 8322
7721 public LSL_String llXorBase64Strings(string str1, string str2) 8323 public LSL_String llXorBase64Strings(string str1, string str2)
7722 { 8324 {
7723 m_host.AddScriptLPS(1); 8325 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7724 Deprecated("llXorBase64Strings"); 8326
7725 ScriptSleep(300); 8327 ScriptSleep(300);
7726 return String.Empty; 8328 m_host.AddScriptLPS(1);
8329
8330 if (str1 == String.Empty)
8331 return String.Empty;
8332 if (str2 == String.Empty)
8333 return str1;
8334
8335 int len = str2.Length;
8336 if ((len % 4) != 0) // LL is EVIL!!!!
8337 {
8338 while (str2.EndsWith("="))
8339 str2 = str2.Substring(0, str2.Length - 1);
8340
8341 len = str2.Length;
8342 int mod = len % 4;
8343
8344 if (mod == 1)
8345 str2 = str2.Substring(0, str2.Length - 1);
8346 else if (mod == 2)
8347 str2 += "==";
8348 else if (mod == 3)
8349 str2 += "=";
8350 }
8351
8352 byte[] data1;
8353 byte[] data2;
8354 try
8355 {
8356 data1 = Convert.FromBase64String(str1);
8357 data2 = Convert.FromBase64String(str2);
8358 }
8359 catch (Exception)
8360 {
8361 return new LSL_String(String.Empty);
8362 }
8363
8364 // For cases where the decoded length of s2 is greater
8365 // than the decoded length of s1, simply perform a normal
8366 // decode and XOR
8367 //
8368 if (data2.Length >= data1.Length)
8369 {
8370 for (int pos = 0 ; pos < data1.Length ; pos++ )
8371 data1[pos] ^= data2[pos];
8372
8373 return Convert.ToBase64String(data1);
8374 }
8375
8376 // Remove padding
8377 while (str1.EndsWith("="))
8378 str1 = str1.Substring(0, str1.Length - 1);
8379 while (str2.EndsWith("="))
8380 str2 = str2.Substring(0, str2.Length - 1);
8381
8382 byte[] d1 = new byte[str1.Length];
8383 byte[] d2 = new byte[str2.Length];
8384
8385 for (int i = 0 ; i < str1.Length ; i++)
8386 {
8387 int idx = b64.IndexOf(str1.Substring(i, 1));
8388 if (idx == -1)
8389 idx = 0;
8390 d1[i] = (byte)idx;
8391 }
8392
8393 for (int i = 0 ; i < str2.Length ; i++)
8394 {
8395 int idx = b64.IndexOf(str2.Substring(i, 1));
8396 if (idx == -1)
8397 idx = 0;
8398 d2[i] = (byte)idx;
8399 }
8400
8401 string output = String.Empty;
8402
8403 for (int pos = 0 ; pos < d1.Length ; pos++)
8404 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8405
8406 while (output.Length % 3 > 0)
8407 output += "=";
8408
8409 return output;
7727 } 8410 }
7728 8411
7729 public void llRemoteDataSetRegion() 8412 public void llRemoteDataSetRegion()
@@ -7847,13 +8530,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7847 public LSL_Integer llGetNumberOfPrims() 8530 public LSL_Integer llGetNumberOfPrims()
7848 { 8531 {
7849 m_host.AddScriptLPS(1); 8532 m_host.AddScriptLPS(1);
7850 int avatarCount = 0; 8533 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7851 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8534
7852 {
7853 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7854 avatarCount++;
7855 });
7856
7857 return m_host.ParentGroup.PrimCount + avatarCount; 8535 return m_host.ParentGroup.PrimCount + avatarCount;
7858 } 8536 }
7859 8537
@@ -7869,55 +8547,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7869 m_host.AddScriptLPS(1); 8547 m_host.AddScriptLPS(1);
7870 UUID objID = UUID.Zero; 8548 UUID objID = UUID.Zero;
7871 LSL_List result = new LSL_List(); 8549 LSL_List result = new LSL_List();
8550
8551 // If the ID is not valid, return null result
7872 if (!UUID.TryParse(obj, out objID)) 8552 if (!UUID.TryParse(obj, out objID))
7873 { 8553 {
7874 result.Add(new LSL_Vector()); 8554 result.Add(new LSL_Vector());
7875 result.Add(new LSL_Vector()); 8555 result.Add(new LSL_Vector());
7876 return result; 8556 return result;
7877 } 8557 }
8558
8559 // Check if this is an attached prim. If so, replace
8560 // the UUID with the avatar UUID and report it's bounding box
8561 SceneObjectPart part = World.GetSceneObjectPart(objID);
8562 if (part != null && part.ParentGroup.IsAttachment)
8563 objID = part.ParentGroup.AttachedAvatar;
8564
8565 // Find out if this is an avatar ID. If so, return it's box
7878 ScenePresence presence = World.GetScenePresence(objID); 8566 ScenePresence presence = World.GetScenePresence(objID);
7879 if (presence != null) 8567 if (presence != null)
7880 { 8568 {
7881 if (presence.ParentID == 0) // not sat on an object 8569 // As per LSL Wiki, there is no difference between sitting
8570 // and standing avatar since server 1.36
8571 LSL_Vector lower;
8572 LSL_Vector upper;
8573 if (presence.Animator.Animations.DefaultAnimation.AnimID
8574 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7882 { 8575 {
7883 LSL_Vector lower; 8576 // This is for ground sitting avatars
7884 LSL_Vector upper; 8577 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7885 if (presence.Animator.Animations.DefaultAnimation.AnimID 8578 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7886 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8579 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7887 {
7888 // This is for ground sitting avatars
7889 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7890 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7891 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7892 }
7893 else
7894 {
7895 // This is for standing/flying avatars
7896 float height = presence.Appearance.AvatarHeight / 2.0f;
7897 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7898 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7899 }
7900 result.Add(lower);
7901 result.Add(upper);
7902 return result;
7903 } 8580 }
7904 else 8581 else
7905 { 8582 {
7906 // sitting on an object so we need the bounding box of that 8583 // This is for standing/flying avatars
7907 // which should include the avatar so set the UUID to the 8584 float height = presence.Appearance.AvatarHeight / 2.0f;
7908 // UUID of the object the avatar is sat on and allow it to fall through 8585 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7909 // to processing an object 8586 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7910 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7911 objID = p.UUID;
7912 } 8587 }
8588
8589 // Adjust to the documented error offsets (see LSL Wiki)
8590 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8591 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8592
8593 if (lower.x > upper.x)
8594 lower.x = upper.x;
8595 if (lower.y > upper.y)
8596 lower.y = upper.y;
8597 if (lower.z > upper.z)
8598 lower.z = upper.z;
8599
8600 result.Add(lower);
8601 result.Add(upper);
8602 return result;
7913 } 8603 }
7914 SceneObjectPart part = World.GetSceneObjectPart(objID); 8604
8605 part = World.GetSceneObjectPart(objID);
7915 // Currently only works for single prims without a sitting avatar 8606 // Currently only works for single prims without a sitting avatar
7916 if (part != null) 8607 if (part != null)
7917 { 8608 {
7918 Vector3 halfSize = part.Scale / 2.0f; 8609 float minX;
7919 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8610 float maxX;
7920 LSL_Vector upper = new LSL_Vector(halfSize); 8611 float minY;
8612 float maxY;
8613 float minZ;
8614 float maxZ;
8615
8616 // This BBox is in sim coordinates, with the offset being
8617 // a contained point.
8618 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8619 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8620
8621 minX -= offsets[0].X;
8622 maxX -= offsets[0].X;
8623 minY -= offsets[0].Y;
8624 maxY -= offsets[0].Y;
8625 minZ -= offsets[0].Z;
8626 maxZ -= offsets[0].Z;
8627
8628 LSL_Vector lower;
8629 LSL_Vector upper;
8630
8631 // Adjust to the documented error offsets (see LSL Wiki)
8632 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8633 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8634
8635 if (lower.x > upper.x)
8636 lower.x = upper.x;
8637 if (lower.y > upper.y)
8638 lower.y = upper.y;
8639 if (lower.z > upper.z)
8640 lower.z = upper.z;
8641
7921 result.Add(lower); 8642 result.Add(lower);
7922 result.Add(upper); 8643 result.Add(upper);
7923 return result; 8644 return result;
@@ -7931,7 +8652,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7931 8652
7932 public LSL_Vector llGetGeometricCenter() 8653 public LSL_Vector llGetGeometricCenter()
7933 { 8654 {
7934 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8655 Vector3 tmp = m_host.GetGeometricCenter();
8656 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7935 } 8657 }
7936 8658
7937 public LSL_List llGetPrimitiveParams(LSL_List rules) 8659 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7959,24 +8681,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7959 { 8681 {
7960 m_host.AddScriptLPS(1); 8682 m_host.AddScriptLPS(1);
7961 8683
7962 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8684 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8685 // keep other options as before
7963 8686
8687 List<SceneObjectPart> parts;
8688 List<ScenePresence> avatars;
8689
7964 LSL_List res = new LSL_List(); 8690 LSL_List res = new LSL_List();
7965 LSL_List remaining = null; 8691 LSL_List remaining = null;
7966 8692
7967 foreach (SceneObjectPart part in parts) 8693 while (rules.Length > 0)
7968 { 8694 {
7969 remaining = GetPrimParams(part, rules, ref res);
7970 }
7971
7972 while (remaining != null && remaining.Length > 2)
7973 {
7974 linknumber = remaining.GetLSLIntegerItem(0);
7975 rules = remaining.GetSublist(1, -1);
7976 parts = GetLinkParts(linknumber); 8695 parts = GetLinkParts(linknumber);
8696 avatars = GetLinkAvatars(linknumber);
7977 8697
8698 remaining = null;
7978 foreach (SceneObjectPart part in parts) 8699 foreach (SceneObjectPart part in parts)
8700 {
7979 remaining = GetPrimParams(part, rules, ref res); 8701 remaining = GetPrimParams(part, rules, ref res);
8702 }
8703 foreach (ScenePresence avatar in avatars)
8704 {
8705 remaining = GetPrimParams(avatar, rules, ref res);
8706 }
8707
8708 if (remaining != null && remaining.Length > 0)
8709 {
8710 linknumber = remaining.GetLSLIntegerItem(0);
8711 rules = remaining.GetSublist(1, -1);
8712 }
7980 } 8713 }
7981 8714
7982 return res; 8715 return res;
@@ -8021,13 +8754,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8021 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8754 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8022 part.AbsolutePosition.Y, 8755 part.AbsolutePosition.Y,
8023 part.AbsolutePosition.Z); 8756 part.AbsolutePosition.Z);
8024 // For some reason, the part.AbsolutePosition.* values do not change if the
8025 // linkset is rotated; they always reflect the child prim's world position
8026 // as though the linkset is unrotated. This is incompatible behavior with SL's
8027 // implementation, so will break scripts imported from there (not to mention it
8028 // makes it more difficult to determine a child prim's actual inworld position).
8029 if (part.ParentID != 0)
8030 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8031 res.Add(v); 8757 res.Add(v);
8032 break; 8758 break;
8033 8759
@@ -8199,30 +8925,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8199 if (remain < 1) 8925 if (remain < 1)
8200 return null; 8926 return null;
8201 8927
8202 face=(int)rules.GetLSLIntegerItem(idx++); 8928 face = (int)rules.GetLSLIntegerItem(idx++);
8203 8929
8204 tex = part.Shape.Textures; 8930 tex = part.Shape.Textures;
8931 int shiny;
8205 if (face == ScriptBaseClass.ALL_SIDES) 8932 if (face == ScriptBaseClass.ALL_SIDES)
8206 { 8933 {
8207 for (face = 0; face < GetNumberOfSides(part); face++) 8934 for (face = 0; face < GetNumberOfSides(part); face++)
8208 { 8935 {
8209 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8936 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8210 // Convert Shininess to PRIM_SHINY_* 8937 if (shinyness == Shininess.High)
8211 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8938 {
8212 // PRIM_BUMP_* 8939 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8213 res.Add(new LSL_Integer((int)texface.Bump)); 8940 }
8941 else if (shinyness == Shininess.Medium)
8942 {
8943 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8944 }
8945 else if (shinyness == Shininess.Low)
8946 {
8947 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8948 }
8949 else
8950 {
8951 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8952 }
8953 res.Add(new LSL_Integer(shiny));
8954 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8214 } 8955 }
8215 } 8956 }
8216 else 8957 else
8217 { 8958 {
8218 if (face >= 0 && face < GetNumberOfSides(part)) 8959 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8960 if (shinyness == Shininess.High)
8219 { 8961 {
8220 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8962 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8221 // Convert Shininess to PRIM_SHINY_* 8963 }
8222 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8964 else if (shinyness == Shininess.Medium)
8223 // PRIM_BUMP_* 8965 {
8224 res.Add(new LSL_Integer((int)texface.Bump)); 8966 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8967 }
8968 else if (shinyness == Shininess.Low)
8969 {
8970 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8225 } 8971 }
8972 else
8973 {
8974 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8975 }
8976 res.Add(new LSL_Integer(shiny));
8977 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8226 } 8978 }
8227 break; 8979 break;
8228 8980
@@ -8230,24 +8982,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8230 if (remain < 1) 8982 if (remain < 1)
8231 return null; 8983 return null;
8232 8984
8233 face=(int)rules.GetLSLIntegerItem(idx++); 8985 face = (int)rules.GetLSLIntegerItem(idx++);
8234 8986
8235 tex = part.Shape.Textures; 8987 tex = part.Shape.Textures;
8988 int fullbright;
8236 if (face == ScriptBaseClass.ALL_SIDES) 8989 if (face == ScriptBaseClass.ALL_SIDES)
8237 { 8990 {
8238 for (face = 0; face < GetNumberOfSides(part); face++) 8991 for (face = 0; face < GetNumberOfSides(part); face++)
8239 { 8992 {
8240 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8993 if (tex.GetFace((uint)face).Fullbright == true)
8241 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8994 {
8995 fullbright = ScriptBaseClass.TRUE;
8996 }
8997 else
8998 {
8999 fullbright = ScriptBaseClass.FALSE;
9000 }
9001 res.Add(new LSL_Integer(fullbright));
8242 } 9002 }
8243 } 9003 }
8244 else 9004 else
8245 { 9005 {
8246 if (face >= 0 && face < GetNumberOfSides(part)) 9006 if (tex.GetFace((uint)face).Fullbright == true)
8247 { 9007 {
8248 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9008 fullbright = ScriptBaseClass.TRUE;
8249 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8250 } 9009 }
9010 else
9011 {
9012 fullbright = ScriptBaseClass.FALSE;
9013 }
9014 res.Add(new LSL_Integer(fullbright));
8251 } 9015 }
8252 break; 9016 break;
8253 9017
@@ -8269,27 +9033,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8269 break; 9033 break;
8270 9034
8271 case (int)ScriptBaseClass.PRIM_TEXGEN: 9035 case (int)ScriptBaseClass.PRIM_TEXGEN:
9036 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8272 if (remain < 1) 9037 if (remain < 1)
8273 return null; 9038 return null;
8274 9039
8275 face=(int)rules.GetLSLIntegerItem(idx++); 9040 face = (int)rules.GetLSLIntegerItem(idx++);
8276 9041
8277 tex = part.Shape.Textures; 9042 tex = part.Shape.Textures;
8278 if (face == ScriptBaseClass.ALL_SIDES) 9043 if (face == ScriptBaseClass.ALL_SIDES)
8279 { 9044 {
8280 for (face = 0; face < GetNumberOfSides(part); face++) 9045 for (face = 0; face < GetNumberOfSides(part); face++)
8281 { 9046 {
8282 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9047 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8283 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9048 {
8284 res.Add(new LSL_Integer((uint)texgen >> 1)); 9049 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9050 }
9051 else
9052 {
9053 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9054 }
8285 } 9055 }
8286 } 9056 }
8287 else 9057 else
8288 { 9058 {
8289 if (face >= 0 && face < GetNumberOfSides(part)) 9059 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9060 {
9061 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9062 }
9063 else
8290 { 9064 {
8291 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9065 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8292 res.Add(new LSL_Integer((uint)texgen >> 1));
8293 } 9066 }
8294 } 9067 }
8295 break; 9068 break;
@@ -8313,24 +9086,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8313 if (remain < 1) 9086 if (remain < 1)
8314 return null; 9087 return null;
8315 9088
8316 face=(int)rules.GetLSLIntegerItem(idx++); 9089 face = (int)rules.GetLSLIntegerItem(idx++);
8317 9090
8318 tex = part.Shape.Textures; 9091 tex = part.Shape.Textures;
9092 float primglow;
8319 if (face == ScriptBaseClass.ALL_SIDES) 9093 if (face == ScriptBaseClass.ALL_SIDES)
8320 { 9094 {
8321 for (face = 0; face < GetNumberOfSides(part); face++) 9095 for (face = 0; face < GetNumberOfSides(part); face++)
8322 { 9096 {
8323 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9097 primglow = tex.GetFace((uint)face).Glow;
8324 res.Add(new LSL_Float(texface.Glow)); 9098 res.Add(new LSL_Float(primglow));
8325 } 9099 }
8326 } 9100 }
8327 else 9101 else
8328 { 9102 {
8329 if (face >= 0 && face < GetNumberOfSides(part)) 9103 primglow = tex.GetFace((uint)face).Glow;
8330 { 9104 res.Add(new LSL_Float(primglow));
8331 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8332 res.Add(new LSL_Float(texface.Glow));
8333 }
8334 } 9105 }
8335 break; 9106 break;
8336 9107
@@ -8342,15 +9113,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8342 textColor.B)); 9113 textColor.B));
8343 res.Add(new LSL_Float(textColor.A)); 9114 res.Add(new LSL_Float(textColor.A));
8344 break; 9115 break;
9116
8345 case (int)ScriptBaseClass.PRIM_NAME: 9117 case (int)ScriptBaseClass.PRIM_NAME:
8346 res.Add(new LSL_String(part.Name)); 9118 res.Add(new LSL_String(part.Name));
8347 break; 9119 break;
9120
8348 case (int)ScriptBaseClass.PRIM_DESC: 9121 case (int)ScriptBaseClass.PRIM_DESC:
8349 res.Add(new LSL_String(part.Description)); 9122 res.Add(new LSL_String(part.Description));
8350 break; 9123 break;
9124
8351 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9125 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8352 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9126 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8353 break; 9127 break;
9128
8354 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9129 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8355 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9130 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8356 break; 9131 break;
@@ -8961,8 +9736,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8961 // The function returns an ordered list 9736 // The function returns an ordered list
8962 // representing the tokens found in the supplied 9737 // representing the tokens found in the supplied
8963 // sources string. If two successive tokenizers 9738 // sources string. If two successive tokenizers
8964 // are encountered, then a NULL entry is added 9739 // are encountered, then a null-string entry is
8965 // to the list. 9740 // added to the list.
8966 // 9741 //
8967 // It is a precondition that the source and 9742 // It is a precondition that the source and
8968 // toekizer lisst are non-null. If they are null, 9743 // toekizer lisst are non-null. If they are null,
@@ -8970,7 +9745,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8970 // while their lengths are being determined. 9745 // while their lengths are being determined.
8971 // 9746 //
8972 // A small amount of working memoryis required 9747 // A small amount of working memoryis required
8973 // of approximately 8*#tokenizers. 9748 // of approximately 8*#tokenizers + 8*srcstrlen.
8974 // 9749 //
8975 // There are many ways in which this function 9750 // There are many ways in which this function
8976 // can be implemented, this implementation is 9751 // can be implemented, this implementation is
@@ -8986,155 +9761,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8986 // and eliminates redundant tokenizers as soon 9761 // and eliminates redundant tokenizers as soon
8987 // as is possible. 9762 // as is possible.
8988 // 9763 //
8989 // The implementation tries to avoid any copying 9764 // The implementation tries to minimize temporary
8990 // of arrays or other objects. 9765 // garbage generation.
8991 // </remarks> 9766 // </remarks>
8992 9767
8993 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9768 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8994 { 9769 {
8995 int beginning = 0; 9770 return ParseString2List(src, separators, spacers, true);
8996 int srclen = src.Length; 9771 }
8997 int seplen = separators.Length;
8998 object[] separray = separators.Data;
8999 int spclen = spacers.Length;
9000 object[] spcarray = spacers.Data;
9001 int mlen = seplen+spclen;
9002
9003 int[] offset = new int[mlen+1];
9004 bool[] active = new bool[mlen];
9005
9006 int best;
9007 int j;
9008
9009 // Initial capacity reduces resize cost
9010 9772
9011 LSL_List tokens = new LSL_List(); 9773 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9774 {
9775 int srclen = src.Length;
9776 int seplen = separators.Length;
9777 object[] separray = separators.Data;
9778 int spclen = spacers.Length;
9779 object[] spcarray = spacers.Data;
9780 int dellen = 0;
9781 string[] delarray = new string[seplen+spclen];
9012 9782
9013 // All entries are initially valid 9783 int outlen = 0;
9784 string[] outarray = new string[srclen*2+1];
9014 9785
9015 for (int i = 0; i < mlen; i++) 9786 int i, j;
9016 active[i] = true; 9787 string d;
9017 9788
9018 offset[mlen] = srclen; 9789 m_host.AddScriptLPS(1);
9019 9790
9020 while (beginning < srclen) 9791 /*
9792 * Convert separator and spacer lists to C# strings.
9793 * Also filter out null strings so we don't hang.
9794 */
9795 for (i = 0; i < seplen; i ++)
9021 { 9796 {
9797 d = separray[i].ToString();
9798 if (d.Length > 0)
9799 {
9800 delarray[dellen++] = d;
9801 }
9802 }
9803 seplen = dellen;
9022 9804
9023 best = mlen; // as bad as it gets 9805 for (i = 0; i < spclen; i ++)
9806 {
9807 d = spcarray[i].ToString();
9808 if (d.Length > 0)
9809 {
9810 delarray[dellen++] = d;
9811 }
9812 }
9024 9813
9025 // Scan for separators 9814 /*
9815 * Scan through source string from beginning to end.
9816 */
9817 for (i = 0;;)
9818 {
9026 9819
9027 for (j = 0; j < seplen; j++) 9820 /*
9821 * Find earliest delimeter in src starting at i (if any).
9822 */
9823 int earliestDel = -1;
9824 int earliestSrc = srclen;
9825 string earliestStr = null;
9826 for (j = 0; j < dellen; j ++)
9028 { 9827 {
9029 if (separray[j].ToString() == String.Empty) 9828 d = delarray[j];
9030 active[j] = false; 9829 if (d != null)
9031
9032 if (active[j])
9033 { 9830 {
9034 // scan all of the markers 9831 int index = src.IndexOf(d, i);
9035 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9832 if (index < 0)
9036 { 9833 {
9037 // not present at all 9834 delarray[j] = null; // delim nowhere in src, don't check it anymore
9038 active[j] = false;
9039 } 9835 }
9040 else 9836 else if (index < earliestSrc)
9041 { 9837 {
9042 // present and correct 9838 earliestSrc = index; // where delimeter starts in source string
9043 if (offset[j] < offset[best]) 9839 earliestDel = j; // where delimeter is in delarray[]
9044 { 9840 earliestStr = d; // the delimeter string from delarray[]
9045 // closest so far 9841 if (index == i) break; // can't do any better than found at beg of string
9046 best = j;
9047 if (offset[best] == beginning)
9048 break;
9049 }
9050 } 9842 }
9051 } 9843 }
9052 } 9844 }
9053 9845
9054 // Scan for spacers 9846 /*
9055 9847 * Output source string starting at i through start of earliest delimeter.
9056 if (offset[best] != beginning) 9848 */
9849 if (keepNulls || (earliestSrc > i))
9057 { 9850 {
9058 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9851 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9059 {
9060 if (spcarray[j-seplen].ToString() == String.Empty)
9061 active[j] = false;
9062
9063 if (active[j])
9064 {
9065 // scan all of the markers
9066 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9067 {
9068 // not present at all
9069 active[j] = false;
9070 }
9071 else
9072 {
9073 // present and correct
9074 if (offset[j] < offset[best])
9075 {
9076 // closest so far
9077 best = j;
9078 }
9079 }
9080 }
9081 }
9082 } 9852 }
9083 9853
9084 // This is the normal exit from the scanning loop 9854 /*
9855 * If no delimeter found at or after i, we're done scanning.
9856 */
9857 if (earliestDel < 0) break;
9085 9858
9086 if (best == mlen) 9859 /*
9860 * If delimeter was a spacer, output the spacer.
9861 */
9862 if (earliestDel >= seplen)
9087 { 9863 {
9088 // no markers were found on this pass 9864 outarray[outlen++] = earliestStr;
9089 // so we're pretty much done
9090 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9091 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9092 break;
9093 } 9865 }
9094 9866
9095 // Otherwise we just add the newly delimited token 9867 /*
9096 // and recalculate where the search should continue. 9868 * Look at rest of src string following delimeter.
9097 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9869 */
9098 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9870 i = earliestSrc + earliestStr.Length;
9099
9100 if (best < seplen)
9101 {
9102 beginning = offset[best] + (separray[best].ToString()).Length;
9103 }
9104 else
9105 {
9106 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9107 string str = spcarray[best - seplen].ToString();
9108 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9109 tokens.Add(new LSL_String(str));
9110 }
9111 } 9871 }
9112 9872
9113 // This an awkward an not very intuitive boundary case. If the 9873 /*
9114 // last substring is a tokenizer, then there is an implied trailing 9874 * Make up an exact-sized output array suitable for an LSL_List object.
9115 // null list entry. Hopefully the single comparison will not be too 9875 */
9116 // arduous. Alternatively the 'break' could be replced with a return 9876 object[] outlist = new object[outlen];
9117 // but that's shabby programming. 9877 for (i = 0; i < outlen; i ++)
9118
9119 if ((beginning == srclen) && (keepNulls))
9120 { 9878 {
9121 if (srclen != 0) 9879 outlist[i] = new LSL_String(outarray[i]);
9122 tokens.Add(new LSL_String(""));
9123 } 9880 }
9124 9881 return new LSL_List(outlist);
9125 return tokens;
9126 }
9127
9128 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9129 {
9130 m_host.AddScriptLPS(1);
9131 return this.ParseString(src, separators, spacers, false);
9132 }
9133
9134 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9135 {
9136 m_host.AddScriptLPS(1);
9137 return this.ParseString(src, separators, spacers, true);
9138 } 9882 }
9139 9883
9140 public LSL_Integer llGetObjectPermMask(int mask) 9884 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9229,6 +9973,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9229 case 4: 9973 case 4:
9230 return (int)item.NextPermissions; 9974 return (int)item.NextPermissions;
9231 } 9975 }
9976 m_host.TaskInventory.LockItemsForRead(false);
9232 9977
9233 return -1; 9978 return -1;
9234 } 9979 }
@@ -9431,31 +10176,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9431 UUID key = new UUID(); 10176 UUID key = new UUID();
9432 if (UUID.TryParse(id, out key)) 10177 if (UUID.TryParse(id, out key))
9433 { 10178 {
9434 try 10179 // return total object mass
9435 { 10180 SceneObjectPart part = World.GetSceneObjectPart(key);
9436 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10181 if (part != null)
9437 if (obj != null) 10182 return part.ParentGroup.GetMass();
9438 return (double)obj.GetMass(); 10183
9439 // the object is null so the key is for an avatar 10184 // the object is null so the key is for an avatar
9440 ScenePresence avatar = World.GetScenePresence(key); 10185 ScenePresence avatar = World.GetScenePresence(key);
9441 if (avatar != null) 10186 if (avatar != null)
9442 if (avatar.IsChildAgent)
9443 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9444 // child agents have a mass of 1.0
9445 return 1;
9446 else
9447 return (double)avatar.GetMass();
9448 }
9449 catch (KeyNotFoundException)
9450 { 10187 {
9451 return 0; // The Object/Agent not in the region so just return zero 10188 if (avatar.IsChildAgent)
10189 {
10190 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10191 // child agents have a mass of 1.0
10192 return 1;
10193 }
10194 else
10195 {
10196 return (double)avatar.GetMass();
10197 }
9452 } 10198 }
9453 } 10199 }
9454 return 0; 10200 return 0;
9455 } 10201 }
9456 10202
9457 /// <summary> 10203 /// <summary>
9458 /// illListReplaceList removes the sub-list defined by the inclusive indices 10204 /// llListReplaceList removes the sub-list defined by the inclusive indices
9459 /// start and end and inserts the src list in its place. The inclusive 10205 /// start and end and inserts the src list in its place. The inclusive
9460 /// nature of the indices means that at least one element must be deleted 10206 /// nature of the indices means that at least one element must be deleted
9461 /// if the indices are within the bounds of the existing list. I.e. 2,2 10207 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9512,16 +10258,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9512 // based upon end. Note that if end exceeds the upper 10258 // based upon end. Note that if end exceeds the upper
9513 // bound in this case, the entire destination list 10259 // bound in this case, the entire destination list
9514 // is removed. 10260 // is removed.
9515 else 10261 else if (start == 0)
9516 { 10262 {
9517 if (end + 1 < dest.Length) 10263 if (end + 1 < dest.Length)
9518 {
9519 return src + dest.GetSublist(end + 1, -1); 10264 return src + dest.GetSublist(end + 1, -1);
9520 }
9521 else 10265 else
9522 {
9523 return src; 10266 return src;
9524 } 10267 }
10268 else // Start < 0
10269 {
10270 if (end + 1 < dest.Length)
10271 return dest.GetSublist(end + 1, -1);
10272 else
10273 return new LSL_List();
9525 } 10274 }
9526 } 10275 }
9527 // Finally, if start > end, we strip away a prefix and 10276 // Finally, if start > end, we strip away a prefix and
@@ -9572,17 +10321,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9572 int width = 0; 10321 int width = 0;
9573 int height = 0; 10322 int height = 0;
9574 10323
9575 ParcelMediaCommandEnum? commandToSend = null; 10324 uint commandToSend = 0;
9576 float time = 0.0f; // default is from start 10325 float time = 0.0f; // default is from start
9577 10326
9578 ScenePresence presence = null; 10327 ScenePresence presence = null;
9579 10328
9580 for (int i = 0; i < commandList.Data.Length; i++) 10329 for (int i = 0; i < commandList.Data.Length; i++)
9581 { 10330 {
9582 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10331 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9583 switch (command) 10332 switch (command)
9584 { 10333 {
9585 case ParcelMediaCommandEnum.Agent: 10334 case (uint)ParcelMediaCommandEnum.Agent:
9586 // we send only to one agent 10335 // we send only to one agent
9587 if ((i + 1) < commandList.Length) 10336 if ((i + 1) < commandList.Length)
9588 { 10337 {
@@ -9599,25 +10348,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9599 } 10348 }
9600 break; 10349 break;
9601 10350
9602 case ParcelMediaCommandEnum.Loop: 10351 case (uint)ParcelMediaCommandEnum.Loop:
9603 loop = 1; 10352 loop = 1;
9604 commandToSend = command; 10353 commandToSend = command;
9605 update = true; //need to send the media update packet to set looping 10354 update = true; //need to send the media update packet to set looping
9606 break; 10355 break;
9607 10356
9608 case ParcelMediaCommandEnum.Play: 10357 case (uint)ParcelMediaCommandEnum.Play:
9609 loop = 0; 10358 loop = 0;
9610 commandToSend = command; 10359 commandToSend = command;
9611 update = true; //need to send the media update packet to make sure it doesn't loop 10360 update = true; //need to send the media update packet to make sure it doesn't loop
9612 break; 10361 break;
9613 10362
9614 case ParcelMediaCommandEnum.Pause: 10363 case (uint)ParcelMediaCommandEnum.Pause:
9615 case ParcelMediaCommandEnum.Stop: 10364 case (uint)ParcelMediaCommandEnum.Stop:
9616 case ParcelMediaCommandEnum.Unload: 10365 case (uint)ParcelMediaCommandEnum.Unload:
9617 commandToSend = command; 10366 commandToSend = command;
9618 break; 10367 break;
9619 10368
9620 case ParcelMediaCommandEnum.Url: 10369 case (uint)ParcelMediaCommandEnum.Url:
9621 if ((i + 1) < commandList.Length) 10370 if ((i + 1) < commandList.Length)
9622 { 10371 {
9623 if (commandList.Data[i + 1] is LSL_String) 10372 if (commandList.Data[i + 1] is LSL_String)
@@ -9630,7 +10379,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9630 } 10379 }
9631 break; 10380 break;
9632 10381
9633 case ParcelMediaCommandEnum.Texture: 10382 case (uint)ParcelMediaCommandEnum.Texture:
9634 if ((i + 1) < commandList.Length) 10383 if ((i + 1) < commandList.Length)
9635 { 10384 {
9636 if (commandList.Data[i + 1] is LSL_String) 10385 if (commandList.Data[i + 1] is LSL_String)
@@ -9643,7 +10392,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9643 } 10392 }
9644 break; 10393 break;
9645 10394
9646 case ParcelMediaCommandEnum.Time: 10395 case (uint)ParcelMediaCommandEnum.Time:
9647 if ((i + 1) < commandList.Length) 10396 if ((i + 1) < commandList.Length)
9648 { 10397 {
9649 if (commandList.Data[i + 1] is LSL_Float) 10398 if (commandList.Data[i + 1] is LSL_Float)
@@ -9655,7 +10404,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9655 } 10404 }
9656 break; 10405 break;
9657 10406
9658 case ParcelMediaCommandEnum.AutoAlign: 10407 case (uint)ParcelMediaCommandEnum.AutoAlign:
9659 if ((i + 1) < commandList.Length) 10408 if ((i + 1) < commandList.Length)
9660 { 10409 {
9661 if (commandList.Data[i + 1] is LSL_Integer) 10410 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9669,7 +10418,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9669 } 10418 }
9670 break; 10419 break;
9671 10420
9672 case ParcelMediaCommandEnum.Type: 10421 case (uint)ParcelMediaCommandEnum.Type:
9673 if ((i + 1) < commandList.Length) 10422 if ((i + 1) < commandList.Length)
9674 { 10423 {
9675 if (commandList.Data[i + 1] is LSL_String) 10424 if (commandList.Data[i + 1] is LSL_String)
@@ -9682,7 +10431,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9682 } 10431 }
9683 break; 10432 break;
9684 10433
9685 case ParcelMediaCommandEnum.Desc: 10434 case (uint)ParcelMediaCommandEnum.Desc:
9686 if ((i + 1) < commandList.Length) 10435 if ((i + 1) < commandList.Length)
9687 { 10436 {
9688 if (commandList.Data[i + 1] is LSL_String) 10437 if (commandList.Data[i + 1] is LSL_String)
@@ -9695,7 +10444,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9695 } 10444 }
9696 break; 10445 break;
9697 10446
9698 case ParcelMediaCommandEnum.Size: 10447 case (uint)ParcelMediaCommandEnum.Size:
9699 if ((i + 2) < commandList.Length) 10448 if ((i + 2) < commandList.Length)
9700 { 10449 {
9701 if (commandList.Data[i + 1] is LSL_Integer) 10450 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9765,7 +10514,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9765 } 10514 }
9766 } 10515 }
9767 10516
9768 if (commandToSend != null) 10517 if (commandToSend != 0)
9769 { 10518 {
9770 // the commandList contained a start/stop/... command, too 10519 // the commandList contained a start/stop/... command, too
9771 if (presence == null) 10520 if (presence == null)
@@ -9802,7 +10551,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9802 10551
9803 if (aList.Data[i] != null) 10552 if (aList.Data[i] != null)
9804 { 10553 {
9805 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10554 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9806 { 10555 {
9807 case ParcelMediaCommandEnum.Url: 10556 case ParcelMediaCommandEnum.Url:
9808 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10557 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9859,15 +10608,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9859 10608
9860 if (quick_pay_buttons.Data.Length < 4) 10609 if (quick_pay_buttons.Data.Length < 4)
9861 { 10610 {
9862 LSLError("List must have at least 4 elements"); 10611 int x;
9863 return; 10612 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10613 {
10614 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10615 }
9864 } 10616 }
9865 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10617 int[] nPrice = new int[5];
9866 10618 nPrice[0] = price;
9867 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10619 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9868 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10620 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9869 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10621 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9870 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10622 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10623 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9871 m_host.ParentGroup.HasGroupChanged = true; 10624 m_host.ParentGroup.HasGroupChanged = true;
9872 } 10625 }
9873 10626
@@ -9884,7 +10637,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9884 return new LSL_Vector(); 10637 return new LSL_Vector();
9885 } 10638 }
9886 10639
9887 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10640// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10641 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9888 if (presence != null) 10642 if (presence != null)
9889 { 10643 {
9890 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10644 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9906,7 +10660,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9906 return new LSL_Rotation(); 10660 return new LSL_Rotation();
9907 } 10661 }
9908 10662
9909 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10663// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10664 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9910 if (presence != null) 10665 if (presence != null)
9911 { 10666 {
9912 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10667 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9966,14 +10721,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9966 { 10721 {
9967 m_host.AddScriptLPS(1); 10722 m_host.AddScriptLPS(1);
9968 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10723 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9969 if (detectedParams == null) return; // only works on the first detected avatar 10724 if (detectedParams == null)
9970 10725 {
10726 if (m_host.ParentGroup.IsAttachment == true)
10727 {
10728 detectedParams = new DetectParams();
10729 detectedParams.Key = m_host.OwnerID;
10730 }
10731 else
10732 {
10733 return;
10734 }
10735 }
10736
9971 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10737 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9972 if (avatar != null) 10738 if (avatar != null)
9973 { 10739 {
9974 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10740 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9975 simname, pos, lookAt); 10741 simname, pos, lookAt);
9976 } 10742 }
10743
9977 ScriptSleep(1000); 10744 ScriptSleep(1000);
9978 } 10745 }
9979 10746
@@ -10097,12 +10864,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10097 10864
10098 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10865 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10099 object[] data = rules.Data; 10866 object[] data = rules.Data;
10100 for (int i = 0; i < data.Length; ++i) { 10867 for (int i = 0; i < data.Length; ++i)
10868 {
10101 int type = Convert.ToInt32(data[i++].ToString()); 10869 int type = Convert.ToInt32(data[i++].ToString());
10102 if (i >= data.Length) break; // odd number of entries => ignore the last 10870 if (i >= data.Length) break; // odd number of entries => ignore the last
10103 10871
10104 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10872 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10105 switch (type) { 10873 switch (type)
10874 {
10106 case ScriptBaseClass.CAMERA_FOCUS: 10875 case ScriptBaseClass.CAMERA_FOCUS:
10107 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10876 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10108 case ScriptBaseClass.CAMERA_POSITION: 10877 case ScriptBaseClass.CAMERA_POSITION:
@@ -10207,19 +10976,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10207 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10976 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10208 { 10977 {
10209 m_host.AddScriptLPS(1); 10978 m_host.AddScriptLPS(1);
10210 string ret = String.Empty; 10979
10211 string src1 = llBase64ToString(str1); 10980 if (str1 == String.Empty)
10212 string src2 = llBase64ToString(str2); 10981 return String.Empty;
10213 int c = 0; 10982 if (str2 == String.Empty)
10214 for (int i = 0; i < src1.Length; i++) 10983 return str1;
10984
10985 int len = str2.Length;
10986 if ((len % 4) != 0) // LL is EVIL!!!!
10215 { 10987 {
10216 ret += (char) (src1[i] ^ src2[c]); 10988 while (str2.EndsWith("="))
10989 str2 = str2.Substring(0, str2.Length - 1);
10217 10990
10218 c++; 10991 len = str2.Length;
10219 if (c >= src2.Length) 10992 int mod = len % 4;
10220 c = 0; 10993
10994 if (mod == 1)
10995 str2 = str2.Substring(0, str2.Length - 1);
10996 else if (mod == 2)
10997 str2 += "==";
10998 else if (mod == 3)
10999 str2 += "=";
10221 } 11000 }
10222 return llStringToBase64(ret); 11001
11002 byte[] data1;
11003 byte[] data2;
11004 try
11005 {
11006 data1 = Convert.FromBase64String(str1);
11007 data2 = Convert.FromBase64String(str2);
11008 }
11009 catch (Exception)
11010 {
11011 return new LSL_String(String.Empty);
11012 }
11013
11014 byte[] d2 = new Byte[data1.Length];
11015 int pos = 0;
11016
11017 if (data1.Length <= data2.Length)
11018 {
11019 Array.Copy(data2, 0, d2, 0, data1.Length);
11020 }
11021 else
11022 {
11023 while (pos < data1.Length)
11024 {
11025 len = data1.Length - pos;
11026 if (len > data2.Length)
11027 len = data2.Length;
11028
11029 Array.Copy(data2, 0, d2, pos, len);
11030 pos += len;
11031 }
11032 }
11033
11034 for (pos = 0 ; pos < data1.Length ; pos++ )
11035 data1[pos] ^= d2[pos];
11036
11037 return Convert.ToBase64String(data1);
10223 } 11038 }
10224 11039
10225 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11040 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10272,16 +11087,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10272 if (userAgent != null) 11087 if (userAgent != null)
10273 httpHeaders["User-Agent"] = userAgent; 11088 httpHeaders["User-Agent"] = userAgent;
10274 11089
11090 // See if the URL contains any header hacks
11091 string[] urlParts = url.Split(new char[] {'\n'});
11092 if (urlParts.Length > 1)
11093 {
11094 // Iterate the passed headers and parse them
11095 for (int i = 1 ; i < urlParts.Length ; i++ )
11096 {
11097 // The rest of those would be added to the body in SL.
11098 // Let's not do that.
11099 if (urlParts[i] == String.Empty)
11100 break;
11101
11102 // See if this could be a valid header
11103 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11104 if (headerParts.Length != 2)
11105 continue;
11106
11107 string headerName = headerParts[0].Trim();
11108 string headerValue = headerParts[1].Trim();
11109
11110 // Filter out headers that could be used to abuse
11111 // another system or cloak the request
11112 if (headerName.ToLower() == "x-secondlife-shard" ||
11113 headerName.ToLower() == "x-secondlife-object-name" ||
11114 headerName.ToLower() == "x-secondlife-object-key" ||
11115 headerName.ToLower() == "x-secondlife-region" ||
11116 headerName.ToLower() == "x-secondlife-local-position" ||
11117 headerName.ToLower() == "x-secondlife-local-velocity" ||
11118 headerName.ToLower() == "x-secondlife-local-rotation" ||
11119 headerName.ToLower() == "x-secondlife-owner-name" ||
11120 headerName.ToLower() == "x-secondlife-owner-key" ||
11121 headerName.ToLower() == "connection" ||
11122 headerName.ToLower() == "content-length" ||
11123 headerName.ToLower() == "from" ||
11124 headerName.ToLower() == "host" ||
11125 headerName.ToLower() == "proxy-authorization" ||
11126 headerName.ToLower() == "referer" ||
11127 headerName.ToLower() == "trailer" ||
11128 headerName.ToLower() == "transfer-encoding" ||
11129 headerName.ToLower() == "via" ||
11130 headerName.ToLower() == "authorization")
11131 continue;
11132
11133 httpHeaders[headerName] = headerValue;
11134 }
11135
11136 // Finally, strip any protocol specifier from the URL
11137 url = urlParts[0].Trim();
11138 int idx = url.IndexOf(" HTTP/");
11139 if (idx != -1)
11140 url = url.Substring(0, idx);
11141 }
11142
10275 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11143 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10276 Regex r = new Regex(authregex); 11144 Regex r = new Regex(authregex);
10277 int[] gnums = r.GetGroupNumbers(); 11145 int[] gnums = r.GetGroupNumbers();
10278 Match m = r.Match(url); 11146 Match m = r.Match(url);
10279 if (m.Success) { 11147 if (m.Success)
10280 for (int i = 1; i < gnums.Length; i++) { 11148 {
11149 for (int i = 1; i < gnums.Length; i++)
11150 {
10281 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11151 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10282 //CaptureCollection cc = g.Captures; 11152 //CaptureCollection cc = g.Captures;
10283 } 11153 }
10284 if (m.Groups.Count == 5) { 11154 if (m.Groups.Count == 5)
11155 {
10285 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11156 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10286 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11157 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10287 } 11158 }
@@ -10484,6 +11355,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10484 11355
10485 LSL_List ret = new LSL_List(); 11356 LSL_List ret = new LSL_List();
10486 UUID key = new UUID(); 11357 UUID key = new UUID();
11358
11359
10487 if (UUID.TryParse(id, out key)) 11360 if (UUID.TryParse(id, out key))
10488 { 11361 {
10489 ScenePresence av = World.GetScenePresence(key); 11362 ScenePresence av = World.GetScenePresence(key);
@@ -10501,13 +11374,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10501 ret.Add(new LSL_String("")); 11374 ret.Add(new LSL_String(""));
10502 break; 11375 break;
10503 case ScriptBaseClass.OBJECT_POS: 11376 case ScriptBaseClass.OBJECT_POS:
10504 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11377 Vector3 avpos;
11378
11379 if (av.ParentID != 0 && av.ParentPart != null)
11380 {
11381 avpos = av.OffsetPosition;
11382
11383 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11384 avpos -= sitOffset;
11385
11386 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11387 }
11388 else
11389 avpos = av.AbsolutePosition;
11390
11391 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10505 break; 11392 break;
10506 case ScriptBaseClass.OBJECT_ROT: 11393 case ScriptBaseClass.OBJECT_ROT:
10507 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11394 Quaternion avrot = av.Rotation;
11395 if (av.ParentID != 0 && av.ParentPart != null)
11396 {
11397 avrot = av.ParentPart.GetWorldRotation() * avrot;
11398 }
11399 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10508 break; 11400 break;
10509 case ScriptBaseClass.OBJECT_VELOCITY: 11401 case ScriptBaseClass.OBJECT_VELOCITY:
10510 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11402 Vector3 avvel = av.Velocity;
11403 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10511 break; 11404 break;
10512 case ScriptBaseClass.OBJECT_OWNER: 11405 case ScriptBaseClass.OBJECT_OWNER:
10513 ret.Add(new LSL_String(id)); 11406 ret.Add(new LSL_String(id));
@@ -10563,11 +11456,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10563 case ScriptBaseClass.OBJECT_NAME: 11456 case ScriptBaseClass.OBJECT_NAME:
10564 ret.Add(new LSL_String(obj.Name)); 11457 ret.Add(new LSL_String(obj.Name));
10565 break; 11458 break;
10566 case ScriptBaseClass.OBJECT_DESC: 11459 case ScriptBaseClass.OBJECT_DESC:
10567 ret.Add(new LSL_String(obj.Description)); 11460 ret.Add(new LSL_String(obj.Description));
10568 break; 11461 break;
10569 case ScriptBaseClass.OBJECT_POS: 11462 case ScriptBaseClass.OBJECT_POS:
10570 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11463 Vector3 opos = obj.AbsolutePosition;
11464 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10571 break; 11465 break;
10572 case ScriptBaseClass.OBJECT_ROT: 11466 case ScriptBaseClass.OBJECT_ROT:
10573 { 11467 {
@@ -10617,9 +11511,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10617 // The value returned in SL for normal prims is prim count 11511 // The value returned in SL for normal prims is prim count
10618 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11512 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10619 break; 11513 break;
10620 // The following 3 costs I have intentionaly coded to return zero. They are part of 11514
10621 // "Land Impact" calculations. These calculations are probably not applicable 11515 // costs below may need to be diferent for root parts, need to check
10622 // to OpenSim and are not yet complete in SL
10623 case ScriptBaseClass.OBJECT_SERVER_COST: 11516 case ScriptBaseClass.OBJECT_SERVER_COST:
10624 // The linden calculation is here 11517 // The linden calculation is here
10625 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11518 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10627,16 +11520,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10627 ret.Add(new LSL_Float(0)); 11520 ret.Add(new LSL_Float(0));
10628 break; 11521 break;
10629 case ScriptBaseClass.OBJECT_STREAMING_COST: 11522 case ScriptBaseClass.OBJECT_STREAMING_COST:
10630 // The linden calculation is here 11523 // The value returned in SL for normal prims is prim count * 0.06
10631 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11524 ret.Add(new LSL_Float(obj.StreamingCost));
10632 // The value returned in SL for normal prims looks like the prim count * 0.06
10633 ret.Add(new LSL_Float(0));
10634 break; 11525 break;
10635 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11526 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10636 // The linden calculation is here 11527 // The value returned in SL for normal prims is prim count
10637 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11528 ret.Add(new LSL_Float(obj.PhysicsCost));
10638 // The value returned in SL for normal prims looks like the prim count
10639 ret.Add(new LSL_Float(0));
10640 break; 11529 break;
10641 default: 11530 default:
10642 // Invalid or unhandled constant. 11531 // Invalid or unhandled constant.
@@ -10847,15 +11736,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10847 return result; 11736 return result;
10848 } 11737 }
10849 11738
10850 public void print(string str) 11739 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10851 { 11740 {
10852 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11741 List<SceneObjectPart> parts = GetLinkParts(link);
10853 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11742 if (parts.Count < 1)
10854 if (ossl != null) 11743 return 0;
10855 { 11744
10856 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11745 return GetNumberOfSides(parts[0]);
10857 m_log.Info("LSL print():" + str);
10858 }
10859 } 11746 }
10860 11747
10861 private string Name2Username(string name) 11748 private string Name2Username(string name)
@@ -10900,7 +11787,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10900 11787
10901 return rq.ToString(); 11788 return rq.ToString();
10902 } 11789 }
10903 11790/*
11791 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11792 {
11793 m_SayShoutCount = 0;
11794 }
11795*/
10904 private struct Tri 11796 private struct Tri
10905 { 11797 {
10906 public Vector3 p1; 11798 public Vector3 p1;
@@ -11040,9 +11932,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11040 11932
11041 ContactResult result = new ContactResult (); 11933 ContactResult result = new ContactResult ();
11042 result.ConsumerID = group.LocalId; 11934 result.ConsumerID = group.LocalId;
11043 result.Depth = intersection.distance; 11935// result.Depth = intersection.distance;
11044 result.Normal = intersection.normal; 11936 result.Normal = intersection.normal;
11045 result.Pos = intersection.ipoint; 11937 result.Pos = intersection.ipoint;
11938 result.Depth = Vector3.Mag(rayStart - result.Pos);
11046 11939
11047 contacts.Add(result); 11940 contacts.Add(result);
11048 }); 11941 });
@@ -11175,6 +12068,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11175 12068
11176 return contacts[0]; 12069 return contacts[0];
11177 } 12070 }
12071/*
12072 // not done:
12073 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12074 {
12075 ContactResult[] contacts = null;
12076 World.ForEachSOG(delegate(SceneObjectGroup group)
12077 {
12078 if (m_host.ParentGroup == group)
12079 return;
12080
12081 if (group.IsAttachment)
12082 return;
12083
12084 if(group.RootPart.PhysActor != null)
12085 return;
12086
12087 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12088 });
12089 return contacts;
12090 }
12091*/
11178 12092
11179 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12093 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11180 { 12094 {
@@ -11216,32 +12130,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11216 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12130 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11217 12131
11218 12132
11219 if (checkTerrain) 12133 if (World.SuportsRayCastFiltered())
11220 { 12134 {
11221 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12135 if (dist == 0)
11222 if (groundContact != null) 12136 return list;
11223 results.Add((ContactResult)groundContact);
11224 }
11225 12137
11226 if (checkAgents) 12138 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11227 { 12139 if (checkTerrain)
11228 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12140 rayfilter |= RayFilterFlags.land;
11229 foreach (ContactResult r in agentHits) 12141// if (checkAgents)
11230 results.Add(r); 12142// rayfilter |= RayFilterFlags.agent;
11231 } 12143 if (checkPhysical)
12144 rayfilter |= RayFilterFlags.physical;
12145 if (checkNonPhysical)
12146 rayfilter |= RayFilterFlags.nonphysical;
12147 if (detectPhantom)
12148 rayfilter |= RayFilterFlags.LSLPhanton;
12149
12150 Vector3 direction = dir * ( 1/dist);
12151
12152 if(rayfilter == 0)
12153 {
12154 list.Add(new LSL_Integer(0));
12155 return list;
12156 }
11232 12157
11233 if (checkPhysical || checkNonPhysical || detectPhantom) 12158 // get some more contacts to sort ???
12159 int physcount = 4 * count;
12160 if (physcount > 20)
12161 physcount = 20;
12162
12163 object physresults;
12164 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12165
12166 if (physresults == null)
12167 {
12168 list.Add(new LSL_Integer(-3)); // timeout error
12169 return list;
12170 }
12171
12172 results = (List<ContactResult>)physresults;
12173
12174 // for now physics doesn't detect sitted avatars so do it outside physics
12175 if (checkAgents)
12176 {
12177 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12178 foreach (ContactResult r in agentHits)
12179 results.Add(r);
12180 }
12181
12182 // TODO: Replace this with a better solution. ObjectIntersection can only
12183 // detect nonphysical phantoms. They are detected by virtue of being
12184 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12185 // physicsl phantoms as done by the physics scene
12186 // We don't want anything else but phantoms here.
12187 if (detectPhantom)
12188 {
12189 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12190 foreach (ContactResult r in objectHits)
12191 results.Add(r);
12192 }
12193 }
12194 else
11234 { 12195 {
11235 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12196 if (checkTerrain)
11236 foreach (ContactResult r in objectHits) 12197 {
11237 results.Add(r); 12198 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12199 if (groundContact != null)
12200 results.Add((ContactResult)groundContact);
12201 }
12202
12203 if (checkAgents)
12204 {
12205 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12206 foreach (ContactResult r in agentHits)
12207 results.Add(r);
12208 }
12209
12210 if (checkPhysical || checkNonPhysical || detectPhantom)
12211 {
12212 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12213 foreach (ContactResult r in objectHits)
12214 results.Add(r);
12215 }
11238 } 12216 }
11239 12217
11240 results.Sort(delegate(ContactResult a, ContactResult b) 12218 results.Sort(delegate(ContactResult a, ContactResult b)
11241 { 12219 {
11242 return a.Depth.CompareTo(b.Depth); 12220 return a.Depth.CompareTo(b.Depth);
11243 }); 12221 });
11244 12222
11245 int values = 0; 12223 int values = 0;
11246 SceneObjectGroup thisgrp = m_host.ParentGroup; 12224 SceneObjectGroup thisgrp = m_host.ParentGroup;
11247 12225
@@ -11334,7 +12312,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11334 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12312 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11335 if (!isAccount) return 0; 12313 if (!isAccount) return 0;
11336 if (estate.HasAccess(id)) return 1; 12314 if (estate.HasAccess(id)) return 1;
11337 if (estate.IsBanned(id)) 12315 if (estate.IsBanned(id, World.GetUserFlags(id)))
11338 estate.RemoveBan(id); 12316 estate.RemoveBan(id);
11339 estate.AddEstateUser(id); 12317 estate.AddEstateUser(id);
11340 break; 12318 break;
@@ -11353,14 +12331,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11353 break; 12331 break;
11354 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12332 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11355 if (!isAccount) return 0; 12333 if (!isAccount) return 0;
11356 if (estate.IsBanned(id)) return 1; 12334 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11357 EstateBan ban = new EstateBan(); 12335 EstateBan ban = new EstateBan();
11358 ban.EstateID = estate.EstateID; 12336 ban.EstateID = estate.EstateID;
11359 ban.BannedUserID = id; 12337 ban.BannedUserID = id;
11360 estate.AddBan(ban); 12338 estate.AddBan(ban);
11361 break; 12339 break;
11362 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12340 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11363 if (!isAccount || !estate.IsBanned(id)) return 0; 12341 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11364 estate.RemoveBan(id); 12342 estate.RemoveBan(id);
11365 break; 12343 break;
11366 default: return 0; 12344 default: return 0;
@@ -11389,7 +12367,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11389 return 16384; 12367 return 16384;
11390 } 12368 }
11391 12369
11392 public LSL_Integer llGetUsedMemory() 12370 public virtual LSL_Integer llGetUsedMemory()
11393 { 12371 {
11394 m_host.AddScriptLPS(1); 12372 m_host.AddScriptLPS(1);
11395 // The value returned for LSO scripts in SL 12373 // The value returned for LSO scripts in SL
@@ -11417,22 +12395,731 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11417 public void llSetSoundQueueing(int queue) 12395 public void llSetSoundQueueing(int queue)
11418 { 12396 {
11419 m_host.AddScriptLPS(1); 12397 m_host.AddScriptLPS(1);
11420 NotImplemented("llSetSoundQueueing");
11421 } 12398 }
11422 12399
11423 public void llCollisionSprite(string impact_sprite) 12400 public void llCollisionSprite(string impact_sprite)
11424 { 12401 {
11425 m_host.AddScriptLPS(1); 12402 m_host.AddScriptLPS(1);
11426 NotImplemented("llCollisionSprite"); 12403 // Viewer 2.0 broke this and it's likely LL has no intention
12404 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11427 } 12405 }
11428 12406
11429 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12407 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11430 { 12408 {
11431 m_host.AddScriptLPS(1); 12409 m_host.AddScriptLPS(1);
11432 NotImplemented("llGodLikeRezObject"); 12410
12411 if (!World.Permissions.IsGod(m_host.OwnerID))
12412 NotImplemented("llGodLikeRezObject");
12413
12414 AssetBase rezAsset = World.AssetService.Get(inventory);
12415 if (rezAsset == null)
12416 {
12417 llSay(0, "Asset not found");
12418 return;
12419 }
12420
12421 SceneObjectGroup group = null;
12422
12423 try
12424 {
12425 string xmlData = Utils.BytesToString(rezAsset.Data);
12426 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12427 }
12428 catch
12429 {
12430 llSay(0, "Asset not found");
12431 return;
12432 }
12433
12434 if (group == null)
12435 {
12436 llSay(0, "Asset not found");
12437 return;
12438 }
12439
12440 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12441 group.RootPart.AttachOffset = group.AbsolutePosition;
12442
12443 group.ResetIDs();
12444
12445 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12446 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12447 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12448 group.ScheduleGroupForFullUpdate();
12449
12450 // objects rezzed with this method are die_at_edge by default.
12451 group.RootPart.SetDieAtEdge(true);
12452
12453 group.ResumeScripts();
12454
12455 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12456 "object_rez", new Object[] {
12457 new LSL_String(
12458 group.RootPart.UUID.ToString()) },
12459 new DetectParams[0]));
12460 }
12461
12462 public LSL_String llTransferLindenDollars(string destination, int amount)
12463 {
12464 UUID txn = UUID.Random();
12465
12466 Util.FireAndForget(delegate(object x)
12467 {
12468 int replycode = 0;
12469 string replydata = destination + "," + amount.ToString();
12470
12471 try
12472 {
12473 TaskInventoryItem item = m_item;
12474 if (item == null)
12475 {
12476 replydata = "SERVICE_ERROR";
12477 return;
12478 }
12479
12480 m_host.AddScriptLPS(1);
12481
12482 if (item.PermsGranter == UUID.Zero)
12483 {
12484 replydata = "MISSING_PERMISSION_DEBIT";
12485 return;
12486 }
12487
12488 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12489 {
12490 replydata = "MISSING_PERMISSION_DEBIT";
12491 return;
12492 }
12493
12494 UUID toID = new UUID();
12495
12496 if (!UUID.TryParse(destination, out toID))
12497 {
12498 replydata = "INVALID_AGENT";
12499 return;
12500 }
12501
12502 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12503
12504 if (money == null)
12505 {
12506 replydata = "TRANSFERS_DISABLED";
12507 return;
12508 }
12509
12510 bool result = money.ObjectGiveMoney(
12511 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12512
12513 if (result)
12514 {
12515 replycode = 1;
12516 return;
12517 }
12518
12519 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12520 }
12521 finally
12522 {
12523 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12524 "transaction_result", new Object[] {
12525 new LSL_String(txn.ToString()),
12526 new LSL_Integer(replycode),
12527 new LSL_String(replydata) },
12528 new DetectParams[0]));
12529 }
12530 });
12531
12532 return txn.ToString();
11433 } 12533 }
11434 12534
11435 #endregion 12535 #endregion
12536
12537 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12538 {
12539 SceneObjectGroup group = m_host.ParentGroup;
12540
12541 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12542 return;
12543 if (group.IsAttachment)
12544 return;
12545
12546 if (frames.Data.Length > 0) // We are getting a new motion
12547 {
12548 if (group.RootPart.KeyframeMotion != null)
12549 group.RootPart.KeyframeMotion.Delete();
12550 group.RootPart.KeyframeMotion = null;
12551
12552 int idx = 0;
12553
12554 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12555 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12556
12557 while (idx < options.Data.Length)
12558 {
12559 int option = (int)options.GetLSLIntegerItem(idx++);
12560 int remain = options.Data.Length - idx;
12561
12562 switch (option)
12563 {
12564 case ScriptBaseClass.KFM_MODE:
12565 if (remain < 1)
12566 break;
12567 int modeval = (int)options.GetLSLIntegerItem(idx++);
12568 switch(modeval)
12569 {
12570 case ScriptBaseClass.KFM_FORWARD:
12571 mode = KeyframeMotion.PlayMode.Forward;
12572 break;
12573 case ScriptBaseClass.KFM_REVERSE:
12574 mode = KeyframeMotion.PlayMode.Reverse;
12575 break;
12576 case ScriptBaseClass.KFM_LOOP:
12577 mode = KeyframeMotion.PlayMode.Loop;
12578 break;
12579 case ScriptBaseClass.KFM_PING_PONG:
12580 mode = KeyframeMotion.PlayMode.PingPong;
12581 break;
12582 }
12583 break;
12584 case ScriptBaseClass.KFM_DATA:
12585 if (remain < 1)
12586 break;
12587 int dataval = (int)options.GetLSLIntegerItem(idx++);
12588 data = (KeyframeMotion.DataFormat)dataval;
12589 break;
12590 }
12591 }
12592
12593 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12594
12595 idx = 0;
12596
12597 int elemLength = 2;
12598 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12599 elemLength = 3;
12600
12601 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12602 while (idx < frames.Data.Length)
12603 {
12604 int remain = frames.Data.Length - idx;
12605
12606 if (remain < elemLength)
12607 break;
12608
12609 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12610 frame.Position = null;
12611 frame.Rotation = null;
12612
12613 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12614 {
12615 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12616 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12617 }
12618 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12619 {
12620 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12621 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12622 }
12623
12624 float tempf = (float)frames.GetLSLFloatItem(idx++);
12625 frame.TimeMS = (int)(tempf * 1000.0f);
12626
12627 keyframes.Add(frame);
12628 }
12629
12630 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12631 group.RootPart.KeyframeMotion.Start();
12632 }
12633 else
12634 {
12635 if (group.RootPart.KeyframeMotion == null)
12636 return;
12637
12638 if (options.Data.Length == 0)
12639 {
12640 group.RootPart.KeyframeMotion.Stop();
12641 return;
12642 }
12643
12644 int code = (int)options.GetLSLIntegerItem(0);
12645
12646 int idx = 0;
12647
12648 while (idx < options.Data.Length)
12649 {
12650 int option = (int)options.GetLSLIntegerItem(idx++);
12651 int remain = options.Data.Length - idx;
12652
12653 switch (option)
12654 {
12655 case ScriptBaseClass.KFM_COMMAND:
12656 int cmd = (int)options.GetLSLIntegerItem(idx++);
12657 switch (cmd)
12658 {
12659 case ScriptBaseClass.KFM_CMD_PLAY:
12660 group.RootPart.KeyframeMotion.Start();
12661 break;
12662 case ScriptBaseClass.KFM_CMD_STOP:
12663 group.RootPart.KeyframeMotion.Stop();
12664 break;
12665 case ScriptBaseClass.KFM_CMD_PAUSE:
12666 group.RootPart.KeyframeMotion.Pause();
12667 break;
12668 }
12669 break;
12670 }
12671 }
12672 }
12673 }
12674
12675 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12676 {
12677 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12678
12679 int idx = 0;
12680 int idxStart = 0;
12681
12682 bool positionChanged = false;
12683 Vector3 finalPos = Vector3.Zero;
12684
12685 try
12686 {
12687 while (idx < rules.Length)
12688 {
12689 ++rulesParsed;
12690 int code = rules.GetLSLIntegerItem(idx++);
12691
12692 int remain = rules.Length - idx;
12693 idxStart = idx;
12694
12695 switch (code)
12696 {
12697 case (int)ScriptBaseClass.PRIM_POSITION:
12698 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12699 {
12700 if (remain < 1)
12701 return null;
12702
12703 LSL_Vector v;
12704 v = rules.GetVector3Item(idx++);
12705
12706 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12707 if (part == null)
12708 break;
12709
12710 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12711 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12712 if (part.LinkNum > 1)
12713 {
12714 localRot = GetPartLocalRot(part);
12715 localPos = GetPartLocalPos(part);
12716 }
12717
12718 v -= localPos;
12719 v /= localRot;
12720
12721 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12722
12723 v = v + 2 * sitOffset;
12724
12725 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12726 av.SendAvatarDataToAllAgents();
12727
12728 }
12729 break;
12730
12731 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12732 case (int)ScriptBaseClass.PRIM_ROTATION:
12733 {
12734 if (remain < 1)
12735 return null;
12736
12737 LSL_Rotation r;
12738 r = rules.GetQuaternionItem(idx++);
12739
12740 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12741 if (part == null)
12742 break;
12743
12744 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12745 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12746
12747 if (part.LinkNum > 1)
12748 localRot = GetPartLocalRot(part);
12749
12750 r = r * llGetRootRotation() / localRot;
12751 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12752 av.SendAvatarDataToAllAgents();
12753 }
12754 break;
12755
12756 // parse rest doing nothing but number of parameters error check
12757 case (int)ScriptBaseClass.PRIM_SIZE:
12758 case (int)ScriptBaseClass.PRIM_MATERIAL:
12759 case (int)ScriptBaseClass.PRIM_PHANTOM:
12760 case (int)ScriptBaseClass.PRIM_PHYSICS:
12761 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12762 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12763 case (int)ScriptBaseClass.PRIM_NAME:
12764 case (int)ScriptBaseClass.PRIM_DESC:
12765 if (remain < 1)
12766 return null;
12767 idx++;
12768 break;
12769
12770 case (int)ScriptBaseClass.PRIM_GLOW:
12771 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12772 case (int)ScriptBaseClass.PRIM_TEXGEN:
12773 if (remain < 2)
12774 return null;
12775 idx += 2;
12776 break;
12777
12778 case (int)ScriptBaseClass.PRIM_TYPE:
12779 if (remain < 3)
12780 return null;
12781 code = (int)rules.GetLSLIntegerItem(idx++);
12782 remain = rules.Length - idx;
12783 switch (code)
12784 {
12785 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12786 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12787 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12788 if (remain < 6)
12789 return null;
12790 idx += 6;
12791 break;
12792
12793 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12794 if (remain < 5)
12795 return null;
12796 idx += 5;
12797 break;
12798
12799 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12800 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12801 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12802 if (remain < 11)
12803 return null;
12804 idx += 11;
12805 break;
12806
12807 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12808 if (remain < 2)
12809 return null;
12810 idx += 2;
12811 break;
12812 }
12813 break;
12814
12815 case (int)ScriptBaseClass.PRIM_COLOR:
12816 case (int)ScriptBaseClass.PRIM_TEXT:
12817 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12818 case (int)ScriptBaseClass.PRIM_OMEGA:
12819 if (remain < 3)
12820 return null;
12821 idx += 3;
12822 break;
12823
12824 case (int)ScriptBaseClass.PRIM_TEXTURE:
12825 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12826 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12827 if (remain < 5)
12828 return null;
12829 idx += 5;
12830 break;
12831
12832 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12833 if (remain < 7)
12834 return null;
12835
12836 idx += 7;
12837 break;
12838
12839 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12840 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12841 return null;
12842
12843 return rules.GetSublist(idx, -1);
12844 }
12845 }
12846 }
12847 catch (InvalidCastException e)
12848 {
12849 ShoutError(string.Format(
12850 "{0} error running rule #{1}: arg #{2} ",
12851 originFunc, rulesParsed, idx - idxStart) + e.Message);
12852 }
12853 finally
12854 {
12855 if (positionChanged)
12856 {
12857 av.OffsetPosition = finalPos;
12858// av.SendAvatarDataToAllAgents();
12859 av.SendTerseUpdateToAllClients();
12860 positionChanged = false;
12861 }
12862 }
12863 return null;
12864 }
12865
12866 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12867 {
12868 // avatars case
12869 // replies as SL wiki
12870
12871// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12872 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12873
12874 int idx = 0;
12875 while (idx < rules.Length)
12876 {
12877 int code = (int)rules.GetLSLIntegerItem(idx++);
12878 int remain = rules.Length - idx;
12879
12880 switch (code)
12881 {
12882 case (int)ScriptBaseClass.PRIM_MATERIAL:
12883 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12884 break;
12885
12886 case (int)ScriptBaseClass.PRIM_PHYSICS:
12887 res.Add(new LSL_Integer(0));
12888 break;
12889
12890 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12891 res.Add(new LSL_Integer(0));
12892 break;
12893
12894 case (int)ScriptBaseClass.PRIM_PHANTOM:
12895 res.Add(new LSL_Integer(0));
12896 break;
12897
12898 case (int)ScriptBaseClass.PRIM_POSITION:
12899
12900 Vector3 pos = avatar.OffsetPosition;
12901
12902 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12903 pos -= sitOffset;
12904
12905 if( sitPart != null)
12906 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12907
12908 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12909 break;
12910
12911 case (int)ScriptBaseClass.PRIM_SIZE:
12912 // as in llGetAgentSize above
12913 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12914 break;
12915
12916 case (int)ScriptBaseClass.PRIM_ROTATION:
12917 Quaternion rot = avatar.Rotation;
12918 if (sitPart != null)
12919 {
12920 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12921 }
12922
12923 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12924 break;
12925
12926 case (int)ScriptBaseClass.PRIM_TYPE:
12927 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12928 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12929 res.Add(new LSL_Vector(0f,1.0f,0f));
12930 res.Add(new LSL_Float(0.0f));
12931 res.Add(new LSL_Vector(0, 0, 0));
12932 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12933 res.Add(new LSL_Vector(0, 0, 0));
12934 break;
12935
12936 case (int)ScriptBaseClass.PRIM_TEXTURE:
12937 if (remain < 1)
12938 return null;
12939
12940 int face = (int)rules.GetLSLIntegerItem(idx++);
12941 if (face == ScriptBaseClass.ALL_SIDES)
12942 {
12943 for (face = 0; face < 21; face++)
12944 {
12945 res.Add(new LSL_String(""));
12946 res.Add(new LSL_Vector(0,0,0));
12947 res.Add(new LSL_Vector(0,0,0));
12948 res.Add(new LSL_Float(0.0));
12949 }
12950 }
12951 else
12952 {
12953 if (face >= 0 && face < 21)
12954 {
12955 res.Add(new LSL_String(""));
12956 res.Add(new LSL_Vector(0,0,0));
12957 res.Add(new LSL_Vector(0,0,0));
12958 res.Add(new LSL_Float(0.0));
12959 }
12960 }
12961 break;
12962
12963 case (int)ScriptBaseClass.PRIM_COLOR:
12964 if (remain < 1)
12965 return null;
12966
12967 face = (int)rules.GetLSLIntegerItem(idx++);
12968
12969 if (face == ScriptBaseClass.ALL_SIDES)
12970 {
12971 for (face = 0; face < 21; face++)
12972 {
12973 res.Add(new LSL_Vector(0,0,0));
12974 res.Add(new LSL_Float(0));
12975 }
12976 }
12977 else
12978 {
12979 res.Add(new LSL_Vector(0,0,0));
12980 res.Add(new LSL_Float(0));
12981 }
12982 break;
12983
12984 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12985 if (remain < 1)
12986 return null;
12987 face = (int)rules.GetLSLIntegerItem(idx++);
12988
12989 if (face == ScriptBaseClass.ALL_SIDES)
12990 {
12991 for (face = 0; face < 21; face++)
12992 {
12993 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12994 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12995 }
12996 }
12997 else
12998 {
12999 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13000 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13001 }
13002 break;
13003
13004 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13005 if (remain < 1)
13006 return null;
13007 face = (int)rules.GetLSLIntegerItem(idx++);
13008
13009 if (face == ScriptBaseClass.ALL_SIDES)
13010 {
13011 for (face = 0; face < 21; face++)
13012 {
13013 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13014 }
13015 }
13016 else
13017 {
13018 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13019 }
13020 break;
13021
13022 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13023 res.Add(new LSL_Integer(0));
13024 res.Add(new LSL_Integer(0));// softness
13025 res.Add(new LSL_Float(0.0f)); // gravity
13026 res.Add(new LSL_Float(0.0f)); // friction
13027 res.Add(new LSL_Float(0.0f)); // wind
13028 res.Add(new LSL_Float(0.0f)); // tension
13029 res.Add(new LSL_Vector(0f,0f,0f));
13030 break;
13031
13032 case (int)ScriptBaseClass.PRIM_TEXGEN:
13033 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13034 if (remain < 1)
13035 return null;
13036 face = (int)rules.GetLSLIntegerItem(idx++);
13037
13038 if (face == ScriptBaseClass.ALL_SIDES)
13039 {
13040 for (face = 0; face < 21; face++)
13041 {
13042 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13043 }
13044 }
13045 else
13046 {
13047 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13048 }
13049 break;
13050
13051 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13052 res.Add(new LSL_Integer(0));
13053 res.Add(new LSL_Vector(0f,0f,0f));
13054 res.Add(new LSL_Float(0f)); // intensity
13055 res.Add(new LSL_Float(0f)); // radius
13056 res.Add(new LSL_Float(0f)); // falloff
13057 break;
13058
13059 case (int)ScriptBaseClass.PRIM_GLOW:
13060 if (remain < 1)
13061 return null;
13062 face = (int)rules.GetLSLIntegerItem(idx++);
13063
13064 if (face == ScriptBaseClass.ALL_SIDES)
13065 {
13066 for (face = 0; face < 21; face++)
13067 {
13068 res.Add(new LSL_Float(0f));
13069 }
13070 }
13071 else
13072 {
13073 res.Add(new LSL_Float(0f));
13074 }
13075 break;
13076
13077 case (int)ScriptBaseClass.PRIM_TEXT:
13078 res.Add(new LSL_String(""));
13079 res.Add(new LSL_Vector(0f,0f,0f));
13080 res.Add(new LSL_Float(1.0f));
13081 break;
13082
13083 case (int)ScriptBaseClass.PRIM_NAME:
13084 res.Add(new LSL_String(avatar.Name));
13085 break;
13086
13087 case (int)ScriptBaseClass.PRIM_DESC:
13088 res.Add(new LSL_String(""));
13089 break;
13090
13091 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13092 Quaternion lrot = avatar.Rotation;
13093
13094 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13095 {
13096 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13097 }
13098 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13099 break;
13100
13101 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13102 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13103 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13104 lpos -= lsitOffset;
13105
13106 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13107 {
13108 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13109 }
13110 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13111 break;
13112
13113 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13114 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13115 return null;
13116
13117 return rules.GetSublist(idx, -1);
13118 }
13119 }
13120
13121 return null;
13122 }
11436 } 13123 }
11437 13124
11438 public class NotecardCache 13125 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 29bc163..17277d7 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -138,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
139 internal float m_ScriptDelayFactor = 1.0f; 139 internal float m_ScriptDelayFactor = 1.0f;
140 internal float m_ScriptDistanceFactor = 1.0f; 140 internal float m_ScriptDistanceFactor = 1.0f;
141 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 143
143 protected IUrlModule m_UrlModule = null; 144 protected IUrlModule m_UrlModule = null;
@@ -147,6 +148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
147 m_ScriptEngine = ScriptEngine; 148 m_ScriptEngine = ScriptEngine;
148 m_host = host; 149 m_host = host;
149 m_item = item; 150 m_item = item;
151 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
150 152
151 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 153 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
152 154
@@ -210,7 +212,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
210 212
211 internal void OSSLError(string msg) 213 internal void OSSLError(string msg)
212 { 214 {
213 throw new Exception("OSSL Runtime Error: " + msg); 215 if (m_debuggerSafe)
216 {
217 OSSLShoutError(msg);
218 }
219 else
220 {
221 throw new Exception("OSSL Runtime Error: " + msg);
222 }
214 } 223 }
215 224
216 /// <summary> 225 /// <summary>
@@ -918,18 +927,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
918 if (target != null) 927 if (target != null)
919 { 928 {
920 UUID animID=UUID.Zero; 929 UUID animID=UUID.Zero;
921 lock (m_host.TaskInventory) 930 m_host.TaskInventory.LockItemsForRead(true);
931 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
922 { 932 {
923 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 933 if (inv.Value.Name == animation)
924 { 934 {
925 if (inv.Value.Name == animation) 935 if (inv.Value.Type == (int)AssetType.Animation)
926 { 936 animID = inv.Value.AssetID;
927 if (inv.Value.Type == (int)AssetType.Animation) 937 continue;
928 animID = inv.Value.AssetID;
929 continue;
930 }
931 } 938 }
932 } 939 }
940 m_host.TaskInventory.LockItemsForRead(false);
933 if (animID == UUID.Zero) 941 if (animID == UUID.Zero)
934 target.Animator.AddAnimation(animation, m_host.UUID); 942 target.Animator.AddAnimation(animation, m_host.UUID);
935 else 943 else
@@ -970,6 +978,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
970 else 978 else
971 animID = UUID.Zero; 979 animID = UUID.Zero;
972 } 980 }
981 m_host.TaskInventory.LockItemsForRead(false);
973 982
974 if (animID == UUID.Zero) 983 if (animID == UUID.Zero)
975 target.Animator.RemoveAnimation(animation); 984 target.Animator.RemoveAnimation(animation);
@@ -1808,6 +1817,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1808 1817
1809 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1818 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1810 { 1819 {
1820 m_host.TaskInventory.LockItemsForRead(true);
1811 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1821 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1812 { 1822 {
1813 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1823 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1815,6 +1825,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1815 assetID = item.AssetID; 1825 assetID = item.AssetID;
1816 } 1826 }
1817 } 1827 }
1828 m_host.TaskInventory.LockItemsForRead(false);
1818 } 1829 }
1819 1830
1820 if (assetID == UUID.Zero) 1831 if (assetID == UUID.Zero)
@@ -2300,7 +2311,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2300 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2311 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2301 m_host.AddScriptLPS(1); 2312 m_host.AddScriptLPS(1);
2302 2313
2303 return NpcCreate(firstname, lastname, position, notecard, false, false); 2314 return NpcCreate(firstname, lastname, position, notecard, true, false);
2304 } 2315 }
2305 2316
2306 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2317 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2311,24 +2322,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2311 return NpcCreate( 2322 return NpcCreate(
2312 firstname, lastname, position, notecard, 2323 firstname, lastname, position, notecard,
2313 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2324 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2314 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2325 false);
2326// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2315 } 2327 }
2316 2328
2317 private LSL_Key NpcCreate( 2329 private LSL_Key NpcCreate(
2318 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2330 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2319 { 2331 {
2332 if (!owned)
2333 OSSLError("Unowned NPCs are unsupported");
2334
2335 string groupTitle = String.Empty;
2336
2337 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2338 return new LSL_Key(UUID.Zero.ToString());
2339
2340 if (firstname != String.Empty || lastname != String.Empty)
2341 {
2342 if (firstname != "Shown outfit:")
2343 groupTitle = "- NPC -";
2344 }
2345
2320 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2346 INPCModule module = World.RequestModuleInterface<INPCModule>();
2321 if (module != null) 2347 if (module != null)
2322 { 2348 {
2323 AvatarAppearance appearance = null; 2349 AvatarAppearance appearance = null;
2324 2350
2325 UUID id; 2351// UUID id;
2326 if (UUID.TryParse(notecard, out id)) 2352// if (UUID.TryParse(notecard, out id))
2327 { 2353// {
2328 ScenePresence clonePresence = World.GetScenePresence(id); 2354// ScenePresence clonePresence = World.GetScenePresence(id);
2329 if (clonePresence != null) 2355// if (clonePresence != null)
2330 appearance = clonePresence.Appearance; 2356// appearance = clonePresence.Appearance;
2331 } 2357// }
2332 2358
2333 if (appearance == null) 2359 if (appearance == null)
2334 { 2360 {
@@ -2336,9 +2362,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2336 2362
2337 if (appearanceSerialized != null) 2363 if (appearanceSerialized != null)
2338 { 2364 {
2339 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2365 try
2340 appearance = new AvatarAppearance(); 2366 {
2341 appearance.Unpack(appearanceOsd); 2367 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2368 appearance = new AvatarAppearance();
2369 appearance.Unpack(appearanceOsd);
2370 }
2371 catch
2372 {
2373 return UUID.Zero.ToString();
2374 }
2342 } 2375 }
2343 } 2376 }
2344 2377
@@ -2356,6 +2389,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2356 World, 2389 World,
2357 appearance); 2390 appearance);
2358 2391
2392 ScenePresence sp;
2393 if (World.TryGetScenePresence(x, out sp))
2394 {
2395 sp.Grouptitle = groupTitle;
2396 sp.SendAvatarDataToAllAgents();
2397 }
2359 return new LSL_Key(x.ToString()); 2398 return new LSL_Key(x.ToString());
2360 } 2399 }
2361 2400
@@ -2655,16 +2694,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2655 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2694 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2656 m_host.AddScriptLPS(1); 2695 m_host.AddScriptLPS(1);
2657 2696
2658 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2697 ManualResetEvent ev = new ManualResetEvent(false);
2659 if (module != null)
2660 {
2661 UUID npcId = new UUID(npc.m_string);
2662 2698
2663 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2699 Util.FireAndForget(delegate(object x) {
2664 return; 2700 try
2701 {
2702 INPCModule module = World.RequestModuleInterface<INPCModule>();
2703 if (module != null)
2704 {
2705 UUID npcId = new UUID(npc.m_string);
2665 2706
2666 module.DeleteNPC(npcId, World); 2707 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2667 } 2708 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2709 {
2710 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2711 return;
2712 }
2713
2714 module.DeleteNPC(npcId, World);
2715 }
2716 }
2717 finally
2718 {
2719 ev.Set();
2720 }
2721 });
2722 ev.WaitOne();
2668 } 2723 }
2669 2724
2670 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2725 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3637,4 +3692,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3637 DropAttachmentAt(false, pos, rot); 3692 DropAttachmentAt(false, pos, rot);
3638 } 3693 }
3639 } 3694 }
3640} \ No newline at end of file 3695}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 24cceea..4dd795d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -70,7 +70,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
70 private const int AGENT = 1; 70 private const int AGENT = 1;
71 private const int AGENT_BY_USERNAME = 0x10; 71 private const int AGENT_BY_USERNAME = 0x10;
72 private const int NPC = 0x20; 72 private const int NPC = 0x20;
73 private const int OS_NPC = 0x01000000;
74 private const int ACTIVE = 2; 73 private const int ACTIVE = 2;
75 private const int PASSIVE = 4; 74 private const int PASSIVE = 4;
76 private const int SCRIPTED = 8; 75 private const int SCRIPTED = 8;
@@ -235,7 +234,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
235 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 234 List<SensedEntity> sensedEntities = new List<SensedEntity>();
236 235
237 // Is the sensor type is AGENT and not SCRIPTED then include agents 236 // Is the sensor type is AGENT and not SCRIPTED then include agents
238 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 237 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
239 { 238 {
240 sensedEntities.AddRange(doAgentSensor(ts)); 239 sensedEntities.AddRange(doAgentSensor(ts));
241 } 240 }
@@ -334,7 +333,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
334 float dy; 333 float dy;
335 float dz; 334 float dz;
336 335
337 Quaternion q = SensePoint.GetWorldRotation(); 336// Quaternion q = SensePoint.RotationOffset;
337 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
338 if (SensePoint.ParentGroup.IsAttachment) 338 if (SensePoint.ParentGroup.IsAttachment)
339 { 339 {
340 // In attachments, rotate the sensor cone with the 340 // In attachments, rotate the sensor cone with the
@@ -348,7 +348,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
348 // Position of a sensor in a child prim attached to an avatar 348 // Position of a sensor in a child prim attached to an avatar
349 // will be still wrong. 349 // will be still wrong.
350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
351 q = avatar.Rotation * q; 351 fromRegionPos = avatar.AbsolutePosition;
352 q = avatar.Rotation;
352 } 353 }
353 354
354 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -475,7 +476,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
475 // Position of a sensor in a child prim attached to an avatar 476 // Position of a sensor in a child prim attached to an avatar
476 // will be still wrong. 477 // will be still wrong.
477 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 478 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
478 q = avatar.Rotation * q; 479 if (avatar == null)
480 return sensedEntities;
481 fromRegionPos = avatar.AbsolutePosition;
482 q = avatar.Rotation;
479 } 483 }
480 484
481 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 485 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -491,7 +495,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
491// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 495// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
492// presence.Name, presence.PresenceType, ts.name, ts.type); 496// presence.Name, presence.PresenceType, ts.name, ts.type);
493 497
494 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 498 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
495 { 499 {
496 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 500 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
497 if (npcData == null || !npcData.SenseAsAgent) 501 if (npcData == null || !npcData.SenseAsAgent)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index bc63030..9ee6946 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -118,25 +118,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
118 if (Timers.Count == 0) 118 if (Timers.Count == 0)
119 return; 119 return;
120 120
121 Dictionary<string, TimerClass>.ValueCollection tvals;
121 lock (TimerListLock) 122 lock (TimerListLock)
122 { 123 {
123 // Go through all timers 124 // Go through all timers
124 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 125 tvals = Timers.Values;
125 foreach (TimerClass ts in tvals) 126 }
127
128 foreach (TimerClass ts in tvals)
129 {
130 // Time has passed?
131 if (ts.next < DateTime.Now.Ticks)
126 { 132 {
127 // Time has passed? 133 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
128 if (ts.next < DateTime.Now.Ticks) 134 // Add it to queue
129 { 135 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
130 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 136 new EventParams("timer", new Object[0],
131 // Add it to queue 137 new DetectParams[0]));
132 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 138 // set next interval
133 new EventParams("timer", new Object[0], 139
134 new DetectParams[0])); 140 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 // set next interval 141 ts.next = DateTime.Now.Ticks + ts.interval;
136
137 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
138 ts.next = DateTime.Now.Ticks + ts.interval;
139 }
140 } 142 }
141 } 143 }
142 } 144 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index e97ff9d..05c20f9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -126,6 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
126 LSL_Float llGetEnergy(); 126 LSL_Float llGetEnergy();
127 LSL_Vector llGetForce(); 127 LSL_Vector llGetForce();
128 LSL_Integer llGetFreeMemory(); 128 LSL_Integer llGetFreeMemory();
129 LSL_Integer llGetUsedMemory();
129 LSL_Integer llGetFreeURLs(); 130 LSL_Integer llGetFreeURLs();
130 LSL_Vector llGetGeometricCenter(); 131 LSL_Vector llGetGeometricCenter();
131 LSL_Float llGetGMTclock(); 132 LSL_Float llGetGMTclock();
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
149 LSL_Vector llGetLocalPos(); 150 LSL_Vector llGetLocalPos();
150 LSL_Rotation llGetLocalRot(); 151 LSL_Rotation llGetLocalRot();
151 LSL_Float llGetMass(); 152 LSL_Float llGetMass();
153 LSL_Float llGetMassMKS();
152 LSL_Integer llGetMemoryLimit(); 154 LSL_Integer llGetMemoryLimit();
153 void llGetNextEmail(string address, string subject); 155 void llGetNextEmail(string address, string subject);
154 LSL_String llGetNotecardLine(string name, int line); 156 LSL_String llGetNotecardLine(string name, int line);
@@ -202,12 +204,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
202 LSL_String llGetTimestamp(); 204 LSL_String llGetTimestamp();
203 LSL_Vector llGetTorque(); 205 LSL_Vector llGetTorque();
204 LSL_Integer llGetUnixTime(); 206 LSL_Integer llGetUnixTime();
205 LSL_Integer llGetUsedMemory();
206 LSL_Vector llGetVel(); 207 LSL_Vector llGetVel();
207 LSL_Float llGetWallclock(); 208 LSL_Float llGetWallclock();
208 void llGiveInventory(string destination, string inventory); 209 void llGiveInventory(string destination, string inventory);
209 void llGiveInventoryList(string destination, string category, LSL_List inventory); 210 void llGiveInventoryList(string destination, string category, LSL_List inventory);
210 LSL_Integer llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
212 LSL_String llTransferLindenDollars(string destination, int amount);
211 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
212 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
213 LSL_Vector llGroundContour(LSL_Vector offset); 215 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -330,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
330 void llSensorRemove(); 332 void llSensorRemove();
331 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate); 333 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate);
332 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
333 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
334 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
335 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -355,11 +358,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
355 void llSetParcelMusicURL(string url); 358 void llSetParcelMusicURL(string url);
356 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 359 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
357 void llSetPos(LSL_Vector pos); 360 void llSetPos(LSL_Vector pos);
361 LSL_Integer llSetRegionPos(LSL_Vector pos);
358 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 362 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
359 void llSetPrimitiveParams(LSL_List rules); 363 void llSetPrimitiveParams(LSL_List rules);
360 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 364 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
361 void llSetPrimURL(string url); 365 void llSetPrimURL(string url);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
363 void llSetRemoteScriptAccessPin(int pin); 366 void llSetRemoteScriptAccessPin(int pin);
364 void llSetRot(LSL_Rotation rot); 367 void llSetRot(LSL_Rotation rot);
365 void llSetScale(LSL_Vector scale); 368 void llSetScale(LSL_Vector scale);
@@ -379,6 +382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
379 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 382 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
380 void llSetVehicleType(int type); 383 void llSetVehicleType(int type);
381 void llSetVehicleVectorParam(int param, LSL_Vector vec); 384 void llSetVehicleVectorParam(int param, LSL_Vector vec);
385 void llSetVelocity(LSL_Vector velocity, int local);
382 void llShout(int channelID, string text); 386 void llShout(int channelID, string text);
383 LSL_Float llSin(double f); 387 LSL_Float llSin(double f);
384 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 388 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -422,9 +426,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
422 LSL_Vector llWind(LSL_Vector offset); 426 LSL_Vector llWind(LSL_Vector offset);
423 LSL_String llXorBase64Strings(string str1, string str2); 427 LSL_String llXorBase64Strings(string str1, string str2);
424 LSL_String llXorBase64StringsCorrect(string str1, string str2); 428 LSL_String llXorBase64StringsCorrect(string str1, string str2);
425 void print(string str); 429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
426 431
427 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); 432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
433 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
428 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 434 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
429 } 435 }
430} 436}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 93188c9..b1fbed5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -144,7 +144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
144 // Avatar Info Commands 144 // Avatar Info Commands
145 string osGetAgentIP(string agent); 145 string osGetAgentIP(string agent);
146 LSL_List osGetAgents(); 146 LSL_List osGetAgents();
147 147
148 // Teleport commands 148 // Teleport commands
149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 60a7e14..c788407 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -56,7 +56,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
56 public const int ACTIVE = 2; 56 public const int ACTIVE = 2;
57 public const int PASSIVE = 4; 57 public const int PASSIVE = 4;
58 public const int SCRIPTED = 8; 58 public const int SCRIPTED = 8;
59 public const int OS_NPC = 0x01000000;
60 59
61 public const int CONTROL_FWD = 1; 60 public const int CONTROL_FWD = 1;
62 public const int CONTROL_BACK = 2; 61 public const int CONTROL_BACK = 2;
@@ -95,6 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
95 public const int AGENT_CROUCHING = 1024; 94 public const int AGENT_CROUCHING = 1024;
96 public const int AGENT_BUSY = 2048; 95 public const int AGENT_BUSY = 2048;
97 public const int AGENT_ALWAYS_RUN = 4096; 96 public const int AGENT_ALWAYS_RUN = 4096;
97 public const int AGENT_MALE = 8192;
98 98
99 //Particle Systems 99 //Particle Systems
100 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 100 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -337,6 +337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
337 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 337 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
338 public const int CHANGED_MEDIA = 2048; 338 public const int CHANGED_MEDIA = 2048;
339 public const int CHANGED_ANIMATION = 16384; 339 public const int CHANGED_ANIMATION = 16384;
340 public const int CHANGED_POSITION = 32768;
340 public const int TYPE_INVALID = 0; 341 public const int TYPE_INVALID = 0;
341 public const int TYPE_INTEGER = 1; 342 public const int TYPE_INTEGER = 1;
342 public const int TYPE_FLOAT = 2; 343 public const int TYPE_FLOAT = 2;
@@ -642,6 +643,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
642 public const int PRIM_MEDIA_PERM_OWNER = 1; 643 public const int PRIM_MEDIA_PERM_OWNER = 1;
643 public const int PRIM_MEDIA_PERM_GROUP = 2; 644 public const int PRIM_MEDIA_PERM_GROUP = 2;
644 public const int PRIM_MEDIA_PERM_ANYONE = 4; 645 public const int PRIM_MEDIA_PERM_ANYONE = 4;
646
647 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
648 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
649 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
650 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
651
652 public const int PRIM_PHYSICS_MATERIAL = 31;
653 public const int DENSITY = 1;
654 public const int FRICTION = 2;
655 public const int RESTITUTION = 4;
656 public const int GRAVITY_MULTIPLIER = 8;
645 657
646 // extra constants for llSetPrimMediaParams 658 // extra constants for llSetPrimMediaParams
647 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 659 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -714,6 +726,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
714 726
715 public static readonly LSLInteger RCERR_UNKNOWN = -1; 727 public static readonly LSLInteger RCERR_UNKNOWN = -1;
716 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 728 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
717 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 729 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
730
731 public const int KFM_MODE = 1;
732 public const int KFM_LOOP = 1;
733 public const int KFM_REVERSE = 3;
734 public const int KFM_FORWARD = 0;
735 public const int KFM_PING_PONG = 2;
736 public const int KFM_DATA = 2;
737 public const int KFM_TRANSLATION = 2;
738 public const int KFM_ROTATION = 1;
739 public const int KFM_COMMAND = 0;
740 public const int KFM_CMD_PLAY = 0;
741 public const int KFM_CMD_STOP = 1;
742 public const int KFM_CMD_PAUSE = 2;
718 } 743 }
719} 744}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index c457880..89b6eff 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -314,6 +315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 315 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 316 }
316 317
318 [DebuggerNonUserCode]
317 public void llDie() 319 public void llDie()
318 { 320 {
319 m_LSL_Functions.llDie(); 321 m_LSL_Functions.llDie();
@@ -474,6 +476,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
474 return m_LSL_Functions.llGetFreeMemory(); 476 return m_LSL_Functions.llGetFreeMemory();
475 } 477 }
476 478
479 public LSL_Integer llGetUsedMemory()
480 {
481 return m_LSL_Functions.llGetUsedMemory();
482 }
483
477 public LSL_Integer llGetFreeURLs() 484 public LSL_Integer llGetFreeURLs()
478 { 485 {
479 return m_LSL_Functions.llGetFreeURLs(); 486 return m_LSL_Functions.llGetFreeURLs();
@@ -579,6 +586,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
579 return m_LSL_Functions.llGetMass(); 586 return m_LSL_Functions.llGetMass();
580 } 587 }
581 588
589 public LSL_Float llGetMassMKS()
590 {
591 return m_LSL_Functions.llGetMassMKS();
592 }
593
582 public LSL_Integer llGetMemoryLimit() 594 public LSL_Integer llGetMemoryLimit()
583 { 595 {
584 return m_LSL_Functions.llGetMemoryLimit(); 596 return m_LSL_Functions.llGetMemoryLimit();
@@ -844,11 +856,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
844 return m_LSL_Functions.llGetUnixTime(); 856 return m_LSL_Functions.llGetUnixTime();
845 } 857 }
846 858
847 public LSL_Integer llGetUsedMemory()
848 {
849 return m_LSL_Functions.llGetUsedMemory();
850 }
851
852 public LSL_Vector llGetVel() 859 public LSL_Vector llGetVel()
853 { 860 {
854 return m_LSL_Functions.llGetVel(); 861 return m_LSL_Functions.llGetVel();
@@ -874,6 +881,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
874 return m_LSL_Functions.llGiveMoney(destination, amount); 881 return m_LSL_Functions.llGiveMoney(destination, amount);
875 } 882 }
876 883
884 public LSL_String llTransferLindenDollars(string destination, int amount)
885 {
886 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
887 }
888
877 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 889 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
878 { 890 {
879 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 891 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1483,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1483 m_LSL_Functions.llSetAlpha(alpha, face); 1495 m_LSL_Functions.llSetAlpha(alpha, face);
1484 } 1496 }
1485 1497
1498 public void llSetAngularVelocity(LSL_Vector angvelocity, int local)
1499 {
1500 m_LSL_Functions.llSetAngularVelocity(angvelocity, local);
1501 }
1502
1486 public void llSetBuoyancy(double buoyancy) 1503 public void llSetBuoyancy(double buoyancy)
1487 { 1504 {
1488 m_LSL_Functions.llSetBuoyancy(buoyancy); 1505 m_LSL_Functions.llSetBuoyancy(buoyancy);
@@ -1603,6 +1620,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1603 m_LSL_Functions.llSetPos(pos); 1620 m_LSL_Functions.llSetPos(pos);
1604 } 1621 }
1605 1622
1623 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1624 {
1625 return m_LSL_Functions.llSetRegionPos(pos);
1626 }
1627
1606 public void llSetPrimitiveParams(LSL_List rules) 1628 public void llSetPrimitiveParams(LSL_List rules)
1607 { 1629 {
1608 m_LSL_Functions.llSetPrimitiveParams(rules); 1630 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1618,11 +1640,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1618 m_LSL_Functions.llSetPrimURL(url); 1640 m_LSL_Functions.llSetPrimURL(url);
1619 } 1641 }
1620 1642
1621 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1622 {
1623 return m_LSL_Functions.llSetRegionPos(pos);
1624 }
1625
1626 public void llSetRemoteScriptAccessPin(int pin) 1643 public void llSetRemoteScriptAccessPin(int pin)
1627 { 1644 {
1628 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1645 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1718,6 +1735,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1718 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1735 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1719 } 1736 }
1720 1737
1738 public void llSetVelocity(LSL_Vector velocity, int local)
1739 {
1740 m_LSL_Functions.llSetVelocity(velocity, local);
1741 }
1742
1721 public void llShout(int channelID, string text) 1743 public void llShout(int channelID, string text)
1722 { 1744 {
1723 m_LSL_Functions.llShout(channelID, text); 1745 m_LSL_Functions.llShout(channelID, text);
@@ -1968,9 +1990,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1968 return m_LSL_Functions.llClearLinkMedia(link, face); 1990 return m_LSL_Functions.llClearLinkMedia(link, face);
1969 } 1991 }
1970 1992
1971 public void print(string str) 1993 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1994 {
1995 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1996 }
1997
1998 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1999 {
2000 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2001 }
2002
2003 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1972 { 2004 {
1973 m_LSL_Functions.print(str); 2005 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1974 } 2006 }
1975 } 2007 }
1976} 2008}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 5a58f73..22804f5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
39 40
40namespace OpenSim.Region.ScriptEngine.Shared 41namespace OpenSim.Region.ScriptEngine.Shared
@@ -102,6 +103,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
102 Type = 0; 103 Type = 0;
103 Velocity = new LSL_Types.Vector3(); 104 Velocity = new LSL_Types.Vector3();
104 initializeSurfaceTouch(); 105 initializeSurfaceTouch();
106 Country = String.Empty;
105 } 107 }
106 108
107 public UUID Key; 109 public UUID Key;
@@ -133,6 +135,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
133 private int touchFace; 135 private int touchFace;
134 public int TouchFace { get { return touchFace; } } 136 public int TouchFace { get { return touchFace; } }
135 137
138 public string Country;
139
136 // This can be done in two places including the constructor 140 // This can be done in two places including the constructor
137 // so be carefull what gets added here 141 // so be carefull what gets added here
138 private void initializeSurfaceTouch() 142 private void initializeSurfaceTouch()
@@ -180,6 +184,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
180 return; 184 return;
181 185
182 Name = presence.Firstname + " " + presence.Lastname; 186 Name = presence.Firstname + " " + presence.Lastname;
187 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
188 if (account != null)
189 Country = account.UserCountry;
190
183 Owner = Key; 191 Owner = Key;
184 Position = new LSL_Types.Vector3(presence.AbsolutePosition); 192 Position = new LSL_Types.Vector3(presence.AbsolutePosition);
185 Rotation = new LSL_Types.Quaternion( 193 Rotation = new LSL_Types.Quaternion(
@@ -189,22 +197,27 @@ namespace OpenSim.Region.ScriptEngine.Shared
189 presence.Rotation.W); 197 presence.Rotation.W);
190 Velocity = new LSL_Types.Vector3(presence.Velocity); 198 Velocity = new LSL_Types.Vector3(presence.Velocity);
191 199
192 if (presence.PresenceType != PresenceType.Npc) 200 Type = 0x01; // Avatar
193 { 201 if (presence.PresenceType == PresenceType.Npc)
194 Type = AGENT; 202 Type = 0x20;
195 } 203
196 else 204 // Cope Impl. We don't use OS_NPC.
197 { 205 //if (presence.PresenceType != PresenceType.Npc)
198 Type = OS_NPC; 206 //{
199 207 // Type = AGENT;
200 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 208 //}
201 INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); 209 //else
202 210 //{
203 if (npcData.SenseAsAgent) 211 // Type = OS_NPC;
204 { 212
205 Type |= AGENT; 213 // INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
206 } 214 // INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
207 } 215
216 // if (npcData.SenseAsAgent)
217 // {
218 // Type |= AGENT;
219 // }
220 //}
208 221
209 if (presence.Velocity != Vector3.Zero) 222 if (presence.Velocity != Vector3.Zero)
210 Type |= ACTIVE; 223 Type |= ACTIVE;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 5793cc9..771db0c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Reflection; 34using System.Reflection;
34using System.Runtime.Remoting; 35using System.Runtime.Remoting;
35using System.Runtime.Remoting.Lifetime; 36using System.Runtime.Remoting.Lifetime;
@@ -219,13 +220,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
219 220
220 if (part != null) 221 if (part != null)
221 { 222 {
222 lock (part.TaskInventory) 223 part.TaskInventory.LockItemsForRead(true);
224 if (part.TaskInventory.ContainsKey(ItemID))
223 { 225 {
224 if (part.TaskInventory.ContainsKey(ItemID)) 226 ScriptTask = part.TaskInventory[ItemID];
225 {
226 ScriptTask = part.TaskInventory[ItemID];
227 }
228 } 227 }
228 part.TaskInventory.LockItemsForRead(false);
229 } 229 }
230 230
231 ApiManager am = new ApiManager(); 231 ApiManager am = new ApiManager();
@@ -417,14 +417,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
417 { 417 {
418 int permsMask; 418 int permsMask;
419 UUID permsGranter; 419 UUID permsGranter;
420 lock (part.TaskInventory) 420 part.TaskInventory.LockItemsForRead(true);
421 if (!part.TaskInventory.ContainsKey(ItemID))
421 { 422 {
422 if (!part.TaskInventory.ContainsKey(ItemID)) 423 part.TaskInventory.LockItemsForRead(false);
423 return; 424 return;
424
425 permsGranter = part.TaskInventory[ItemID].PermsGranter;
426 permsMask = part.TaskInventory[ItemID].PermsMask;
427 } 425 }
426 permsGranter = part.TaskInventory[ItemID].PermsGranter;
427 permsMask = part.TaskInventory[ItemID].PermsMask;
428 part.TaskInventory.LockItemsForRead(false);
428 429
429 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 430 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
430 { 431 {
@@ -552,6 +553,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
552 return true; 553 return true;
553 } 554 }
554 555
556 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
555 public void SetState(string state) 557 public void SetState(string state)
556 { 558 {
557 if (state == State) 559 if (state == State)
@@ -563,7 +565,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
563 new DetectParams[0])); 565 new DetectParams[0]));
564 PostEvent(new EventParams("state_entry", new Object[0], 566 PostEvent(new EventParams("state_entry", new Object[0],
565 new DetectParams[0])); 567 new DetectParams[0]));
566 568
567 throw new EventAbortException(); 569 throw new EventAbortException();
568 } 570 }
569 571
@@ -653,45 +655,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
653 /// <returns></returns> 655 /// <returns></returns>
654 public object EventProcessor() 656 public object EventProcessor()
655 { 657 {
658 EventParams data = null;
656 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 659 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
657 if (!Running) 660 if (!Running)
658 return 0; 661 return 0;
659 662
660 lock (m_Script)
661 {
662// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 663// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
663 664
664 if (Suspended) 665 if (Suspended)
665 return 0; 666 return 0;
666
667 EventParams data = null;
668 667
669 lock (EventQueue) 668 lock (EventQueue)
669 {
670 data = (EventParams) EventQueue.Dequeue();
671 if (data == null) // Shouldn't happen
670 { 672 {
671 data = (EventParams)EventQueue.Dequeue(); 673 if (EventQueue.Count > 0 && Running && !ShuttingDown)
672 if (data == null) // Shouldn't happen
673 { 674 {
674 if (EventQueue.Count > 0 && Running && !ShuttingDown) 675 m_CurrentWorkItem = Engine.QueueEventHandler(this);
675 {
676 m_CurrentWorkItem = Engine.QueueEventHandler(this);
677 }
678 else
679 {
680 m_CurrentWorkItem = null;
681 }
682 return 0;
683 } 676 }
684 677 else
685 if (data.EventName == "timer")
686 m_TimerQueued = false;
687 if (data.EventName == "control")
688 { 678 {
689 if (m_ControlEventsInQueue > 0) 679 m_CurrentWorkItem = null;
690 m_ControlEventsInQueue--;
691 } 680 }
692 if (data.EventName == "collision") 681 return 0;
693 m_CollisionInQueue = false;
694 } 682 }
683
684 if (data.EventName == "timer")
685 m_TimerQueued = false;
686 if (data.EventName == "control")
687 {
688 if (m_ControlEventsInQueue > 0)
689 m_ControlEventsInQueue--;
690 }
691 if (data.EventName == "collision")
692 m_CollisionInQueue = false;
693 }
694
695 lock(m_Script)
696 {
695 697
696// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 698// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
697 699
@@ -846,6 +848,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
846 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 848 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
847 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 849 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
848 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 850 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
851 part.CollisionSound = UUID.Zero;
849 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 852 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
850 EventQueue.Clear(); 853 EventQueue.Clear();
851 m_Script.ResetVars(); 854 m_Script.ResetVars();
@@ -860,6 +863,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
860 new Object[0], new DetectParams[0])); 863 new Object[0], new DetectParams[0]));
861 } 864 }
862 865
866 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
863 public void ApiResetScript() 867 public void ApiResetScript()
864 { 868 {
865 // bool running = Running; 869 // bool running = Running;
@@ -871,6 +875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
871 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 875 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
872 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 876 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
873 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 877 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
878 part.CollisionSound = UUID.Zero;
874 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 879 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
875 880
876 EventQueue.Clear(); 881 EventQueue.Clear();
@@ -891,10 +896,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
891 896
892 public Dictionary<string, object> GetVars() 897 public Dictionary<string, object> GetVars()
893 { 898 {
894 if (m_Script != null) 899 return m_Script.GetVars();
895 return m_Script.GetVars();
896 else
897 return new Dictionary<string, object>();
898 } 900 }
899 901
900 public void SetVars(Dictionary<string, object> vars) 902 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index fcb98a5..c9c4753 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -102,19 +102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
102 102
103 public override string ToString() 103 public override string ToString()
104 { 104 {
105 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 105 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
106 return s; 106 return s;
107 } 107 }
108 108
109 public static explicit operator LSLString(Vector3 vec) 109 public static explicit operator LSLString(Vector3 vec)
110 { 110 {
111 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 111 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
112 return new LSLString(s); 112 return new LSLString(s);
113 } 113 }
114 114
115 public static explicit operator string(Vector3 vec) 115 public static explicit operator string(Vector3 vec)
116 { 116 {
117 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 117 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
118 return s; 118 return s;
119 } 119 }
120 120
@@ -389,19 +389,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
389 389
390 public override string ToString() 390 public override string ToString()
391 { 391 {
392 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 392 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
393 return st; 393 return st;
394 } 394 }
395 395
396 public static explicit operator string(Quaternion r) 396 public static explicit operator string(Quaternion r)
397 { 397 {
398 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 398 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
399 return s; 399 return s;
400 } 400 }
401 401
402 public static explicit operator LSLString(Quaternion r) 402 public static explicit operator LSLString(Quaternion r)
403 { 403 {
404 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 404 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
405 return new LSLString(s); 405 return new LSLString(s);
406 } 406 }
407 407
@@ -521,6 +521,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
521 size += 64; 521 size += 64;
522 else if (o is int) 522 else if (o is int)
523 size += 4; 523 size += 4;
524 else if (o is uint)
525 size += 4;
524 else if (o is string) 526 else if (o is string)
525 size += ((string)o).Length; 527 size += ((string)o).Length;
526 else if (o is float) 528 else if (o is float)
@@ -686,24 +688,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
686 688
687 public static bool operator ==(list a, list b) 689 public static bool operator ==(list a, list b)
688 { 690 {
689 int la = -1; 691 int la = a.Length;
690 int lb = -1; 692 int lb = b.Length;
691 try { la = a.Length; }
692 catch (NullReferenceException) { }
693 try { lb = b.Length; }
694 catch (NullReferenceException) { }
695 693
696 return la == lb; 694 return la == lb;
697 } 695 }
698 696
699 public static bool operator !=(list a, list b) 697 public static bool operator !=(list a, list b)
700 { 698 {
701 int la = -1; 699 int la = a.Length;
702 int lb = -1; 700 int lb = b.Length;
703 try { la = a.Length; }
704 catch (NullReferenceException) { }
705 try {lb = b.Length;}
706 catch (NullReferenceException) { }
707 701
708 return la != lb; 702 return la != lb;
709 } 703 }
@@ -937,7 +931,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
937 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 931 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
938 } 932 }
939 933
940 if (ascending == 0) 934 if (ascending != 1)
941 { 935 {
942 ret = 0 - ret; 936 ret = 0 - ret;
943 } 937 }
@@ -970,6 +964,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
970 stride = 1; 964 stride = 1;
971 } 965 }
972 966
967 if ((Data.Length % stride) != 0)
968 return new list(ret);
969
973 // we can optimize here in the case where stride == 1 and the list 970 // we can optimize here in the case where stride == 1 and the list
974 // consists of homogeneous types 971 // consists of homogeneous types
975 972
@@ -989,7 +986,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
989 if (homogeneous) 986 if (homogeneous)
990 { 987 {
991 Array.Sort(ret, new HomogeneousComparer()); 988 Array.Sort(ret, new HomogeneousComparer());
992 if (ascending == 0) 989 if (ascending != 1)
993 { 990 {
994 Array.Reverse(ret); 991 Array.Reverse(ret);
995 } 992 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 0460f22..9f05666 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Globalization; 32using System.Globalization;
32using System.IO; 33using System.IO;
33using System.Reflection; 34using System.Reflection;
@@ -128,6 +129,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
128 private Dictionary<UUID, IScriptInstance> m_Scripts = 129 private Dictionary<UUID, IScriptInstance> m_Scripts =
129 new Dictionary<UUID, IScriptInstance>(); 130 new Dictionary<UUID, IScriptInstance>();
130 131
132 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
133
131 // Maps the asset ID to the assembly 134 // Maps the asset ID to the assembly
132 135
133 private Dictionary<UUID, string> m_Assemblies = 136 private Dictionary<UUID, string> m_Assemblies =
@@ -150,6 +153,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
150 IWorkItemResult m_CurrentCompile = null; 153 IWorkItemResult m_CurrentCompile = null;
151 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 154 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
152 155
156 private void lockScriptsForRead(bool locked)
157 {
158 if (locked)
159 {
160 if (m_scriptsLock.RecursiveReadCount > 0)
161 {
162 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
163 m_scriptsLock.ExitReadLock();
164 }
165 if (m_scriptsLock.RecursiveWriteCount > 0)
166 {
167 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
168 m_scriptsLock.ExitWriteLock();
169 }
170
171 while (!m_scriptsLock.TryEnterReadLock(60000))
172 {
173 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
174 if (m_scriptsLock.IsWriteLockHeld)
175 {
176 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
177 }
178 }
179 }
180 else
181 {
182 if (m_scriptsLock.RecursiveReadCount > 0)
183 {
184 m_scriptsLock.ExitReadLock();
185 }
186 }
187 }
188 private void lockScriptsForWrite(bool locked)
189 {
190 if (locked)
191 {
192 if (m_scriptsLock.RecursiveReadCount > 0)
193 {
194 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
195 m_scriptsLock.ExitReadLock();
196 }
197 if (m_scriptsLock.RecursiveWriteCount > 0)
198 {
199 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
200 m_scriptsLock.ExitWriteLock();
201 }
202
203 while (!m_scriptsLock.TryEnterWriteLock(60000))
204 {
205 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
206 if (m_scriptsLock.IsWriteLockHeld)
207 {
208 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
209 }
210 }
211 }
212 else
213 {
214 if (m_scriptsLock.RecursiveWriteCount > 0)
215 {
216 m_scriptsLock.ExitWriteLock();
217 }
218 }
219 }
220
153 public string ScriptEngineName 221 public string ScriptEngineName
154 { 222 {
155 get { return "XEngine"; } 223 get { return "XEngine"; }
@@ -576,64 +644,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine
576 { 644 {
577 if (!m_Enabled) 645 if (!m_Enabled)
578 return; 646 return;
647 lockScriptsForRead(true);
579 648
580 lock (m_Scripts) 649 List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values);
581 {
582 m_log.InfoFormat(
583 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName);
584 650
585 foreach (IScriptInstance instance in m_Scripts.Values) 651// foreach (IScriptInstance instance in m_Scripts.Values)
652 foreach (IScriptInstance instance in instancesToDel)
653 {
654 // Force a final state save
655 //
656 if (m_Assemblies.ContainsKey(instance.AssetID))
586 { 657 {
587 // Force a final state save 658 string assembly = m_Assemblies[instance.AssetID];
588 //
589 if (m_Assemblies.ContainsKey(instance.AssetID))
590 {
591 string assembly = m_Assemblies[instance.AssetID];
592 659
593 try 660 try
594 { 661 {
595 instance.SaveState(assembly); 662 instance.SaveState(assembly);
596 }
597 catch (Exception e)
598 {
599 m_log.Error(
600 string.Format(
601 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
602 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
603 , e);
604 }
605 } 663 }
664 catch (Exception e)
665 {
666 m_log.Error(
667 string.Format(
668 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
669 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
670 , e);
671 }
672 }
606 673
607 // Clear the event queue and abort the instance thread 674 // Clear the event queue and abort the instance thread
608 // 675 //
609 instance.ClearQueue(); 676 instance.ClearQueue();
610 instance.Stop(0); 677 instance.Stop(0);
611 678
612 // Release events, timer, etc 679 // Release events, timer, etc
613 // 680 //
614 instance.DestroyScriptInstance(); 681 instance.DestroyScriptInstance();
615 682
616 // Unload scripts and app domains. 683 // Unload scripts and app domains
617 // Must be done explicitly because they have infinite 684 // Must be done explicitly because they have infinite
618 // lifetime. 685 // lifetime
619 // However, don't bother to do this if the simulator is shutting 686 //
620 // down since it takes a long time with many scripts. 687// if (!m_SimulatorShuttingDown)
621 if (!m_SimulatorShuttingDown) 688 {
689 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
690 if (m_DomainScripts[instance.AppDomain].Count == 0)
622 { 691 {
623 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 692 m_DomainScripts.Remove(instance.AppDomain);
624 if (m_DomainScripts[instance.AppDomain].Count == 0) 693 UnloadAppDomain(instance.AppDomain);
625 {
626 m_DomainScripts.Remove(instance.AppDomain);
627 UnloadAppDomain(instance.AppDomain);
628 }
629 } 694 }
630 } 695 }
631 696
632 m_Scripts.Clear(); 697// m_Scripts.Clear();
633 m_PrimObjects.Clear(); 698// m_PrimObjects.Clear();
634 m_Assemblies.Clear(); 699// m_Assemblies.Clear();
635 m_DomainScripts.Clear(); 700// m_DomainScripts.Clear();
636 } 701 }
702 lockScriptsForRead(false);
703 lockScriptsForWrite(true);
704 m_Scripts.Clear();
705 lockScriptsForWrite(false);
706 m_PrimObjects.Clear();
707 m_Assemblies.Clear();
708 m_DomainScripts.Clear();
709
637 lock (m_ScriptEngines) 710 lock (m_ScriptEngines)
638 { 711 {
639 m_ScriptEngines.Remove(this); 712 m_ScriptEngines.Remove(this);
@@ -702,22 +775,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
702 775
703 List<IScriptInstance> instances = new List<IScriptInstance>(); 776 List<IScriptInstance> instances = new List<IScriptInstance>();
704 777
705 lock (m_Scripts) 778 lockScriptsForRead(true);
706 { 779 foreach (IScriptInstance instance in m_Scripts.Values)
707 foreach (IScriptInstance instance in m_Scripts.Values)
708 instances.Add(instance); 780 instances.Add(instance);
709 } 781 lockScriptsForRead(false);
710 782
711 foreach (IScriptInstance i in instances) 783 foreach (IScriptInstance i in instances)
712 { 784 {
713 string assembly = String.Empty; 785 string assembly = String.Empty;
714 786
715 lock (m_Scripts) 787
716 {
717 if (!m_Assemblies.ContainsKey(i.AssetID)) 788 if (!m_Assemblies.ContainsKey(i.AssetID))
718 continue; 789 continue;
719 assembly = m_Assemblies[i.AssetID]; 790 assembly = m_Assemblies[i.AssetID];
720 } 791
721 792
722 try 793 try
723 { 794 {
@@ -1119,96 +1190,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1119 } 1190 }
1120 1191
1121 ScriptInstance instance = null; 1192 ScriptInstance instance = null;
1122 lock (m_Scripts) 1193 // Create the object record
1194 lockScriptsForRead(true);
1195 if ((!m_Scripts.ContainsKey(itemID)) ||
1196 (m_Scripts[itemID].AssetID != assetID))
1123 { 1197 {
1124 // Create the object record 1198 lockScriptsForRead(false);
1125 if ((!m_Scripts.ContainsKey(itemID)) ||
1126 (m_Scripts[itemID].AssetID != assetID))
1127 {
1128 UUID appDomain = assetID;
1129 1199
1130 if (part.ParentGroup.IsAttachment) 1200 UUID appDomain = assetID;
1131 appDomain = part.ParentGroup.RootPart.UUID;
1132 1201
1133 if (!m_AppDomains.ContainsKey(appDomain)) 1202 if (part.ParentGroup.IsAttachment)
1134 { 1203 appDomain = part.ParentGroup.RootPart.UUID;
1135 try
1136 {
1137 AppDomainSetup appSetup = new AppDomainSetup();
1138 appSetup.PrivateBinPath = Path.Combine(
1139 m_ScriptEnginesPath,
1140 m_Scene.RegionInfo.RegionID.ToString());
1141 1204
1142 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1205 if (!m_AppDomains.ContainsKey(appDomain))
1143 Evidence evidence = new Evidence(baseEvidence); 1206 {
1207 try
1208 {
1209 AppDomainSetup appSetup = new AppDomainSetup();
1210 appSetup.PrivateBinPath = Path.Combine(
1211 m_ScriptEnginesPath,
1212 m_Scene.RegionInfo.RegionID.ToString());
1144 1213
1145 AppDomain sandbox; 1214 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1146 if (m_AppDomainLoading) 1215 Evidence evidence = new Evidence(baseEvidence);
1147 {
1148 sandbox = AppDomain.CreateDomain(
1149 m_Scene.RegionInfo.RegionID.ToString(),
1150 evidence, appSetup);
1151 sandbox.AssemblyResolve +=
1152 new ResolveEventHandler(
1153 AssemblyResolver.OnAssemblyResolve);
1154 }
1155 else
1156 {
1157 sandbox = AppDomain.CurrentDomain;
1158 }
1159
1160 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1161 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1162 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1163 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1164 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1165 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1166 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1167
1168 m_AppDomains[appDomain] = sandbox;
1169 1216
1170 m_DomainScripts[appDomain] = new List<UUID>(); 1217 AppDomain sandbox;
1218 if (m_AppDomainLoading)
1219 {
1220 sandbox = AppDomain.CreateDomain(
1221 m_Scene.RegionInfo.RegionID.ToString(),
1222 evidence, appSetup);
1223 m_AppDomains[appDomain].AssemblyResolve +=
1224 new ResolveEventHandler(
1225 AssemblyResolver.OnAssemblyResolve);
1171 } 1226 }
1172 catch (Exception e) 1227 else
1173 { 1228 {
1174 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1229 sandbox = AppDomain.CurrentDomain;
1175 m_ScriptErrorMessage += "Exception creating app domain:\n";
1176 m_ScriptFailCount++;
1177 lock (m_AddingAssemblies)
1178 {
1179 m_AddingAssemblies[assembly]--;
1180 }
1181 return false;
1182 } 1230 }
1183 }
1184 m_DomainScripts[appDomain].Add(itemID);
1185
1186 instance = new ScriptInstance(this, part,
1187 itemID, assetID, assembly,
1188 m_AppDomains[appDomain],
1189 part.ParentGroup.RootPart.Name,
1190 item.Name, startParam, postOnRez,
1191 stateSource, m_MaxScriptQueue);
1192
1193// if (DebugLevel >= 1)
1194// m_log.DebugFormat(
1195// "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1196// part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1197// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1198 1231
1199 if (presence != null) 1232 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1233 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1234 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1235 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1236 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1237 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1238 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1239
1240 m_AppDomains[appDomain] = sandbox;
1241
1242 m_DomainScripts[appDomain] = new List<UUID>();
1243 }
1244 catch (Exception e)
1200 { 1245 {
1201 ShowScriptSaveResponse(item.OwnerID, 1246 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1202 assetID, "Compile successful", true); 1247 m_ScriptErrorMessage += "Exception creating app domain:\n";
1248 m_ScriptFailCount++;
1249 lock (m_AddingAssemblies)
1250 {
1251 m_AddingAssemblies[assembly]--;
1252 }
1253 return false;
1203 } 1254 }
1255 }
1256 m_DomainScripts[appDomain].Add(itemID);
1257
1258 instance = new ScriptInstance(this, part,
1259 itemID, assetID, assembly,
1260 m_AppDomains[appDomain],
1261 part.ParentGroup.RootPart.Name,
1262 item.Name, startParam, postOnRez,
1263 stateSource, m_MaxScriptQueue);
1264
1265// m_log.DebugFormat(
1266// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1267// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1268// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1204 1269
1205 instance.AppDomain = appDomain; 1270 if (presence != null)
1206 instance.LineMap = linemap; 1271 {
1207 1272 ShowScriptSaveResponse(item.OwnerID,
1208 m_Scripts[itemID] = instance; 1273 assetID, "Compile successful", true);
1209 } 1274 }
1210 }
1211 1275
1276 instance.AppDomain = appDomain;
1277 instance.LineMap = linemap;
1278 lockScriptsForWrite(true);
1279 m_Scripts[itemID] = instance;
1280 lockScriptsForWrite(false);
1281 }
1282 else
1283 {
1284 lockScriptsForRead(false);
1285 }
1212 lock (m_PrimObjects) 1286 lock (m_PrimObjects)
1213 { 1287 {
1214 if (!m_PrimObjects.ContainsKey(localID)) 1288 if (!m_PrimObjects.ContainsKey(localID))
@@ -1226,7 +1300,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1226 m_AddingAssemblies[assembly]--; 1300 m_AddingAssemblies[assembly]--;
1227 } 1301 }
1228 1302
1229 if (instance != null) 1303 if (instance!=null)
1230 instance.Init(); 1304 instance.Init();
1231 1305
1232 bool runIt; 1306 bool runIt;
@@ -1249,18 +1323,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1249 m_CompileDict.Remove(itemID); 1323 m_CompileDict.Remove(itemID);
1250 } 1324 }
1251 1325
1252 IScriptInstance instance = null; 1326 lockScriptsForRead(true);
1253 1327 // Do we even have it?
1254 lock (m_Scripts) 1328 if (!m_Scripts.ContainsKey(itemID))
1255 { 1329 {
1256 // Do we even have it? 1330 // Do we even have it?
1257 if (!m_Scripts.ContainsKey(itemID)) 1331 if (!m_Scripts.ContainsKey(itemID))
1258 return; 1332 return;
1259 1333
1260 instance = m_Scripts[itemID]; 1334 lockScriptsForRead(false);
1335 lockScriptsForWrite(true);
1261 m_Scripts.Remove(itemID); 1336 m_Scripts.Remove(itemID);
1337 lockScriptsForWrite(false);
1338
1339 return;
1262 } 1340 }
1341
1263 1342
1343 IScriptInstance instance=m_Scripts[itemID];
1344 lockScriptsForRead(false);
1345 lockScriptsForWrite(true);
1346 m_Scripts.Remove(itemID);
1347 lockScriptsForWrite(false);
1264 instance.ClearQueue(); 1348 instance.ClearQueue();
1265 1349
1266 // Give the script some time to finish processing its last event. Simply aborting the script thread can 1350 // Give the script some time to finish processing its last event. Simply aborting the script thread can
@@ -1299,8 +1383,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1299 1383
1300 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1384 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1301 if (handlerObjectRemoved != null) 1385 if (handlerObjectRemoved != null)
1302 handlerObjectRemoved(instance.ObjectID); 1386 {
1387 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1388 handlerObjectRemoved(part.UUID);
1389 }
1303 1390
1391 CleanAssemblies();
1392
1304 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1393 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1305 if (handlerScriptRemoved != null) 1394 if (handlerScriptRemoved != null)
1306 handlerScriptRemoved(itemID); 1395 handlerScriptRemoved(itemID);
@@ -1561,12 +1650,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1561 private IScriptInstance GetInstance(UUID itemID) 1650 private IScriptInstance GetInstance(UUID itemID)
1562 { 1651 {
1563 IScriptInstance instance; 1652 IScriptInstance instance;
1564 lock (m_Scripts) 1653 lockScriptsForRead(true);
1654 if (!m_Scripts.ContainsKey(itemID))
1565 { 1655 {
1566 if (!m_Scripts.ContainsKey(itemID)) 1656 lockScriptsForRead(false);
1567 return null; 1657 return null;
1568 instance = m_Scripts[itemID];
1569 } 1658 }
1659 instance = m_Scripts[itemID];
1660 lockScriptsForRead(false);
1570 return instance; 1661 return instance;
1571 } 1662 }
1572 1663
@@ -1590,6 +1681,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1590 return false; 1681 return false;
1591 } 1682 }
1592 1683
1684 [DebuggerNonUserCode]
1593 public void ApiResetScript(UUID itemID) 1685 public void ApiResetScript(UUID itemID)
1594 { 1686 {
1595 IScriptInstance instance = GetInstance(itemID); 1687 IScriptInstance instance = GetInstance(itemID);
@@ -1651,6 +1743,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1651 return UUID.Zero; 1743 return UUID.Zero;
1652 } 1744 }
1653 1745
1746 [DebuggerNonUserCode]
1654 public void SetState(UUID itemID, string newState) 1747 public void SetState(UUID itemID, string newState)
1655 { 1748 {
1656 IScriptInstance instance = GetInstance(itemID); 1749 IScriptInstance instance = GetInstance(itemID);
@@ -1673,11 +1766,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1673 1766
1674 List<IScriptInstance> instances = new List<IScriptInstance>(); 1767 List<IScriptInstance> instances = new List<IScriptInstance>();
1675 1768
1676 lock (m_Scripts) 1769 lockScriptsForRead(true);
1677 { 1770 foreach (IScriptInstance instance in m_Scripts.Values)
1678 foreach (IScriptInstance instance in m_Scripts.Values)
1679 instances.Add(instance); 1771 instances.Add(instance);
1680 } 1772 lockScriptsForRead(false);
1681 1773
1682 foreach (IScriptInstance i in instances) 1774 foreach (IScriptInstance i in instances)
1683 { 1775 {