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.cs3195
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs113
-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, 3238 insertions, 1041 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 fa57845..9011966 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 {
@@ -3443,15 +3762,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3443 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3762 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3444 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3763 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3445 } 3764 }
3765 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3766 {
3767 implicitPerms = perm;
3768 }
3446 } 3769 }
3447 3770
3448 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3771 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3449 { 3772 {
3450 lock (m_host.TaskInventory) 3773 m_host.TaskInventory.LockItemsForWrite(true);
3451 { 3774 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3452 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3775 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3453 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3776 m_host.TaskInventory.LockItemsForWrite(false);
3454 }
3455 3777
3456 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3778 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3457 "run_time_permissions", new Object[] { 3779 "run_time_permissions", new Object[] {
@@ -3494,11 +3816,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3494 3816
3495 if (!m_waitingForScriptAnswer) 3817 if (!m_waitingForScriptAnswer)
3496 { 3818 {
3497 lock (m_host.TaskInventory) 3819 m_host.TaskInventory.LockItemsForWrite(true);
3498 { 3820 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3499 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3821 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3500 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3822 m_host.TaskInventory.LockItemsForWrite(false);
3501 }
3502 3823
3503 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3824 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3504 m_waitingForScriptAnswer=true; 3825 m_waitingForScriptAnswer=true;
@@ -3527,14 +3848,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3527 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3848 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3528 llReleaseControls(); 3849 llReleaseControls();
3529 3850
3530 lock (m_host.TaskInventory) 3851 m_host.TaskInventory.LockItemsForWrite(true);
3531 { 3852 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3532 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3853 m_host.TaskInventory.LockItemsForWrite(false);
3533 } 3854
3534 3855 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3535 m_ScriptEngine.PostScriptEvent( 3856 "run_time_permissions", new Object[] {
3536 m_item.ItemID, 3857 new LSL_Integer(answer) },
3537 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3858 new DetectParams[0]));
3538 } 3859 }
3539 3860
3540 public LSL_String llGetPermissionsKey() 3861 public LSL_String llGetPermissionsKey()
@@ -3573,14 +3894,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3573 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3894 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3574 { 3895 {
3575 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3896 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3576 3897 if (parts.Count > 0)
3577 foreach (SceneObjectPart part in parts) 3898 {
3578 part.SetFaceColorAlpha(face, color, null); 3899 try
3900 {
3901 foreach (SceneObjectPart part in parts)
3902 part.SetFaceColorAlpha(face, color, null);
3903 }
3904 finally
3905 {
3906 }
3907 }
3579 } 3908 }
3580 3909
3581 public void llCreateLink(string target, int parent) 3910 public void llCreateLink(string target, int parent)
3582 { 3911 {
3583 m_host.AddScriptLPS(1); 3912 m_host.AddScriptLPS(1);
3913
3584 UUID targetID; 3914 UUID targetID;
3585 3915
3586 if (!UUID.TryParse(target, out targetID)) 3916 if (!UUID.TryParse(target, out targetID))
@@ -3686,10 +4016,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3686 // Restructuring Multiple Prims. 4016 // Restructuring Multiple Prims.
3687 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4017 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3688 parts.Remove(parentPrim.RootPart); 4018 parts.Remove(parentPrim.RootPart);
3689 foreach (SceneObjectPart part in parts) 4019 if (parts.Count > 0)
3690 { 4020 {
3691 parentPrim.DelinkFromGroup(part.LocalId, true); 4021 try
4022 {
4023 foreach (SceneObjectPart part in parts)
4024 {
4025 parentPrim.DelinkFromGroup(part.LocalId, true);
4026 }
4027 }
4028 finally
4029 {
4030 }
3692 } 4031 }
4032
3693 parentPrim.HasGroupChanged = true; 4033 parentPrim.HasGroupChanged = true;
3694 parentPrim.ScheduleGroupForFullUpdate(); 4034 parentPrim.ScheduleGroupForFullUpdate();
3695 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4035 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3698,12 +4038,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3698 { 4038 {
3699 SceneObjectPart newRoot = parts[0]; 4039 SceneObjectPart newRoot = parts[0];
3700 parts.Remove(newRoot); 4040 parts.Remove(newRoot);
3701 foreach (SceneObjectPart part in parts) 4041
4042 try
3702 { 4043 {
3703 // Required for linking 4044 foreach (SceneObjectPart part in parts)
3704 part.ClearUpdateSchedule(); 4045 {
3705 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4046 part.ClearUpdateSchedule();
4047 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4048 }
3706 } 4049 }
4050 finally
4051 {
4052 }
4053
4054
3707 newRoot.ParentGroup.HasGroupChanged = true; 4055 newRoot.ParentGroup.HasGroupChanged = true;
3708 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4056 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3709 } 4057 }
@@ -3723,6 +4071,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3723 public void llBreakAllLinks() 4071 public void llBreakAllLinks()
3724 { 4072 {
3725 m_host.AddScriptLPS(1); 4073 m_host.AddScriptLPS(1);
4074
4075 TaskInventoryItem item = m_item;
4076
4077 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4078 && !m_automaticLinkPermission)
4079 {
4080 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4081 return;
4082 }
4083
3726 SceneObjectGroup parentPrim = m_host.ParentGroup; 4084 SceneObjectGroup parentPrim = m_host.ParentGroup;
3727 if (parentPrim.AttachmentPoint != 0) 4085 if (parentPrim.AttachmentPoint != 0)
3728 return; // Fail silently if attached 4086 return; // Fail silently if attached
@@ -3742,25 +4100,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3742 public LSL_String llGetLinkKey(int linknum) 4100 public LSL_String llGetLinkKey(int linknum)
3743 { 4101 {
3744 m_host.AddScriptLPS(1); 4102 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); 4103 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3765 if (part != null) 4104 if (part != null)
3766 { 4105 {
@@ -3768,6 +4107,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3768 } 4107 }
3769 else 4108 else
3770 { 4109 {
4110 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4111 {
4112 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4113
4114 if (linknum < 0)
4115 return UUID.Zero.ToString();
4116
4117 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4118 if (avatars.Count > linknum)
4119 {
4120 return avatars[linknum].UUID.ToString();
4121 }
4122 }
3771 return UUID.Zero.ToString(); 4123 return UUID.Zero.ToString();
3772 } 4124 }
3773 } 4125 }
@@ -3877,17 +4229,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3877 m_host.AddScriptLPS(1); 4229 m_host.AddScriptLPS(1);
3878 int count = 0; 4230 int count = 0;
3879 4231
3880 lock (m_host.TaskInventory) 4232 m_host.TaskInventory.LockItemsForRead(true);
4233 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3881 { 4234 {
3882 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4235 if (inv.Value.Type == type || type == -1)
3883 { 4236 {
3884 if (inv.Value.Type == type || type == -1) 4237 count = count + 1;
3885 {
3886 count = count + 1;
3887 }
3888 } 4238 }
3889 } 4239 }
3890 4240
4241 m_host.TaskInventory.LockItemsForRead(false);
3891 return count; 4242 return count;
3892 } 4243 }
3893 4244
@@ -3896,16 +4247,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3896 m_host.AddScriptLPS(1); 4247 m_host.AddScriptLPS(1);
3897 ArrayList keys = new ArrayList(); 4248 ArrayList keys = new ArrayList();
3898 4249
3899 lock (m_host.TaskInventory) 4250 m_host.TaskInventory.LockItemsForRead(true);
4251 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3900 { 4252 {
3901 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4253 if (inv.Value.Type == type || type == -1)
3902 { 4254 {
3903 if (inv.Value.Type == type || type == -1) 4255 keys.Add(inv.Value.Name);
3904 {
3905 keys.Add(inv.Value.Name);
3906 }
3907 } 4256 }
3908 } 4257 }
4258 m_host.TaskInventory.LockItemsForRead(false);
3909 4259
3910 if (keys.Count == 0) 4260 if (keys.Count == 0)
3911 { 4261 {
@@ -3943,7 +4293,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3943 if (item == null) 4293 if (item == null)
3944 { 4294 {
3945 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4295 llSay(0, String.Format("Could not find object '{0}'", inventory));
3946 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4296 return;
4297// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3947 } 4298 }
3948 4299
3949 UUID objId = item.ItemID; 4300 UUID objId = item.ItemID;
@@ -3971,33 +4322,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3971 return; 4322 return;
3972 } 4323 }
3973 } 4324 }
4325
3974 // destination is an avatar 4326 // destination is an avatar
3975 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4327 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3976 4328
3977 if (agentItem == null) 4329 if (agentItem == null)
3978 return; 4330 return;
3979 4331
3980 if (m_TransferModule != null) 4332 byte[] bucket = new byte[1];
3981 { 4333 bucket[0] = (byte)item.Type;
3982 byte[] bucket = new byte[] { (byte)item.Type }; 4334 //byte[] objBytes = agentItem.ID.GetBytes();
4335 //Array.Copy(objBytes, 0, bucket, 1, 16);
3983 4336
3984 GridInstantMessage msg = new GridInstantMessage(World, 4337 GridInstantMessage msg = new GridInstantMessage(World,
3985 m_host.UUID, m_host.Name + ", an object owned by " + 4338 m_host.OwnerID, m_host.Name, destId,
3986 resolveName(m_host.OwnerID) + ",", destId, 4339 (byte)InstantMessageDialog.TaskInventoryOffered,
3987 (byte)InstantMessageDialog.TaskInventoryOffered, 4340 false, item.Name+". "+m_host.Name+" is located at "+
3988 false, item.Name + "\n" + m_host.Name + " is located at " + 4341 World.RegionInfo.RegionName+" "+
3989 World.RegionInfo.RegionName+" "+ 4342 m_host.AbsolutePosition.ToString(),
3990 m_host.AbsolutePosition.ToString(), 4343 agentItem.ID, true, m_host.AbsolutePosition,
3991 agentItem.ID, true, m_host.AbsolutePosition, 4344 bucket, true);
3992 bucket, true); // TODO: May actually send no timestamp
3993 4345
3994 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4346 ScenePresence sp;
3995 }
3996 4347
4348 if (World.TryGetScenePresence(destId, out sp))
4349 {
4350 sp.ControllingClient.SendInstantMessage(msg);
4351 }
4352 else
4353 {
4354 if (m_TransferModule != null)
4355 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4356 }
4357
4358 //This delay should only occur when giving inventory to avatars.
3997 ScriptSleep(3000); 4359 ScriptSleep(3000);
3998 } 4360 }
3999 } 4361 }
4000 4362
4363 [DebuggerNonUserCode]
4001 public void llRemoveInventory(string name) 4364 public void llRemoveInventory(string name)
4002 { 4365 {
4003 m_host.AddScriptLPS(1); 4366 m_host.AddScriptLPS(1);
@@ -4052,109 +4415,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4052 { 4415 {
4053 m_host.AddScriptLPS(1); 4416 m_host.AddScriptLPS(1);
4054 4417
4055 UUID uuid = (UUID)id; 4418 UUID uuid;
4056 PresenceInfo pinfo = null; 4419 if (UUID.TryParse(id, out uuid))
4057 UserAccount account;
4058
4059 UserInfoCacheEntry ce;
4060 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4061 { 4420 {
4062 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4421 PresenceInfo pinfo = null;
4063 if (account == null) 4422 UserAccount account;
4423
4424 UserInfoCacheEntry ce;
4425 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4064 { 4426 {
4065 m_userInfoCache[uuid] = null; // Cache negative 4427 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4066 return UUID.Zero.ToString(); 4428 if (account == null)
4067 } 4429 {
4430 m_userInfoCache[uuid] = null; // Cache negative
4431 return UUID.Zero.ToString();
4432 }
4068 4433
4069 4434
4070 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4435 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4071 if (pinfos != null && pinfos.Length > 0) 4436 if (pinfos != null && pinfos.Length > 0)
4072 {
4073 foreach (PresenceInfo p in pinfos)
4074 { 4437 {
4075 if (p.RegionID != UUID.Zero) 4438 foreach (PresenceInfo p in pinfos)
4076 { 4439 {
4077 pinfo = p; 4440 if (p.RegionID != UUID.Zero)
4441 {
4442 pinfo = p;
4443 }
4078 } 4444 }
4079 } 4445 }
4080 }
4081 4446
4082 ce = new UserInfoCacheEntry(); 4447 ce = new UserInfoCacheEntry();
4083 ce.time = Util.EnvironmentTickCount(); 4448 ce.time = Util.EnvironmentTickCount();
4084 ce.account = account; 4449 ce.account = account;
4085 ce.pinfo = pinfo; 4450 ce.pinfo = pinfo;
4086 } 4451 m_userInfoCache[uuid] = ce;
4087 else 4452 }
4088 { 4453 else
4089 if (ce == null) 4454 {
4090 return UUID.Zero.ToString(); 4455 if (ce == null)
4456 return UUID.Zero.ToString();
4091 4457
4092 account = ce.account; 4458 account = ce.account;
4093 pinfo = ce.pinfo; 4459 pinfo = ce.pinfo;
4094 } 4460 }
4095 4461
4096 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4462 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4097 {
4098 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4099 if (pinfos != null && pinfos.Length > 0)
4100 { 4463 {
4101 foreach (PresenceInfo p in pinfos) 4464 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4465 if (pinfos != null && pinfos.Length > 0)
4102 { 4466 {
4103 if (p.RegionID != UUID.Zero) 4467 foreach (PresenceInfo p in pinfos)
4104 { 4468 {
4105 pinfo = p; 4469 if (p.RegionID != UUID.Zero)
4470 {
4471 pinfo = p;
4472 }
4106 } 4473 }
4107 } 4474 }
4108 } 4475 else
4109 else 4476 pinfo = null;
4110 pinfo = null;
4111 4477
4112 ce.time = Util.EnvironmentTickCount(); 4478 ce.time = Util.EnvironmentTickCount();
4113 ce.pinfo = pinfo; 4479 ce.pinfo = pinfo;
4114 } 4480 }
4115 4481
4116 string reply = String.Empty; 4482 string reply = String.Empty;
4117 4483
4118 switch (data) 4484 switch (data)
4119 { 4485 {
4120 case 1: // DATA_ONLINE (0|1) 4486 case 1: // DATA_ONLINE (0|1)
4121 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4487 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4122 reply = "1"; 4488 reply = "1";
4123 else 4489 else
4124 reply = "0"; 4490 reply = "0";
4125 break; 4491 break;
4126 case 2: // DATA_NAME (First Last) 4492 case 2: // DATA_NAME (First Last)
4127 reply = account.FirstName + " " + account.LastName; 4493 reply = account.FirstName + " " + account.LastName;
4128 break; 4494 break;
4129 case 3: // DATA_BORN (YYYY-MM-DD) 4495 case 3: // DATA_BORN (YYYY-MM-DD)
4130 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4496 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4131 born = born.AddSeconds(account.Created); 4497 born = born.AddSeconds(account.Created);
4132 reply = born.ToString("yyyy-MM-dd"); 4498 reply = born.ToString("yyyy-MM-dd");
4133 break; 4499 break;
4134 case 4: // DATA_RATING (0,0,0,0,0,0) 4500 case 4: // DATA_RATING (0,0,0,0,0,0)
4135 reply = "0,0,0,0,0,0"; 4501 reply = "0,0,0,0,0,0";
4136 break; 4502 break;
4137 case 7: // DATA_USERLEVEL (integer) 4503 case 8: // DATA_PAYINFO (0|1|2|3)
4138 reply = account.UserLevel.ToString(); 4504 reply = "0";
4139 break; 4505 break;
4140 case 8: // DATA_PAYINFO (0|1|2|3) 4506 default:
4141 reply = "0"; 4507 return UUID.Zero.ToString(); // Raise no event
4142 break; 4508 }
4143 default:
4144 return UUID.Zero.ToString(); // Raise no event
4145 }
4146 4509
4147 UUID rq = UUID.Random(); 4510 UUID rq = UUID.Random();
4148 4511
4149 UUID tid = AsyncCommands. 4512 UUID tid = AsyncCommands.
4150 DataserverPlugin.RegisterRequest(m_host.LocalId, 4513 DataserverPlugin.RegisterRequest(m_host.LocalId,
4151 m_item.ItemID, rq.ToString()); 4514 m_item.ItemID, rq.ToString());
4152 4515
4153 AsyncCommands. 4516 AsyncCommands.
4154 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4517 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4155 4518
4156 ScriptSleep(100); 4519 ScriptSleep(100);
4157 return tid.ToString(); 4520 return tid.ToString();
4521 }
4522 else
4523 {
4524 ShoutError("Invalid UUID passed to llRequestAgentData.");
4525 }
4526 return "";
4158 } 4527 }
4159 4528
4160 public LSL_String llRequestInventoryData(string name) 4529 public LSL_String llRequestInventoryData(string name)
@@ -4211,13 +4580,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4211 if (UUID.TryParse(agent, out agentId)) 4580 if (UUID.TryParse(agent, out agentId))
4212 { 4581 {
4213 ScenePresence presence = World.GetScenePresence(agentId); 4582 ScenePresence presence = World.GetScenePresence(agentId);
4214 if (presence != null) 4583 if (presence != null && presence.PresenceType != PresenceType.Npc)
4215 { 4584 {
4585 // agent must not be a god
4586 if (presence.UserLevel >= 200) return;
4587
4216 // agent must be over the owners land 4588 // agent must be over the owners land
4217 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4589 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4218 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4590 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4219 { 4591 {
4220 World.TeleportClientHome(agentId, presence.ControllingClient); 4592 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4593 {
4594 // They can't be teleported home for some reason
4595 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4596 if (regionInfo != null)
4597 {
4598 World.RequestTeleportLocation(
4599 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4600 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4601 }
4602 }
4221 } 4603 }
4222 } 4604 }
4223 } 4605 }
@@ -4324,7 +4706,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4324 UUID av = new UUID(); 4706 UUID av = new UUID();
4325 if (!UUID.TryParse(agent,out av)) 4707 if (!UUID.TryParse(agent,out av))
4326 { 4708 {
4327 LSLError("First parameter to llDialog needs to be a key"); 4709 //LSLError("First parameter to llDialog needs to be a key");
4328 return; 4710 return;
4329 } 4711 }
4330 4712
@@ -4356,7 +4738,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4356 public void llCollisionSound(string impact_sound, double impact_volume) 4738 public void llCollisionSound(string impact_sound, double impact_volume)
4357 { 4739 {
4358 m_host.AddScriptLPS(1); 4740 m_host.AddScriptLPS(1);
4359 4741
4742 if(impact_sound == "")
4743 {
4744 m_host.CollisionSoundVolume = (float)impact_volume;
4745 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4746 m_host.CollisionSoundType = 0;
4747 return;
4748 }
4360 // TODO: Parameter check logic required. 4749 // TODO: Parameter check logic required.
4361 UUID soundId = UUID.Zero; 4750 UUID soundId = UUID.Zero;
4362 if (!UUID.TryParse(impact_sound, out soundId)) 4751 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4369,6 +4758,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4369 4758
4370 m_host.CollisionSound = soundId; 4759 m_host.CollisionSound = soundId;
4371 m_host.CollisionSoundVolume = (float)impact_volume; 4760 m_host.CollisionSoundVolume = (float)impact_volume;
4761 m_host.CollisionSoundType = 1;
4372 } 4762 }
4373 4763
4374 public LSL_String llGetAnimation(string id) 4764 public LSL_String llGetAnimation(string id)
@@ -4382,14 +4772,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4382 4772
4383 if (m_host.RegionHandle == presence.RegionHandle) 4773 if (m_host.RegionHandle == presence.RegionHandle)
4384 { 4774 {
4385 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4386
4387 if (presence != null) 4775 if (presence != null)
4388 { 4776 {
4389 AnimationSet currentAnims = presence.Animator.Animations; 4777 if (presence.SitGround)
4390 string currentAnimationState = String.Empty; 4778 return "Sitting on Ground";
4391 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4779 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4392 return currentAnimationState; 4780 return "Sitting";
4781
4782 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4783 string lslMovementAnimation;
4784
4785 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4786 return lslMovementAnimation;
4393 } 4787 }
4394 } 4788 }
4395 4789
@@ -4536,7 +4930,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4536 { 4930 {
4537 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4931 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4538 float distance_term = distance * distance * distance; // Script Energy 4932 float distance_term = distance * distance * distance; // Script Energy
4539 float pusher_mass = m_host.GetMass(); 4933 // use total object mass and not part
4934 float pusher_mass = m_host.ParentGroup.GetMass();
4540 4935
4541 float PUSH_ATTENUATION_DISTANCE = 17f; 4936 float PUSH_ATTENUATION_DISTANCE = 17f;
4542 float PUSH_ATTENUATION_SCALE = 5f; 4937 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4786,6 +5181,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4786 { 5181 {
4787 return item.AssetID.ToString(); 5182 return item.AssetID.ToString();
4788 } 5183 }
5184 m_host.TaskInventory.LockItemsForRead(false);
4789 5185
4790 return UUID.Zero.ToString(); 5186 return UUID.Zero.ToString();
4791 } 5187 }
@@ -4919,7 +5315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4919 public LSL_Vector llGetCenterOfMass() 5315 public LSL_Vector llGetCenterOfMass()
4920 { 5316 {
4921 m_host.AddScriptLPS(1); 5317 m_host.AddScriptLPS(1);
4922 Vector3 center = m_host.GetGeometricCenter(); 5318 Vector3 center = m_host.GetCenterOfMass();
4923 return new LSL_Vector(center.X,center.Y,center.Z); 5319 return new LSL_Vector(center.X,center.Y,center.Z);
4924 } 5320 }
4925 5321
@@ -4938,14 +5334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4938 { 5334 {
4939 m_host.AddScriptLPS(1); 5335 m_host.AddScriptLPS(1);
4940 5336
4941 if (src == null) 5337 return src.Length;
4942 {
4943 return 0;
4944 }
4945 else
4946 {
4947 return src.Length;
4948 }
4949 } 5338 }
4950 5339
4951 public LSL_Integer llList2Integer(LSL_List src, int index) 5340 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5016,7 +5405,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5016 else if (src.Data[index] is LSL_Float) 5405 else if (src.Data[index] is LSL_Float)
5017 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5406 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5018 else if (src.Data[index] is LSL_String) 5407 else if (src.Data[index] is LSL_String)
5019 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5408 {
5409 string str = ((LSL_String) src.Data[index]).m_string;
5410 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5411 if (m != Match.Empty)
5412 {
5413 str = m.Value;
5414 double d = 0.0;
5415 if (!Double.TryParse(str, out d))
5416 return 0.0;
5417
5418 return d;
5419 }
5420 return 0.0;
5421 }
5020 return Convert.ToDouble(src.Data[index]); 5422 return Convert.ToDouble(src.Data[index]);
5021 } 5423 }
5022 catch (FormatException) 5424 catch (FormatException)
@@ -5058,7 +5460,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5058 // for completion and should LSL_Key ever be implemented 5460 // for completion and should LSL_Key ever be implemented
5059 // as it's own struct 5461 // as it's own struct
5060 else if (!(src.Data[index] is LSL_String || 5462 else if (!(src.Data[index] is LSL_String ||
5061 src.Data[index] is LSL_Key)) 5463 src.Data[index] is LSL_Key ||
5464 src.Data[index] is String))
5062 { 5465 {
5063 return ""; 5466 return "";
5064 } 5467 }
@@ -5316,7 +5719,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5316 } 5719 }
5317 } 5720 }
5318 } 5721 }
5319 else { 5722 else
5723 {
5320 object[] array = new object[src.Length]; 5724 object[] array = new object[src.Length];
5321 Array.Copy(src.Data, 0, array, 0, src.Length); 5725 Array.Copy(src.Data, 0, array, 0, src.Length);
5322 result = new LSL_List(array); 5726 result = new LSL_List(array);
@@ -5423,7 +5827,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5423 public LSL_Integer llGetRegionAgentCount() 5827 public LSL_Integer llGetRegionAgentCount()
5424 { 5828 {
5425 m_host.AddScriptLPS(1); 5829 m_host.AddScriptLPS(1);
5426 return new LSL_Integer(World.GetRootAgentCount()); 5830
5831 int count = 0;
5832 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5833 count++;
5834 });
5835
5836 return new LSL_Integer(count);
5427 } 5837 }
5428 5838
5429 public LSL_Vector llGetRegionCorner() 5839 public LSL_Vector llGetRegionCorner()
@@ -5664,6 +6074,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5664 flags |= ScriptBaseClass.AGENT_AWAY; 6074 flags |= ScriptBaseClass.AGENT_AWAY;
5665 } 6075 }
5666 6076
6077 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6078 UUID[] anims = agent.Animator.GetAnimationArray();
6079 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6080 {
6081 flags |= ScriptBaseClass.AGENT_BUSY;
6082 }
6083
5667 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6084 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5668 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6085 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5669 { 6086 {
@@ -5711,6 +6128,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5711 flags |= ScriptBaseClass.AGENT_SITTING; 6128 flags |= ScriptBaseClass.AGENT_SITTING;
5712 } 6129 }
5713 6130
6131 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6132 {
6133 flags |= ScriptBaseClass.AGENT_MALE;
6134 }
6135
5714 return flags; 6136 return flags;
5715 } 6137 }
5716 6138
@@ -5858,9 +6280,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5858 6280
5859 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6281 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5860 6282
5861 foreach (SceneObjectPart part in parts) 6283 try
6284 {
6285 foreach (SceneObjectPart part in parts)
6286 {
6287 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6288 }
6289 }
6290 finally
5862 { 6291 {
5863 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5864 } 6292 }
5865 } 6293 }
5866 6294
@@ -5912,13 +6340,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5912 6340
5913 if (m_host.OwnerID == land.LandData.OwnerID) 6341 if (m_host.OwnerID == land.LandData.OwnerID)
5914 { 6342 {
5915 World.TeleportClientHome(agentID, presence.ControllingClient); 6343 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6344 presence.TeleportWithMomentum(pos, null);
6345 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5916 } 6346 }
5917 } 6347 }
5918 } 6348 }
5919 ScriptSleep(5000); 6349 ScriptSleep(5000);
5920 } 6350 }
5921 6351
6352 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6353 {
6354 return ParseString2List(str, separators, in_spacers, false);
6355 }
6356
5922 public LSL_Integer llOverMyLand(string id) 6357 public LSL_Integer llOverMyLand(string id)
5923 { 6358 {
5924 m_host.AddScriptLPS(1); 6359 m_host.AddScriptLPS(1);
@@ -5977,20 +6412,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5977 return agentSize; 6412 return agentSize;
5978 } 6413 }
5979 6414
5980 public LSL_Integer llSameGroup(string agent) 6415 public LSL_Integer llSameGroup(string id)
5981 { 6416 {
5982 m_host.AddScriptLPS(1); 6417 m_host.AddScriptLPS(1);
5983 UUID agentId = new UUID(); 6418 UUID uuid = new UUID();
5984 if (!UUID.TryParse(agent, out agentId)) 6419 if (!UUID.TryParse(id, out uuid))
5985 return new LSL_Integer(0); 6420 return new LSL_Integer(0);
5986 ScenePresence presence = World.GetScenePresence(agentId); 6421
5987 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6422 // Check if it's a group key
5988 return new LSL_Integer(0); 6423 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5989 IClientAPI client = presence.ControllingClient;
5990 if (m_host.GroupID == client.ActiveGroupId)
5991 return new LSL_Integer(1); 6424 return new LSL_Integer(1);
5992 else 6425
6426 // We got passed a UUID.Zero
6427 if (uuid == UUID.Zero)
5993 return new LSL_Integer(0); 6428 return new LSL_Integer(0);
6429
6430 // Handle the case where id names an avatar
6431 ScenePresence presence = World.GetScenePresence(uuid);
6432 if (presence != null)
6433 {
6434 if (presence.IsChildAgent)
6435 return new LSL_Integer(0);
6436
6437 IClientAPI client = presence.ControllingClient;
6438 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6439 return new LSL_Integer(1);
6440
6441 return new LSL_Integer(0);
6442 }
6443
6444 // Handle object case
6445 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6446 if (part != null)
6447 {
6448 // This will handle both deed and non-deed and also the no
6449 // group case
6450 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6451 return new LSL_Integer(1);
6452
6453 return new LSL_Integer(0);
6454 }
6455
6456 return new LSL_Integer(0);
5994 } 6457 }
5995 6458
5996 public void llUnSit(string id) 6459 public void llUnSit(string id)
@@ -6115,7 +6578,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6115 return m_host.ParentGroup.AttachmentPoint; 6578 return m_host.ParentGroup.AttachmentPoint;
6116 } 6579 }
6117 6580
6118 public LSL_Integer llGetFreeMemory() 6581 public virtual LSL_Integer llGetFreeMemory()
6119 { 6582 {
6120 m_host.AddScriptLPS(1); 6583 m_host.AddScriptLPS(1);
6121 // Make scripts designed for LSO happy 6584 // Make scripts designed for LSO happy
@@ -6232,7 +6695,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6232 SetParticleSystem(m_host, rules); 6695 SetParticleSystem(m_host, rules);
6233 } 6696 }
6234 6697
6235 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6698 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6699 {
6236 6700
6237 6701
6238 if (rules.Length == 0) 6702 if (rules.Length == 0)
@@ -6547,6 +7011,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6547 7011
6548 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7012 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6549 { 7013 {
7014 // LSL quaternions can normalize to 0, normal Quaternions can't.
7015 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7016 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7017
6550 part.SitTargetPosition = offset; 7018 part.SitTargetPosition = offset;
6551 part.SitTargetOrientation = rot; 7019 part.SitTargetOrientation = rot;
6552 part.ParentGroup.HasGroupChanged = true; 7020 part.ParentGroup.HasGroupChanged = true;
@@ -6702,13 +7170,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6702 UUID av = new UUID(); 7170 UUID av = new UUID();
6703 if (!UUID.TryParse(avatar,out av)) 7171 if (!UUID.TryParse(avatar,out av))
6704 { 7172 {
6705 LSLError("First parameter to llDialog needs to be a key"); 7173 //LSLError("First parameter to llDialog needs to be a key");
6706 return; 7174 return;
6707 } 7175 }
6708 if (buttons.Length < 1) 7176 if (buttons.Length < 1)
6709 { 7177 {
6710 LSLError("No less than 1 button can be shown"); 7178 buttons.Add("OK");
6711 return;
6712 } 7179 }
6713 if (buttons.Length > 12) 7180 if (buttons.Length > 12)
6714 { 7181 {
@@ -6725,7 +7192,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6725 } 7192 }
6726 if (buttons.Data[i].ToString().Length > 24) 7193 if (buttons.Data[i].ToString().Length > 24)
6727 { 7194 {
6728 LSLError("button label cannot be longer than 24 characters"); 7195 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6729 return; 7196 return;
6730 } 7197 }
6731 buts[i] = buttons.Data[i].ToString(); 7198 buts[i] = buttons.Data[i].ToString();
@@ -6792,9 +7259,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6792 return; 7259 return;
6793 } 7260 }
6794 7261
6795 // the rest of the permission checks are done in RezScript, so check the pin there as well 7262 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6796 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7263 if (dest != null)
7264 {
7265 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7266 {
7267 // the rest of the permission checks are done in RezScript, so check the pin there as well
7268 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6797 7269
7270 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7271 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7272 }
7273 }
6798 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7274 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6799 ScriptSleep(3000); 7275 ScriptSleep(3000);
6800 } 7276 }
@@ -6857,19 +7333,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6857 public LSL_String llMD5String(string src, int nonce) 7333 public LSL_String llMD5String(string src, int nonce)
6858 { 7334 {
6859 m_host.AddScriptLPS(1); 7335 m_host.AddScriptLPS(1);
6860 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7336 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6861 } 7337 }
6862 7338
6863 public LSL_String llSHA1String(string src) 7339 public LSL_String llSHA1String(string src)
6864 { 7340 {
6865 m_host.AddScriptLPS(1); 7341 m_host.AddScriptLPS(1);
6866 return Util.SHA1Hash(src).ToLower(); 7342 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6867 } 7343 }
6868 7344
6869 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7345 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6870 { 7346 {
6871 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7347 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6872 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7348 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7349 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7350 return shapeBlock;
6873 7351
6874 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7352 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6875 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7353 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6974,6 +7452,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6974 // Prim type box, cylinder and prism. 7452 // Prim type box, cylinder and prism.
6975 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) 7453 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)
6976 { 7454 {
7455 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7456 return;
7457
6977 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7458 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6978 ObjectShapePacket.ObjectDataBlock shapeBlock; 7459 ObjectShapePacket.ObjectDataBlock shapeBlock;
6979 7460
@@ -7027,6 +7508,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7027 // Prim type sphere. 7508 // Prim type sphere.
7028 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7509 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7029 { 7510 {
7511 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7512 return;
7513
7030 ObjectShapePacket.ObjectDataBlock shapeBlock; 7514 ObjectShapePacket.ObjectDataBlock shapeBlock;
7031 7515
7032 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7516 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7068,6 +7552,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7068 // Prim type torus, tube and ring. 7552 // Prim type torus, tube and ring.
7069 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) 7553 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)
7070 { 7554 {
7555 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7556 return;
7557
7071 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7558 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7072 ObjectShapePacket.ObjectDataBlock shapeBlock; 7559 ObjectShapePacket.ObjectDataBlock shapeBlock;
7073 7560
@@ -7203,6 +7690,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7203 // Prim type sculpt. 7690 // Prim type sculpt.
7204 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7691 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7205 { 7692 {
7693 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7694 return;
7695
7206 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7696 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7207 UUID sculptId; 7697 UUID sculptId;
7208 7698
@@ -7227,7 +7717,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7227 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7717 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7228 { 7718 {
7229 // default 7719 // default
7230 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7720 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7231 } 7721 }
7232 7722
7233 part.Shape.SetSculptProperties((byte)type, sculptId); 7723 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7244,48 +7734,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7244 ScriptSleep(200); 7734 ScriptSleep(200);
7245 } 7735 }
7246 7736
7247 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7737 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7248 { 7738 {
7249 m_host.AddScriptLPS(1); 7739 m_host.AddScriptLPS(1);
7250 7740
7251 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7741 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7252 7742
7253 ScriptSleep(200); 7743 ScriptSleep(200);
7254 } 7744 }
7255 7745
7256 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7746 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7257 { 7747 {
7258 m_host.AddScriptLPS(1); 7748 List<object> parts = new List<object>();
7749 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7750 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7751 foreach (SceneObjectPart p in prims)
7752 parts.Add(p);
7753 foreach (ScenePresence p in avatars)
7754 parts.Add(p);
7259 7755
7260 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7756 LSL_List remaining = null;
7757 uint rulesParsed = 0;
7758
7759 if (parts.Count > 0)
7760 {
7761 foreach (object part in parts)
7762 {
7763 if (part is SceneObjectPart)
7764 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7765 else
7766 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7767 }
7768
7769 while ((object)remaining != null && remaining.Length > 2)
7770 {
7771 linknumber = remaining.GetLSLIntegerItem(0);
7772 rules = remaining.GetSublist(1, -1);
7773 parts.Clear();
7774 prims = GetLinkParts(linknumber);
7775 avatars = GetLinkAvatars(linknumber);
7776 foreach (SceneObjectPart p in prims)
7777 parts.Add(p);
7778 foreach (ScenePresence p in avatars)
7779 parts.Add(p);
7780
7781 remaining = null;
7782 foreach (object part in parts)
7783 {
7784 if (part is SceneObjectPart)
7785 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7786 else
7787 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7788 }
7789 }
7790 }
7261 } 7791 }
7262 7792
7263 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7793 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7794 float material_density, float material_friction,
7795 float material_restitution, float material_gravity_modifier)
7264 { 7796 {
7265 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7797 ExtraPhysicsData physdata = new ExtraPhysicsData();
7798 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7799 physdata.Density = part.Density;
7800 physdata.Friction = part.Friction;
7801 physdata.Bounce = part.Bounciness;
7802 physdata.GravitationModifier = part.GravityModifier;
7266 7803
7267 LSL_List remaining = null; 7804 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7268 uint rulesParsed = 0; 7805 physdata.Density = material_density;
7806 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7807 physdata.Friction = material_friction;
7808 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7809 physdata.Bounce = material_restitution;
7810 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7811 physdata.GravitationModifier = material_gravity_modifier;
7269 7812
7270 foreach (SceneObjectPart part in parts) 7813 part.UpdateExtraPhysics(physdata);
7271 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7814 }
7272 7815
7273 while (remaining != null && remaining.Length > 2) 7816 public void llSetPhysicsMaterial(int material_bits,
7274 { 7817 float material_gravity_modifier, float material_restitution,
7275 linknumber = remaining.GetLSLIntegerItem(0); 7818 float material_friction, float material_density)
7276 rules = remaining.GetSublist(1, -1); 7819 {
7277 parts = GetLinkParts(linknumber); 7820 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7821 }
7278 7822
7279 foreach (SceneObjectPart part in parts) 7823 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7280 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7824 {
7825 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7826 llSetLinkPrimitiveParamsFast(linknumber, rules);
7827 ScriptSleep(200);
7828 }
7829
7830 // vector up using libomv (c&p from sop )
7831 // vector up rotated by r
7832 private Vector3 Zrot(Quaternion r)
7833 {
7834 double x, y, z, m;
7835
7836 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7837 if (Math.Abs(1.0 - m) > 0.000001)
7838 {
7839 m = 1.0 / Math.Sqrt(m);
7840 r.X *= (float)m;
7841 r.Y *= (float)m;
7842 r.Z *= (float)m;
7843 r.W *= (float)m;
7281 } 7844 }
7845
7846 x = 2 * (r.X * r.Z + r.Y * r.W);
7847 y = 2 * (-r.X * r.W + r.Y * r.Z);
7848 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7849
7850 return new Vector3((float)x, (float)y, (float)z);
7282 } 7851 }
7283 7852
7284 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7853 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7285 { 7854 {
7855 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7856 return null;
7857
7286 int idx = 0; 7858 int idx = 0;
7287 int idxStart = 0; 7859 int idxStart = 0;
7288 7860
7861 SceneObjectGroup parentgrp = part.ParentGroup;
7862
7289 bool positionChanged = false; 7863 bool positionChanged = false;
7290 LSL_Vector currentPosition = GetPartLocalPos(part); 7864 LSL_Vector currentPosition = GetPartLocalPos(part);
7291 7865
@@ -7310,8 +7884,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7310 return null; 7884 return null;
7311 7885
7312 v=rules.GetVector3Item(idx++); 7886 v=rules.GetVector3Item(idx++);
7313 positionChanged = true;
7314 currentPosition = GetSetPosTarget(part, v, currentPosition); 7887 currentPosition = GetSetPosTarget(part, v, currentPosition);
7888 positionChanged = true;
7315 7889
7316 break; 7890 break;
7317 case (int)ScriptBaseClass.PRIM_SIZE: 7891 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7588,7 +8162,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7588 return null; 8162 return null;
7589 8163
7590 string ph = rules.Data[idx++].ToString(); 8164 string ph = rules.Data[idx++].ToString();
7591 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8165 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7592 8166
7593 break; 8167 break;
7594 8168
@@ -7606,12 +8180,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7606 part.ScriptSetPhysicsStatus(physics); 8180 part.ScriptSetPhysicsStatus(physics);
7607 break; 8181 break;
7608 8182
8183 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8184 if (remain < 1)
8185 return null;
8186
8187 int shape_type = rules.GetLSLIntegerItem(idx++);
8188
8189 ExtraPhysicsData physdata = new ExtraPhysicsData();
8190 physdata.Density = part.Density;
8191 physdata.Bounce = part.Bounciness;
8192 physdata.GravitationModifier = part.GravityModifier;
8193 physdata.PhysShapeType = (PhysShapeType)shape_type;
8194
8195 part.UpdateExtraPhysics(physdata);
8196
8197 break;
8198
8199 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8200 if (remain < 5)
8201 return null;
8202
8203 int material_bits = rules.GetLSLIntegerItem(idx++);
8204 float material_density = (float)rules.GetLSLFloatItem(idx++);
8205 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8206 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8207 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8208
8209 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8210
8211 break;
8212
7609 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8213 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7610 if (remain < 1) 8214 if (remain < 1)
7611 return null; 8215 return null;
7612 string temp = rules.Data[idx++].ToString(); 8216 string temp = rules.Data[idx++].ToString();
7613 8217
7614 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8218 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7615 8219
7616 break; 8220 break;
7617 8221
@@ -7685,7 +8289,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7685 if (part.ParentGroup.RootPart == part) 8289 if (part.ParentGroup.RootPart == part)
7686 { 8290 {
7687 SceneObjectGroup parent = part.ParentGroup; 8291 SceneObjectGroup parent = part.ParentGroup;
7688 parent.UpdateGroupPosition(currentPosition); 8292 Util.FireAndForget(delegate(object x) {
8293 parent.UpdateGroupPosition(currentPosition);
8294 });
7689 } 8295 }
7690 else 8296 else
7691 { 8297 {
@@ -7730,10 +8336,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7730 8336
7731 public LSL_String llXorBase64Strings(string str1, string str2) 8337 public LSL_String llXorBase64Strings(string str1, string str2)
7732 { 8338 {
7733 m_host.AddScriptLPS(1); 8339 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7734 Deprecated("llXorBase64Strings"); 8340
7735 ScriptSleep(300); 8341 ScriptSleep(300);
7736 return String.Empty; 8342 m_host.AddScriptLPS(1);
8343
8344 if (str1 == String.Empty)
8345 return String.Empty;
8346 if (str2 == String.Empty)
8347 return str1;
8348
8349 int len = str2.Length;
8350 if ((len % 4) != 0) // LL is EVIL!!!!
8351 {
8352 while (str2.EndsWith("="))
8353 str2 = str2.Substring(0, str2.Length - 1);
8354
8355 len = str2.Length;
8356 int mod = len % 4;
8357
8358 if (mod == 1)
8359 str2 = str2.Substring(0, str2.Length - 1);
8360 else if (mod == 2)
8361 str2 += "==";
8362 else if (mod == 3)
8363 str2 += "=";
8364 }
8365
8366 byte[] data1;
8367 byte[] data2;
8368 try
8369 {
8370 data1 = Convert.FromBase64String(str1);
8371 data2 = Convert.FromBase64String(str2);
8372 }
8373 catch (Exception)
8374 {
8375 return new LSL_String(String.Empty);
8376 }
8377
8378 // For cases where the decoded length of s2 is greater
8379 // than the decoded length of s1, simply perform a normal
8380 // decode and XOR
8381 //
8382 if (data2.Length >= data1.Length)
8383 {
8384 for (int pos = 0 ; pos < data1.Length ; pos++ )
8385 data1[pos] ^= data2[pos];
8386
8387 return Convert.ToBase64String(data1);
8388 }
8389
8390 // Remove padding
8391 while (str1.EndsWith("="))
8392 str1 = str1.Substring(0, str1.Length - 1);
8393 while (str2.EndsWith("="))
8394 str2 = str2.Substring(0, str2.Length - 1);
8395
8396 byte[] d1 = new byte[str1.Length];
8397 byte[] d2 = new byte[str2.Length];
8398
8399 for (int i = 0 ; i < str1.Length ; i++)
8400 {
8401 int idx = b64.IndexOf(str1.Substring(i, 1));
8402 if (idx == -1)
8403 idx = 0;
8404 d1[i] = (byte)idx;
8405 }
8406
8407 for (int i = 0 ; i < str2.Length ; i++)
8408 {
8409 int idx = b64.IndexOf(str2.Substring(i, 1));
8410 if (idx == -1)
8411 idx = 0;
8412 d2[i] = (byte)idx;
8413 }
8414
8415 string output = String.Empty;
8416
8417 for (int pos = 0 ; pos < d1.Length ; pos++)
8418 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8419
8420 while (output.Length % 3 > 0)
8421 output += "=";
8422
8423 return output;
7737 } 8424 }
7738 8425
7739 public void llRemoteDataSetRegion() 8426 public void llRemoteDataSetRegion()
@@ -7857,13 +8544,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7857 public LSL_Integer llGetNumberOfPrims() 8544 public LSL_Integer llGetNumberOfPrims()
7858 { 8545 {
7859 m_host.AddScriptLPS(1); 8546 m_host.AddScriptLPS(1);
7860 int avatarCount = 0; 8547 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7861 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8548
7862 {
7863 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7864 avatarCount++;
7865 });
7866
7867 return m_host.ParentGroup.PrimCount + avatarCount; 8549 return m_host.ParentGroup.PrimCount + avatarCount;
7868 } 8550 }
7869 8551
@@ -7879,55 +8561,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7879 m_host.AddScriptLPS(1); 8561 m_host.AddScriptLPS(1);
7880 UUID objID = UUID.Zero; 8562 UUID objID = UUID.Zero;
7881 LSL_List result = new LSL_List(); 8563 LSL_List result = new LSL_List();
8564
8565 // If the ID is not valid, return null result
7882 if (!UUID.TryParse(obj, out objID)) 8566 if (!UUID.TryParse(obj, out objID))
7883 { 8567 {
7884 result.Add(new LSL_Vector()); 8568 result.Add(new LSL_Vector());
7885 result.Add(new LSL_Vector()); 8569 result.Add(new LSL_Vector());
7886 return result; 8570 return result;
7887 } 8571 }
8572
8573 // Check if this is an attached prim. If so, replace
8574 // the UUID with the avatar UUID and report it's bounding box
8575 SceneObjectPart part = World.GetSceneObjectPart(objID);
8576 if (part != null && part.ParentGroup.IsAttachment)
8577 objID = part.ParentGroup.AttachedAvatar;
8578
8579 // Find out if this is an avatar ID. If so, return it's box
7888 ScenePresence presence = World.GetScenePresence(objID); 8580 ScenePresence presence = World.GetScenePresence(objID);
7889 if (presence != null) 8581 if (presence != null)
7890 { 8582 {
7891 if (presence.ParentID == 0) // not sat on an object 8583 // As per LSL Wiki, there is no difference between sitting
8584 // and standing avatar since server 1.36
8585 LSL_Vector lower;
8586 LSL_Vector upper;
8587 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8588 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7892 { 8589 {
7893 LSL_Vector lower; 8590 // This is for ground sitting avatars
7894 LSL_Vector upper; 8591 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7895 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8592 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7896 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8593 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7897 {
7898 // This is for ground sitting avatars
7899 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7900 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7901 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7902 }
7903 else
7904 {
7905 // This is for standing/flying avatars
7906 float height = presence.Appearance.AvatarHeight / 2.0f;
7907 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7908 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7909 }
7910 result.Add(lower);
7911 result.Add(upper);
7912 return result;
7913 } 8594 }
7914 else 8595 else
7915 { 8596 {
7916 // sitting on an object so we need the bounding box of that 8597 // This is for standing/flying avatars
7917 // which should include the avatar so set the UUID to the 8598 float height = presence.Appearance.AvatarHeight / 2.0f;
7918 // UUID of the object the avatar is sat on and allow it to fall through 8599 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7919 // to processing an object 8600 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7920 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7921 objID = p.UUID;
7922 } 8601 }
8602
8603 // Adjust to the documented error offsets (see LSL Wiki)
8604 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8605 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8606
8607 if (lower.x > upper.x)
8608 lower.x = upper.x;
8609 if (lower.y > upper.y)
8610 lower.y = upper.y;
8611 if (lower.z > upper.z)
8612 lower.z = upper.z;
8613
8614 result.Add(lower);
8615 result.Add(upper);
8616 return result;
7923 } 8617 }
7924 SceneObjectPart part = World.GetSceneObjectPart(objID); 8618
8619 part = World.GetSceneObjectPart(objID);
7925 // Currently only works for single prims without a sitting avatar 8620 // Currently only works for single prims without a sitting avatar
7926 if (part != null) 8621 if (part != null)
7927 { 8622 {
7928 Vector3 halfSize = part.Scale / 2.0f; 8623 float minX;
7929 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8624 float maxX;
7930 LSL_Vector upper = new LSL_Vector(halfSize); 8625 float minY;
8626 float maxY;
8627 float minZ;
8628 float maxZ;
8629
8630 // This BBox is in sim coordinates, with the offset being
8631 // a contained point.
8632 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8633 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8634
8635 minX -= offsets[0].X;
8636 maxX -= offsets[0].X;
8637 minY -= offsets[0].Y;
8638 maxY -= offsets[0].Y;
8639 minZ -= offsets[0].Z;
8640 maxZ -= offsets[0].Z;
8641
8642 LSL_Vector lower;
8643 LSL_Vector upper;
8644
8645 // Adjust to the documented error offsets (see LSL Wiki)
8646 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8647 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8648
8649 if (lower.x > upper.x)
8650 lower.x = upper.x;
8651 if (lower.y > upper.y)
8652 lower.y = upper.y;
8653 if (lower.z > upper.z)
8654 lower.z = upper.z;
8655
7931 result.Add(lower); 8656 result.Add(lower);
7932 result.Add(upper); 8657 result.Add(upper);
7933 return result; 8658 return result;
@@ -7941,7 +8666,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7941 8666
7942 public LSL_Vector llGetGeometricCenter() 8667 public LSL_Vector llGetGeometricCenter()
7943 { 8668 {
7944 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8669 Vector3 tmp = m_host.GetGeometricCenter();
8670 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7945 } 8671 }
7946 8672
7947 public LSL_List llGetPrimitiveParams(LSL_List rules) 8673 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7969,24 +8695,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7969 { 8695 {
7970 m_host.AddScriptLPS(1); 8696 m_host.AddScriptLPS(1);
7971 8697
7972 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8698 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8699 // keep other options as before
7973 8700
8701 List<SceneObjectPart> parts;
8702 List<ScenePresence> avatars;
8703
7974 LSL_List res = new LSL_List(); 8704 LSL_List res = new LSL_List();
7975 LSL_List remaining = null; 8705 LSL_List remaining = null;
7976 8706
7977 foreach (SceneObjectPart part in parts) 8707 while (rules.Length > 0)
7978 { 8708 {
7979 remaining = GetPrimParams(part, rules, ref res);
7980 }
7981
7982 while (remaining != null && remaining.Length > 2)
7983 {
7984 linknumber = remaining.GetLSLIntegerItem(0);
7985 rules = remaining.GetSublist(1, -1);
7986 parts = GetLinkParts(linknumber); 8709 parts = GetLinkParts(linknumber);
8710 avatars = GetLinkAvatars(linknumber);
7987 8711
8712 remaining = null;
7988 foreach (SceneObjectPart part in parts) 8713 foreach (SceneObjectPart part in parts)
8714 {
7989 remaining = GetPrimParams(part, rules, ref res); 8715 remaining = GetPrimParams(part, rules, ref res);
8716 }
8717 foreach (ScenePresence avatar in avatars)
8718 {
8719 remaining = GetPrimParams(avatar, rules, ref res);
8720 }
8721
8722 if (remaining != null && remaining.Length > 0)
8723 {
8724 linknumber = remaining.GetLSLIntegerItem(0);
8725 rules = remaining.GetSublist(1, -1);
8726 }
7990 } 8727 }
7991 8728
7992 return res; 8729 return res;
@@ -8031,13 +8768,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8031 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8768 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8032 part.AbsolutePosition.Y, 8769 part.AbsolutePosition.Y,
8033 part.AbsolutePosition.Z); 8770 part.AbsolutePosition.Z);
8034 // For some reason, the part.AbsolutePosition.* values do not change if the
8035 // linkset is rotated; they always reflect the child prim's world position
8036 // as though the linkset is unrotated. This is incompatible behavior with SL's
8037 // implementation, so will break scripts imported from there (not to mention it
8038 // makes it more difficult to determine a child prim's actual inworld position).
8039 if (part.ParentID != 0)
8040 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8041 res.Add(v); 8771 res.Add(v);
8042 break; 8772 break;
8043 8773
@@ -8209,30 +8939,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8209 if (remain < 1) 8939 if (remain < 1)
8210 return null; 8940 return null;
8211 8941
8212 face=(int)rules.GetLSLIntegerItem(idx++); 8942 face = (int)rules.GetLSLIntegerItem(idx++);
8213 8943
8214 tex = part.Shape.Textures; 8944 tex = part.Shape.Textures;
8945 int shiny;
8215 if (face == ScriptBaseClass.ALL_SIDES) 8946 if (face == ScriptBaseClass.ALL_SIDES)
8216 { 8947 {
8217 for (face = 0; face < GetNumberOfSides(part); face++) 8948 for (face = 0; face < GetNumberOfSides(part); face++)
8218 { 8949 {
8219 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8950 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8220 // Convert Shininess to PRIM_SHINY_* 8951 if (shinyness == Shininess.High)
8221 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8952 {
8222 // PRIM_BUMP_* 8953 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8223 res.Add(new LSL_Integer((int)texface.Bump)); 8954 }
8955 else if (shinyness == Shininess.Medium)
8956 {
8957 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8958 }
8959 else if (shinyness == Shininess.Low)
8960 {
8961 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8962 }
8963 else
8964 {
8965 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8966 }
8967 res.Add(new LSL_Integer(shiny));
8968 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8224 } 8969 }
8225 } 8970 }
8226 else 8971 else
8227 { 8972 {
8228 if (face >= 0 && face < GetNumberOfSides(part)) 8973 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8974 if (shinyness == Shininess.High)
8229 { 8975 {
8230 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8976 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8231 // Convert Shininess to PRIM_SHINY_* 8977 }
8232 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8978 else if (shinyness == Shininess.Medium)
8233 // PRIM_BUMP_* 8979 {
8234 res.Add(new LSL_Integer((int)texface.Bump)); 8980 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8981 }
8982 else if (shinyness == Shininess.Low)
8983 {
8984 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8235 } 8985 }
8986 else
8987 {
8988 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8989 }
8990 res.Add(new LSL_Integer(shiny));
8991 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8236 } 8992 }
8237 break; 8993 break;
8238 8994
@@ -8240,24 +8996,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8240 if (remain < 1) 8996 if (remain < 1)
8241 return null; 8997 return null;
8242 8998
8243 face=(int)rules.GetLSLIntegerItem(idx++); 8999 face = (int)rules.GetLSLIntegerItem(idx++);
8244 9000
8245 tex = part.Shape.Textures; 9001 tex = part.Shape.Textures;
9002 int fullbright;
8246 if (face == ScriptBaseClass.ALL_SIDES) 9003 if (face == ScriptBaseClass.ALL_SIDES)
8247 { 9004 {
8248 for (face = 0; face < GetNumberOfSides(part); face++) 9005 for (face = 0; face < GetNumberOfSides(part); face++)
8249 { 9006 {
8250 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9007 if (tex.GetFace((uint)face).Fullbright == true)
8251 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9008 {
9009 fullbright = ScriptBaseClass.TRUE;
9010 }
9011 else
9012 {
9013 fullbright = ScriptBaseClass.FALSE;
9014 }
9015 res.Add(new LSL_Integer(fullbright));
8252 } 9016 }
8253 } 9017 }
8254 else 9018 else
8255 { 9019 {
8256 if (face >= 0 && face < GetNumberOfSides(part)) 9020 if (tex.GetFace((uint)face).Fullbright == true)
8257 { 9021 {
8258 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9022 fullbright = ScriptBaseClass.TRUE;
8259 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8260 } 9023 }
9024 else
9025 {
9026 fullbright = ScriptBaseClass.FALSE;
9027 }
9028 res.Add(new LSL_Integer(fullbright));
8261 } 9029 }
8262 break; 9030 break;
8263 9031
@@ -8279,27 +9047,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8279 break; 9047 break;
8280 9048
8281 case (int)ScriptBaseClass.PRIM_TEXGEN: 9049 case (int)ScriptBaseClass.PRIM_TEXGEN:
9050 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8282 if (remain < 1) 9051 if (remain < 1)
8283 return null; 9052 return null;
8284 9053
8285 face=(int)rules.GetLSLIntegerItem(idx++); 9054 face = (int)rules.GetLSLIntegerItem(idx++);
8286 9055
8287 tex = part.Shape.Textures; 9056 tex = part.Shape.Textures;
8288 if (face == ScriptBaseClass.ALL_SIDES) 9057 if (face == ScriptBaseClass.ALL_SIDES)
8289 { 9058 {
8290 for (face = 0; face < GetNumberOfSides(part); face++) 9059 for (face = 0; face < GetNumberOfSides(part); face++)
8291 { 9060 {
8292 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9061 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8293 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9062 {
8294 res.Add(new LSL_Integer((uint)texgen >> 1)); 9063 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9064 }
9065 else
9066 {
9067 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9068 }
8295 } 9069 }
8296 } 9070 }
8297 else 9071 else
8298 { 9072 {
8299 if (face >= 0 && face < GetNumberOfSides(part)) 9073 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8300 { 9074 {
8301 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9075 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8302 res.Add(new LSL_Integer((uint)texgen >> 1)); 9076 }
9077 else
9078 {
9079 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8303 } 9080 }
8304 } 9081 }
8305 break; 9082 break;
@@ -8323,24 +9100,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8323 if (remain < 1) 9100 if (remain < 1)
8324 return null; 9101 return null;
8325 9102
8326 face=(int)rules.GetLSLIntegerItem(idx++); 9103 face = (int)rules.GetLSLIntegerItem(idx++);
8327 9104
8328 tex = part.Shape.Textures; 9105 tex = part.Shape.Textures;
9106 float primglow;
8329 if (face == ScriptBaseClass.ALL_SIDES) 9107 if (face == ScriptBaseClass.ALL_SIDES)
8330 { 9108 {
8331 for (face = 0; face < GetNumberOfSides(part); face++) 9109 for (face = 0; face < GetNumberOfSides(part); face++)
8332 { 9110 {
8333 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9111 primglow = tex.GetFace((uint)face).Glow;
8334 res.Add(new LSL_Float(texface.Glow)); 9112 res.Add(new LSL_Float(primglow));
8335 } 9113 }
8336 } 9114 }
8337 else 9115 else
8338 { 9116 {
8339 if (face >= 0 && face < GetNumberOfSides(part)) 9117 primglow = tex.GetFace((uint)face).Glow;
8340 { 9118 res.Add(new LSL_Float(primglow));
8341 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8342 res.Add(new LSL_Float(texface.Glow));
8343 }
8344 } 9119 }
8345 break; 9120 break;
8346 9121
@@ -8352,15 +9127,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8352 textColor.B)); 9127 textColor.B));
8353 res.Add(new LSL_Float(textColor.A)); 9128 res.Add(new LSL_Float(textColor.A));
8354 break; 9129 break;
9130
8355 case (int)ScriptBaseClass.PRIM_NAME: 9131 case (int)ScriptBaseClass.PRIM_NAME:
8356 res.Add(new LSL_String(part.Name)); 9132 res.Add(new LSL_String(part.Name));
8357 break; 9133 break;
9134
8358 case (int)ScriptBaseClass.PRIM_DESC: 9135 case (int)ScriptBaseClass.PRIM_DESC:
8359 res.Add(new LSL_String(part.Description)); 9136 res.Add(new LSL_String(part.Description));
8360 break; 9137 break;
9138
8361 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9139 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8362 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9140 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8363 break; 9141 break;
9142
8364 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9143 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8365 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9144 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8366 break; 9145 break;
@@ -8971,8 +9750,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8971 // The function returns an ordered list 9750 // The function returns an ordered list
8972 // representing the tokens found in the supplied 9751 // representing the tokens found in the supplied
8973 // sources string. If two successive tokenizers 9752 // sources string. If two successive tokenizers
8974 // are encountered, then a NULL entry is added 9753 // are encountered, then a null-string entry is
8975 // to the list. 9754 // added to the list.
8976 // 9755 //
8977 // It is a precondition that the source and 9756 // It is a precondition that the source and
8978 // toekizer lisst are non-null. If they are null, 9757 // toekizer lisst are non-null. If they are null,
@@ -8980,7 +9759,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8980 // while their lengths are being determined. 9759 // while their lengths are being determined.
8981 // 9760 //
8982 // A small amount of working memoryis required 9761 // A small amount of working memoryis required
8983 // of approximately 8*#tokenizers. 9762 // of approximately 8*#tokenizers + 8*srcstrlen.
8984 // 9763 //
8985 // There are many ways in which this function 9764 // There are many ways in which this function
8986 // can be implemented, this implementation is 9765 // can be implemented, this implementation is
@@ -8996,155 +9775,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8996 // and eliminates redundant tokenizers as soon 9775 // and eliminates redundant tokenizers as soon
8997 // as is possible. 9776 // as is possible.
8998 // 9777 //
8999 // The implementation tries to avoid any copying 9778 // The implementation tries to minimize temporary
9000 // of arrays or other objects. 9779 // garbage generation.
9001 // </remarks> 9780 // </remarks>
9002 9781
9003 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9782 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9004 { 9783 {
9005 int beginning = 0; 9784 return ParseString2List(src, separators, spacers, true);
9006 int srclen = src.Length; 9785 }
9007 int seplen = separators.Length;
9008 object[] separray = separators.Data;
9009 int spclen = spacers.Length;
9010 object[] spcarray = spacers.Data;
9011 int mlen = seplen+spclen;
9012
9013 int[] offset = new int[mlen+1];
9014 bool[] active = new bool[mlen];
9015
9016 int best;
9017 int j;
9018
9019 // Initial capacity reduces resize cost
9020 9786
9021 LSL_List tokens = new LSL_List(); 9787 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9788 {
9789 int srclen = src.Length;
9790 int seplen = separators.Length;
9791 object[] separray = separators.Data;
9792 int spclen = spacers.Length;
9793 object[] spcarray = spacers.Data;
9794 int dellen = 0;
9795 string[] delarray = new string[seplen+spclen];
9022 9796
9023 // All entries are initially valid 9797 int outlen = 0;
9798 string[] outarray = new string[srclen*2+1];
9024 9799
9025 for (int i = 0; i < mlen; i++) 9800 int i, j;
9026 active[i] = true; 9801 string d;
9027 9802
9028 offset[mlen] = srclen; 9803 m_host.AddScriptLPS(1);
9029 9804
9030 while (beginning < srclen) 9805 /*
9806 * Convert separator and spacer lists to C# strings.
9807 * Also filter out null strings so we don't hang.
9808 */
9809 for (i = 0; i < seplen; i ++)
9031 { 9810 {
9811 d = separray[i].ToString();
9812 if (d.Length > 0)
9813 {
9814 delarray[dellen++] = d;
9815 }
9816 }
9817 seplen = dellen;
9032 9818
9033 best = mlen; // as bad as it gets 9819 for (i = 0; i < spclen; i ++)
9820 {
9821 d = spcarray[i].ToString();
9822 if (d.Length > 0)
9823 {
9824 delarray[dellen++] = d;
9825 }
9826 }
9034 9827
9035 // Scan for separators 9828 /*
9829 * Scan through source string from beginning to end.
9830 */
9831 for (i = 0;;)
9832 {
9036 9833
9037 for (j = 0; j < seplen; j++) 9834 /*
9835 * Find earliest delimeter in src starting at i (if any).
9836 */
9837 int earliestDel = -1;
9838 int earliestSrc = srclen;
9839 string earliestStr = null;
9840 for (j = 0; j < dellen; j ++)
9038 { 9841 {
9039 if (separray[j].ToString() == String.Empty) 9842 d = delarray[j];
9040 active[j] = false; 9843 if (d != null)
9041
9042 if (active[j])
9043 { 9844 {
9044 // scan all of the markers 9845 int index = src.IndexOf(d, i);
9045 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9846 if (index < 0)
9046 { 9847 {
9047 // not present at all 9848 delarray[j] = null; // delim nowhere in src, don't check it anymore
9048 active[j] = false;
9049 } 9849 }
9050 else 9850 else if (index < earliestSrc)
9051 { 9851 {
9052 // present and correct 9852 earliestSrc = index; // where delimeter starts in source string
9053 if (offset[j] < offset[best]) 9853 earliestDel = j; // where delimeter is in delarray[]
9054 { 9854 earliestStr = d; // the delimeter string from delarray[]
9055 // closest so far 9855 if (index == i) break; // can't do any better than found at beg of string
9056 best = j;
9057 if (offset[best] == beginning)
9058 break;
9059 }
9060 } 9856 }
9061 } 9857 }
9062 } 9858 }
9063 9859
9064 // Scan for spacers 9860 /*
9065 9861 * Output source string starting at i through start of earliest delimeter.
9066 if (offset[best] != beginning) 9862 */
9863 if (keepNulls || (earliestSrc > i))
9067 { 9864 {
9068 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9865 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9069 {
9070 if (spcarray[j-seplen].ToString() == String.Empty)
9071 active[j] = false;
9072
9073 if (active[j])
9074 {
9075 // scan all of the markers
9076 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9077 {
9078 // not present at all
9079 active[j] = false;
9080 }
9081 else
9082 {
9083 // present and correct
9084 if (offset[j] < offset[best])
9085 {
9086 // closest so far
9087 best = j;
9088 }
9089 }
9090 }
9091 }
9092 } 9866 }
9093 9867
9094 // This is the normal exit from the scanning loop 9868 /*
9869 * If no delimeter found at or after i, we're done scanning.
9870 */
9871 if (earliestDel < 0) break;
9095 9872
9096 if (best == mlen) 9873 /*
9874 * If delimeter was a spacer, output the spacer.
9875 */
9876 if (earliestDel >= seplen)
9097 { 9877 {
9098 // no markers were found on this pass 9878 outarray[outlen++] = earliestStr;
9099 // so we're pretty much done
9100 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9101 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9102 break;
9103 } 9879 }
9104 9880
9105 // Otherwise we just add the newly delimited token 9881 /*
9106 // and recalculate where the search should continue. 9882 * Look at rest of src string following delimeter.
9107 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9883 */
9108 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9884 i = earliestSrc + earliestStr.Length;
9109
9110 if (best < seplen)
9111 {
9112 beginning = offset[best] + (separray[best].ToString()).Length;
9113 }
9114 else
9115 {
9116 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9117 string str = spcarray[best - seplen].ToString();
9118 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9119 tokens.Add(new LSL_String(str));
9120 }
9121 } 9885 }
9122 9886
9123 // This an awkward an not very intuitive boundary case. If the 9887 /*
9124 // last substring is a tokenizer, then there is an implied trailing 9888 * Make up an exact-sized output array suitable for an LSL_List object.
9125 // null list entry. Hopefully the single comparison will not be too 9889 */
9126 // arduous. Alternatively the 'break' could be replced with a return 9890 object[] outlist = new object[outlen];
9127 // but that's shabby programming. 9891 for (i = 0; i < outlen; i ++)
9128
9129 if ((beginning == srclen) && (keepNulls))
9130 { 9892 {
9131 if (srclen != 0) 9893 outlist[i] = new LSL_String(outarray[i]);
9132 tokens.Add(new LSL_String(""));
9133 } 9894 }
9134 9895 return new LSL_List(outlist);
9135 return tokens;
9136 }
9137
9138 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9139 {
9140 m_host.AddScriptLPS(1);
9141 return this.ParseString(src, separators, spacers, false);
9142 }
9143
9144 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9145 {
9146 m_host.AddScriptLPS(1);
9147 return this.ParseString(src, separators, spacers, true);
9148 } 9896 }
9149 9897
9150 public LSL_Integer llGetObjectPermMask(int mask) 9898 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9239,6 +9987,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9239 case 4: 9987 case 4:
9240 return (int)item.NextPermissions; 9988 return (int)item.NextPermissions;
9241 } 9989 }
9990 m_host.TaskInventory.LockItemsForRead(false);
9242 9991
9243 return -1; 9992 return -1;
9244 } 9993 }
@@ -9441,31 +10190,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9441 UUID key = new UUID(); 10190 UUID key = new UUID();
9442 if (UUID.TryParse(id, out key)) 10191 if (UUID.TryParse(id, out key))
9443 { 10192 {
9444 try 10193 // return total object mass
9445 { 10194 SceneObjectPart part = World.GetSceneObjectPart(key);
9446 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10195 if (part != null)
9447 if (obj != null) 10196 return part.ParentGroup.GetMass();
9448 return (double)obj.GetMass(); 10197
9449 // the object is null so the key is for an avatar 10198 // the object is null so the key is for an avatar
9450 ScenePresence avatar = World.GetScenePresence(key); 10199 ScenePresence avatar = World.GetScenePresence(key);
9451 if (avatar != null) 10200 if (avatar != null)
9452 if (avatar.IsChildAgent)
9453 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9454 // child agents have a mass of 1.0
9455 return 1;
9456 else
9457 return (double)avatar.GetMass();
9458 }
9459 catch (KeyNotFoundException)
9460 { 10201 {
9461 return 0; // The Object/Agent not in the region so just return zero 10202 if (avatar.IsChildAgent)
10203 {
10204 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10205 // child agents have a mass of 1.0
10206 return 1;
10207 }
10208 else
10209 {
10210 return (double)avatar.GetMass();
10211 }
9462 } 10212 }
9463 } 10213 }
9464 return 0; 10214 return 0;
9465 } 10215 }
9466 10216
9467 /// <summary> 10217 /// <summary>
9468 /// illListReplaceList removes the sub-list defined by the inclusive indices 10218 /// llListReplaceList removes the sub-list defined by the inclusive indices
9469 /// start and end and inserts the src list in its place. The inclusive 10219 /// start and end and inserts the src list in its place. The inclusive
9470 /// nature of the indices means that at least one element must be deleted 10220 /// nature of the indices means that at least one element must be deleted
9471 /// if the indices are within the bounds of the existing list. I.e. 2,2 10221 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9522,16 +10272,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9522 // based upon end. Note that if end exceeds the upper 10272 // based upon end. Note that if end exceeds the upper
9523 // bound in this case, the entire destination list 10273 // bound in this case, the entire destination list
9524 // is removed. 10274 // is removed.
9525 else 10275 else if (start == 0)
9526 { 10276 {
9527 if (end + 1 < dest.Length) 10277 if (end + 1 < dest.Length)
9528 {
9529 return src + dest.GetSublist(end + 1, -1); 10278 return src + dest.GetSublist(end + 1, -1);
9530 }
9531 else 10279 else
9532 {
9533 return src; 10280 return src;
9534 } 10281 }
10282 else // Start < 0
10283 {
10284 if (end + 1 < dest.Length)
10285 return dest.GetSublist(end + 1, -1);
10286 else
10287 return new LSL_List();
9535 } 10288 }
9536 } 10289 }
9537 // Finally, if start > end, we strip away a prefix and 10290 // Finally, if start > end, we strip away a prefix and
@@ -9582,17 +10335,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9582 int width = 0; 10335 int width = 0;
9583 int height = 0; 10336 int height = 0;
9584 10337
9585 ParcelMediaCommandEnum? commandToSend = null; 10338 uint commandToSend = 0;
9586 float time = 0.0f; // default is from start 10339 float time = 0.0f; // default is from start
9587 10340
9588 ScenePresence presence = null; 10341 ScenePresence presence = null;
9589 10342
9590 for (int i = 0; i < commandList.Data.Length; i++) 10343 for (int i = 0; i < commandList.Data.Length; i++)
9591 { 10344 {
9592 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10345 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9593 switch (command) 10346 switch (command)
9594 { 10347 {
9595 case ParcelMediaCommandEnum.Agent: 10348 case (uint)ParcelMediaCommandEnum.Agent:
9596 // we send only to one agent 10349 // we send only to one agent
9597 if ((i + 1) < commandList.Length) 10350 if ((i + 1) < commandList.Length)
9598 { 10351 {
@@ -9609,25 +10362,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9609 } 10362 }
9610 break; 10363 break;
9611 10364
9612 case ParcelMediaCommandEnum.Loop: 10365 case (uint)ParcelMediaCommandEnum.Loop:
9613 loop = 1; 10366 loop = 1;
9614 commandToSend = command; 10367 commandToSend = command;
9615 update = true; //need to send the media update packet to set looping 10368 update = true; //need to send the media update packet to set looping
9616 break; 10369 break;
9617 10370
9618 case ParcelMediaCommandEnum.Play: 10371 case (uint)ParcelMediaCommandEnum.Play:
9619 loop = 0; 10372 loop = 0;
9620 commandToSend = command; 10373 commandToSend = command;
9621 update = true; //need to send the media update packet to make sure it doesn't loop 10374 update = true; //need to send the media update packet to make sure it doesn't loop
9622 break; 10375 break;
9623 10376
9624 case ParcelMediaCommandEnum.Pause: 10377 case (uint)ParcelMediaCommandEnum.Pause:
9625 case ParcelMediaCommandEnum.Stop: 10378 case (uint)ParcelMediaCommandEnum.Stop:
9626 case ParcelMediaCommandEnum.Unload: 10379 case (uint)ParcelMediaCommandEnum.Unload:
9627 commandToSend = command; 10380 commandToSend = command;
9628 break; 10381 break;
9629 10382
9630 case ParcelMediaCommandEnum.Url: 10383 case (uint)ParcelMediaCommandEnum.Url:
9631 if ((i + 1) < commandList.Length) 10384 if ((i + 1) < commandList.Length)
9632 { 10385 {
9633 if (commandList.Data[i + 1] is LSL_String) 10386 if (commandList.Data[i + 1] is LSL_String)
@@ -9640,7 +10393,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9640 } 10393 }
9641 break; 10394 break;
9642 10395
9643 case ParcelMediaCommandEnum.Texture: 10396 case (uint)ParcelMediaCommandEnum.Texture:
9644 if ((i + 1) < commandList.Length) 10397 if ((i + 1) < commandList.Length)
9645 { 10398 {
9646 if (commandList.Data[i + 1] is LSL_String) 10399 if (commandList.Data[i + 1] is LSL_String)
@@ -9653,7 +10406,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9653 } 10406 }
9654 break; 10407 break;
9655 10408
9656 case ParcelMediaCommandEnum.Time: 10409 case (uint)ParcelMediaCommandEnum.Time:
9657 if ((i + 1) < commandList.Length) 10410 if ((i + 1) < commandList.Length)
9658 { 10411 {
9659 if (commandList.Data[i + 1] is LSL_Float) 10412 if (commandList.Data[i + 1] is LSL_Float)
@@ -9665,7 +10418,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9665 } 10418 }
9666 break; 10419 break;
9667 10420
9668 case ParcelMediaCommandEnum.AutoAlign: 10421 case (uint)ParcelMediaCommandEnum.AutoAlign:
9669 if ((i + 1) < commandList.Length) 10422 if ((i + 1) < commandList.Length)
9670 { 10423 {
9671 if (commandList.Data[i + 1] is LSL_Integer) 10424 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9679,7 +10432,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9679 } 10432 }
9680 break; 10433 break;
9681 10434
9682 case ParcelMediaCommandEnum.Type: 10435 case (uint)ParcelMediaCommandEnum.Type:
9683 if ((i + 1) < commandList.Length) 10436 if ((i + 1) < commandList.Length)
9684 { 10437 {
9685 if (commandList.Data[i + 1] is LSL_String) 10438 if (commandList.Data[i + 1] is LSL_String)
@@ -9692,7 +10445,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9692 } 10445 }
9693 break; 10446 break;
9694 10447
9695 case ParcelMediaCommandEnum.Desc: 10448 case (uint)ParcelMediaCommandEnum.Desc:
9696 if ((i + 1) < commandList.Length) 10449 if ((i + 1) < commandList.Length)
9697 { 10450 {
9698 if (commandList.Data[i + 1] is LSL_String) 10451 if (commandList.Data[i + 1] is LSL_String)
@@ -9705,7 +10458,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9705 } 10458 }
9706 break; 10459 break;
9707 10460
9708 case ParcelMediaCommandEnum.Size: 10461 case (uint)ParcelMediaCommandEnum.Size:
9709 if ((i + 2) < commandList.Length) 10462 if ((i + 2) < commandList.Length)
9710 { 10463 {
9711 if (commandList.Data[i + 1] is LSL_Integer) 10464 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9775,7 +10528,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9775 } 10528 }
9776 } 10529 }
9777 10530
9778 if (commandToSend != null) 10531 if (commandToSend != 0)
9779 { 10532 {
9780 // the commandList contained a start/stop/... command, too 10533 // the commandList contained a start/stop/... command, too
9781 if (presence == null) 10534 if (presence == null)
@@ -9812,7 +10565,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9812 10565
9813 if (aList.Data[i] != null) 10566 if (aList.Data[i] != null)
9814 { 10567 {
9815 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10568 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9816 { 10569 {
9817 case ParcelMediaCommandEnum.Url: 10570 case ParcelMediaCommandEnum.Url:
9818 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10571 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9869,15 +10622,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9869 10622
9870 if (quick_pay_buttons.Data.Length < 4) 10623 if (quick_pay_buttons.Data.Length < 4)
9871 { 10624 {
9872 LSLError("List must have at least 4 elements"); 10625 int x;
9873 return; 10626 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10627 {
10628 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10629 }
9874 } 10630 }
9875 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10631 int[] nPrice = new int[5];
9876 10632 nPrice[0] = price;
9877 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10633 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9878 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10634 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9879 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10635 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9880 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10636 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10637 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9881 m_host.ParentGroup.HasGroupChanged = true; 10638 m_host.ParentGroup.HasGroupChanged = true;
9882 } 10639 }
9883 10640
@@ -9894,7 +10651,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9894 return new LSL_Vector(); 10651 return new LSL_Vector();
9895 } 10652 }
9896 10653
9897 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10654// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10655 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9898 if (presence != null) 10656 if (presence != null)
9899 { 10657 {
9900 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10658 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9916,7 +10674,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9916 return new LSL_Rotation(); 10674 return new LSL_Rotation();
9917 } 10675 }
9918 10676
9919 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10677// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10678 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9920 if (presence != null) 10679 if (presence != null)
9921 { 10680 {
9922 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10681 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9976,14 +10735,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9976 { 10735 {
9977 m_host.AddScriptLPS(1); 10736 m_host.AddScriptLPS(1);
9978 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10737 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9979 if (detectedParams == null) return; // only works on the first detected avatar 10738 if (detectedParams == null)
9980 10739 {
10740 if (m_host.ParentGroup.IsAttachment == true)
10741 {
10742 detectedParams = new DetectParams();
10743 detectedParams.Key = m_host.OwnerID;
10744 }
10745 else
10746 {
10747 return;
10748 }
10749 }
10750
9981 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10751 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9982 if (avatar != null) 10752 if (avatar != null)
9983 { 10753 {
9984 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10754 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9985 simname, pos, lookAt); 10755 simname, pos, lookAt);
9986 } 10756 }
10757
9987 ScriptSleep(1000); 10758 ScriptSleep(1000);
9988 } 10759 }
9989 10760
@@ -10107,12 +10878,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10107 10878
10108 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10879 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10109 object[] data = rules.Data; 10880 object[] data = rules.Data;
10110 for (int i = 0; i < data.Length; ++i) { 10881 for (int i = 0; i < data.Length; ++i)
10882 {
10111 int type = Convert.ToInt32(data[i++].ToString()); 10883 int type = Convert.ToInt32(data[i++].ToString());
10112 if (i >= data.Length) break; // odd number of entries => ignore the last 10884 if (i >= data.Length) break; // odd number of entries => ignore the last
10113 10885
10114 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10886 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10115 switch (type) { 10887 switch (type)
10888 {
10116 case ScriptBaseClass.CAMERA_FOCUS: 10889 case ScriptBaseClass.CAMERA_FOCUS:
10117 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10890 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10118 case ScriptBaseClass.CAMERA_POSITION: 10891 case ScriptBaseClass.CAMERA_POSITION:
@@ -10217,19 +10990,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10217 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10990 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10218 { 10991 {
10219 m_host.AddScriptLPS(1); 10992 m_host.AddScriptLPS(1);
10220 string ret = String.Empty; 10993
10221 string src1 = llBase64ToString(str1); 10994 if (str1 == String.Empty)
10222 string src2 = llBase64ToString(str2); 10995 return String.Empty;
10223 int c = 0; 10996 if (str2 == String.Empty)
10224 for (int i = 0; i < src1.Length; i++) 10997 return str1;
10998
10999 int len = str2.Length;
11000 if ((len % 4) != 0) // LL is EVIL!!!!
10225 { 11001 {
10226 ret += (char) (src1[i] ^ src2[c]); 11002 while (str2.EndsWith("="))
11003 str2 = str2.Substring(0, str2.Length - 1);
10227 11004
10228 c++; 11005 len = str2.Length;
10229 if (c >= src2.Length) 11006 int mod = len % 4;
10230 c = 0; 11007
11008 if (mod == 1)
11009 str2 = str2.Substring(0, str2.Length - 1);
11010 else if (mod == 2)
11011 str2 += "==";
11012 else if (mod == 3)
11013 str2 += "=";
10231 } 11014 }
10232 return llStringToBase64(ret); 11015
11016 byte[] data1;
11017 byte[] data2;
11018 try
11019 {
11020 data1 = Convert.FromBase64String(str1);
11021 data2 = Convert.FromBase64String(str2);
11022 }
11023 catch (Exception)
11024 {
11025 return new LSL_String(String.Empty);
11026 }
11027
11028 byte[] d2 = new Byte[data1.Length];
11029 int pos = 0;
11030
11031 if (data1.Length <= data2.Length)
11032 {
11033 Array.Copy(data2, 0, d2, 0, data1.Length);
11034 }
11035 else
11036 {
11037 while (pos < data1.Length)
11038 {
11039 len = data1.Length - pos;
11040 if (len > data2.Length)
11041 len = data2.Length;
11042
11043 Array.Copy(data2, 0, d2, pos, len);
11044 pos += len;
11045 }
11046 }
11047
11048 for (pos = 0 ; pos < data1.Length ; pos++ )
11049 data1[pos] ^= d2[pos];
11050
11051 return Convert.ToBase64String(data1);
10233 } 11052 }
10234 11053
10235 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11054 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10282,16 +11101,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10282 if (userAgent != null) 11101 if (userAgent != null)
10283 httpHeaders["User-Agent"] = userAgent; 11102 httpHeaders["User-Agent"] = userAgent;
10284 11103
11104 // See if the URL contains any header hacks
11105 string[] urlParts = url.Split(new char[] {'\n'});
11106 if (urlParts.Length > 1)
11107 {
11108 // Iterate the passed headers and parse them
11109 for (int i = 1 ; i < urlParts.Length ; i++ )
11110 {
11111 // The rest of those would be added to the body in SL.
11112 // Let's not do that.
11113 if (urlParts[i] == String.Empty)
11114 break;
11115
11116 // See if this could be a valid header
11117 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11118 if (headerParts.Length != 2)
11119 continue;
11120
11121 string headerName = headerParts[0].Trim();
11122 string headerValue = headerParts[1].Trim();
11123
11124 // Filter out headers that could be used to abuse
11125 // another system or cloak the request
11126 if (headerName.ToLower() == "x-secondlife-shard" ||
11127 headerName.ToLower() == "x-secondlife-object-name" ||
11128 headerName.ToLower() == "x-secondlife-object-key" ||
11129 headerName.ToLower() == "x-secondlife-region" ||
11130 headerName.ToLower() == "x-secondlife-local-position" ||
11131 headerName.ToLower() == "x-secondlife-local-velocity" ||
11132 headerName.ToLower() == "x-secondlife-local-rotation" ||
11133 headerName.ToLower() == "x-secondlife-owner-name" ||
11134 headerName.ToLower() == "x-secondlife-owner-key" ||
11135 headerName.ToLower() == "connection" ||
11136 headerName.ToLower() == "content-length" ||
11137 headerName.ToLower() == "from" ||
11138 headerName.ToLower() == "host" ||
11139 headerName.ToLower() == "proxy-authorization" ||
11140 headerName.ToLower() == "referer" ||
11141 headerName.ToLower() == "trailer" ||
11142 headerName.ToLower() == "transfer-encoding" ||
11143 headerName.ToLower() == "via" ||
11144 headerName.ToLower() == "authorization")
11145 continue;
11146
11147 httpHeaders[headerName] = headerValue;
11148 }
11149
11150 // Finally, strip any protocol specifier from the URL
11151 url = urlParts[0].Trim();
11152 int idx = url.IndexOf(" HTTP/");
11153 if (idx != -1)
11154 url = url.Substring(0, idx);
11155 }
11156
10285 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11157 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10286 Regex r = new Regex(authregex); 11158 Regex r = new Regex(authregex);
10287 int[] gnums = r.GetGroupNumbers(); 11159 int[] gnums = r.GetGroupNumbers();
10288 Match m = r.Match(url); 11160 Match m = r.Match(url);
10289 if (m.Success) { 11161 if (m.Success)
10290 for (int i = 1; i < gnums.Length; i++) { 11162 {
11163 for (int i = 1; i < gnums.Length; i++)
11164 {
10291 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11165 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10292 //CaptureCollection cc = g.Captures; 11166 //CaptureCollection cc = g.Captures;
10293 } 11167 }
10294 if (m.Groups.Count == 5) { 11168 if (m.Groups.Count == 5)
11169 {
10295 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11170 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10296 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11171 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10297 } 11172 }
@@ -10494,6 +11369,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10494 11369
10495 LSL_List ret = new LSL_List(); 11370 LSL_List ret = new LSL_List();
10496 UUID key = new UUID(); 11371 UUID key = new UUID();
11372
11373
10497 if (UUID.TryParse(id, out key)) 11374 if (UUID.TryParse(id, out key))
10498 { 11375 {
10499 ScenePresence av = World.GetScenePresence(key); 11376 ScenePresence av = World.GetScenePresence(key);
@@ -10511,13 +11388,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10511 ret.Add(new LSL_String("")); 11388 ret.Add(new LSL_String(""));
10512 break; 11389 break;
10513 case ScriptBaseClass.OBJECT_POS: 11390 case ScriptBaseClass.OBJECT_POS:
10514 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11391 Vector3 avpos;
11392
11393 if (av.ParentID != 0 && av.ParentPart != null)
11394 {
11395 avpos = av.OffsetPosition;
11396
11397 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11398 avpos -= sitOffset;
11399
11400 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11401 }
11402 else
11403 avpos = av.AbsolutePosition;
11404
11405 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10515 break; 11406 break;
10516 case ScriptBaseClass.OBJECT_ROT: 11407 case ScriptBaseClass.OBJECT_ROT:
10517 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11408 Quaternion avrot = av.Rotation;
11409 if (av.ParentID != 0 && av.ParentPart != null)
11410 {
11411 avrot = av.ParentPart.GetWorldRotation() * avrot;
11412 }
11413 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10518 break; 11414 break;
10519 case ScriptBaseClass.OBJECT_VELOCITY: 11415 case ScriptBaseClass.OBJECT_VELOCITY:
10520 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11416 Vector3 avvel = av.Velocity;
11417 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10521 break; 11418 break;
10522 case ScriptBaseClass.OBJECT_OWNER: 11419 case ScriptBaseClass.OBJECT_OWNER:
10523 ret.Add(new LSL_String(id)); 11420 ret.Add(new LSL_String(id));
@@ -10573,11 +11470,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10573 case ScriptBaseClass.OBJECT_NAME: 11470 case ScriptBaseClass.OBJECT_NAME:
10574 ret.Add(new LSL_String(obj.Name)); 11471 ret.Add(new LSL_String(obj.Name));
10575 break; 11472 break;
10576 case ScriptBaseClass.OBJECT_DESC: 11473 case ScriptBaseClass.OBJECT_DESC:
10577 ret.Add(new LSL_String(obj.Description)); 11474 ret.Add(new LSL_String(obj.Description));
10578 break; 11475 break;
10579 case ScriptBaseClass.OBJECT_POS: 11476 case ScriptBaseClass.OBJECT_POS:
10580 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11477 Vector3 opos = obj.AbsolutePosition;
11478 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10581 break; 11479 break;
10582 case ScriptBaseClass.OBJECT_ROT: 11480 case ScriptBaseClass.OBJECT_ROT:
10583 { 11481 {
@@ -10627,9 +11525,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10627 // The value returned in SL for normal prims is prim count 11525 // The value returned in SL for normal prims is prim count
10628 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11526 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10629 break; 11527 break;
10630 // The following 3 costs I have intentionaly coded to return zero. They are part of 11528
10631 // "Land Impact" calculations. These calculations are probably not applicable 11529 // costs below may need to be diferent for root parts, need to check
10632 // to OpenSim and are not yet complete in SL
10633 case ScriptBaseClass.OBJECT_SERVER_COST: 11530 case ScriptBaseClass.OBJECT_SERVER_COST:
10634 // The linden calculation is here 11531 // The linden calculation is here
10635 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11532 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10637,16 +11534,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10637 ret.Add(new LSL_Float(0)); 11534 ret.Add(new LSL_Float(0));
10638 break; 11535 break;
10639 case ScriptBaseClass.OBJECT_STREAMING_COST: 11536 case ScriptBaseClass.OBJECT_STREAMING_COST:
10640 // The linden calculation is here 11537 // The value returned in SL for normal prims is prim count * 0.06
10641 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11538 ret.Add(new LSL_Float(obj.StreamingCost));
10642 // The value returned in SL for normal prims looks like the prim count * 0.06
10643 ret.Add(new LSL_Float(0));
10644 break; 11539 break;
10645 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11540 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10646 // The linden calculation is here 11541 // The value returned in SL for normal prims is prim count
10647 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11542 ret.Add(new LSL_Float(obj.PhysicsCost));
10648 // The value returned in SL for normal prims looks like the prim count
10649 ret.Add(new LSL_Float(0));
10650 break; 11543 break;
10651 default: 11544 default:
10652 // Invalid or unhandled constant. 11545 // Invalid or unhandled constant.
@@ -10857,15 +11750,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10857 return result; 11750 return result;
10858 } 11751 }
10859 11752
10860 public void print(string str) 11753 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10861 { 11754 {
10862 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11755 List<SceneObjectPart> parts = GetLinkParts(link);
10863 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11756 if (parts.Count < 1)
10864 if (ossl != null) 11757 return 0;
10865 { 11758
10866 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11759 return GetNumberOfSides(parts[0]);
10867 m_log.Info("LSL print():" + str);
10868 }
10869 } 11760 }
10870 11761
10871 private string Name2Username(string name) 11762 private string Name2Username(string name)
@@ -10910,7 +11801,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10910 11801
10911 return rq.ToString(); 11802 return rq.ToString();
10912 } 11803 }
10913 11804/*
11805 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11806 {
11807 m_SayShoutCount = 0;
11808 }
11809*/
10914 private struct Tri 11810 private struct Tri
10915 { 11811 {
10916 public Vector3 p1; 11812 public Vector3 p1;
@@ -11050,9 +11946,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11050 11946
11051 ContactResult result = new ContactResult (); 11947 ContactResult result = new ContactResult ();
11052 result.ConsumerID = group.LocalId; 11948 result.ConsumerID = group.LocalId;
11053 result.Depth = intersection.distance; 11949// result.Depth = intersection.distance;
11054 result.Normal = intersection.normal; 11950 result.Normal = intersection.normal;
11055 result.Pos = intersection.ipoint; 11951 result.Pos = intersection.ipoint;
11952 result.Depth = Vector3.Mag(rayStart - result.Pos);
11056 11953
11057 contacts.Add(result); 11954 contacts.Add(result);
11058 }); 11955 });
@@ -11185,6 +12082,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11185 12082
11186 return contacts[0]; 12083 return contacts[0];
11187 } 12084 }
12085/*
12086 // not done:
12087 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12088 {
12089 ContactResult[] contacts = null;
12090 World.ForEachSOG(delegate(SceneObjectGroup group)
12091 {
12092 if (m_host.ParentGroup == group)
12093 return;
12094
12095 if (group.IsAttachment)
12096 return;
12097
12098 if(group.RootPart.PhysActor != null)
12099 return;
12100
12101 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12102 });
12103 return contacts;
12104 }
12105*/
11188 12106
11189 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12107 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11190 { 12108 {
@@ -11226,32 +12144,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11226 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12144 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11227 12145
11228 12146
11229 if (checkTerrain) 12147 if (World.SuportsRayCastFiltered())
11230 { 12148 {
11231 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12149 if (dist == 0)
11232 if (groundContact != null) 12150 return list;
11233 results.Add((ContactResult)groundContact);
11234 }
11235 12151
11236 if (checkAgents) 12152 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11237 { 12153 if (checkTerrain)
11238 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12154 rayfilter |= RayFilterFlags.land;
11239 foreach (ContactResult r in agentHits) 12155// if (checkAgents)
11240 results.Add(r); 12156// rayfilter |= RayFilterFlags.agent;
11241 } 12157 if (checkPhysical)
12158 rayfilter |= RayFilterFlags.physical;
12159 if (checkNonPhysical)
12160 rayfilter |= RayFilterFlags.nonphysical;
12161 if (detectPhantom)
12162 rayfilter |= RayFilterFlags.LSLPhanton;
12163
12164 Vector3 direction = dir * ( 1/dist);
12165
12166 if(rayfilter == 0)
12167 {
12168 list.Add(new LSL_Integer(0));
12169 return list;
12170 }
11242 12171
11243 if (checkPhysical || checkNonPhysical || detectPhantom) 12172 // get some more contacts to sort ???
12173 int physcount = 4 * count;
12174 if (physcount > 20)
12175 physcount = 20;
12176
12177 object physresults;
12178 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12179
12180 if (physresults == null)
12181 {
12182 list.Add(new LSL_Integer(-3)); // timeout error
12183 return list;
12184 }
12185
12186 results = (List<ContactResult>)physresults;
12187
12188 // for now physics doesn't detect sitted avatars so do it outside physics
12189 if (checkAgents)
12190 {
12191 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12192 foreach (ContactResult r in agentHits)
12193 results.Add(r);
12194 }
12195
12196 // TODO: Replace this with a better solution. ObjectIntersection can only
12197 // detect nonphysical phantoms. They are detected by virtue of being
12198 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12199 // physicsl phantoms as done by the physics scene
12200 // We don't want anything else but phantoms here.
12201 if (detectPhantom)
12202 {
12203 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12204 foreach (ContactResult r in objectHits)
12205 results.Add(r);
12206 }
12207 }
12208 else
11244 { 12209 {
11245 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12210 if (checkTerrain)
11246 foreach (ContactResult r in objectHits) 12211 {
11247 results.Add(r); 12212 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12213 if (groundContact != null)
12214 results.Add((ContactResult)groundContact);
12215 }
12216
12217 if (checkAgents)
12218 {
12219 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12220 foreach (ContactResult r in agentHits)
12221 results.Add(r);
12222 }
12223
12224 if (checkPhysical || checkNonPhysical || detectPhantom)
12225 {
12226 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12227 foreach (ContactResult r in objectHits)
12228 results.Add(r);
12229 }
11248 } 12230 }
11249 12231
11250 results.Sort(delegate(ContactResult a, ContactResult b) 12232 results.Sort(delegate(ContactResult a, ContactResult b)
11251 { 12233 {
11252 return a.Depth.CompareTo(b.Depth); 12234 return a.Depth.CompareTo(b.Depth);
11253 }); 12235 });
11254 12236
11255 int values = 0; 12237 int values = 0;
11256 SceneObjectGroup thisgrp = m_host.ParentGroup; 12238 SceneObjectGroup thisgrp = m_host.ParentGroup;
11257 12239
@@ -11344,7 +12326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11344 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12326 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11345 if (!isAccount) return 0; 12327 if (!isAccount) return 0;
11346 if (estate.HasAccess(id)) return 1; 12328 if (estate.HasAccess(id)) return 1;
11347 if (estate.IsBanned(id)) 12329 if (estate.IsBanned(id, World.GetUserFlags(id)))
11348 estate.RemoveBan(id); 12330 estate.RemoveBan(id);
11349 estate.AddEstateUser(id); 12331 estate.AddEstateUser(id);
11350 break; 12332 break;
@@ -11363,14 +12345,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11363 break; 12345 break;
11364 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12346 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11365 if (!isAccount) return 0; 12347 if (!isAccount) return 0;
11366 if (estate.IsBanned(id)) return 1; 12348 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11367 EstateBan ban = new EstateBan(); 12349 EstateBan ban = new EstateBan();
11368 ban.EstateID = estate.EstateID; 12350 ban.EstateID = estate.EstateID;
11369 ban.BannedUserID = id; 12351 ban.BannedUserID = id;
11370 estate.AddBan(ban); 12352 estate.AddBan(ban);
11371 break; 12353 break;
11372 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12354 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11373 if (!isAccount || !estate.IsBanned(id)) return 0; 12355 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11374 estate.RemoveBan(id); 12356 estate.RemoveBan(id);
11375 break; 12357 break;
11376 default: return 0; 12358 default: return 0;
@@ -11399,7 +12381,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11399 return 16384; 12381 return 16384;
11400 } 12382 }
11401 12383
11402 public LSL_Integer llGetUsedMemory() 12384 public virtual LSL_Integer llGetUsedMemory()
11403 { 12385 {
11404 m_host.AddScriptLPS(1); 12386 m_host.AddScriptLPS(1);
11405 // The value returned for LSO scripts in SL 12387 // The value returned for LSO scripts in SL
@@ -11427,22 +12409,731 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11427 public void llSetSoundQueueing(int queue) 12409 public void llSetSoundQueueing(int queue)
11428 { 12410 {
11429 m_host.AddScriptLPS(1); 12411 m_host.AddScriptLPS(1);
11430 NotImplemented("llSetSoundQueueing");
11431 } 12412 }
11432 12413
11433 public void llCollisionSprite(string impact_sprite) 12414 public void llCollisionSprite(string impact_sprite)
11434 { 12415 {
11435 m_host.AddScriptLPS(1); 12416 m_host.AddScriptLPS(1);
11436 NotImplemented("llCollisionSprite"); 12417 // Viewer 2.0 broke this and it's likely LL has no intention
12418 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11437 } 12419 }
11438 12420
11439 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12421 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11440 { 12422 {
11441 m_host.AddScriptLPS(1); 12423 m_host.AddScriptLPS(1);
11442 NotImplemented("llGodLikeRezObject"); 12424
12425 if (!World.Permissions.IsGod(m_host.OwnerID))
12426 NotImplemented("llGodLikeRezObject");
12427
12428 AssetBase rezAsset = World.AssetService.Get(inventory);
12429 if (rezAsset == null)
12430 {
12431 llSay(0, "Asset not found");
12432 return;
12433 }
12434
12435 SceneObjectGroup group = null;
12436
12437 try
12438 {
12439 string xmlData = Utils.BytesToString(rezAsset.Data);
12440 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12441 }
12442 catch
12443 {
12444 llSay(0, "Asset not found");
12445 return;
12446 }
12447
12448 if (group == null)
12449 {
12450 llSay(0, "Asset not found");
12451 return;
12452 }
12453
12454 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12455 group.RootPart.AttachOffset = group.AbsolutePosition;
12456
12457 group.ResetIDs();
12458
12459 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12460 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12461 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12462 group.ScheduleGroupForFullUpdate();
12463
12464 // objects rezzed with this method are die_at_edge by default.
12465 group.RootPart.SetDieAtEdge(true);
12466
12467 group.ResumeScripts();
12468
12469 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12470 "object_rez", new Object[] {
12471 new LSL_String(
12472 group.RootPart.UUID.ToString()) },
12473 new DetectParams[0]));
12474 }
12475
12476 public LSL_String llTransferLindenDollars(string destination, int amount)
12477 {
12478 UUID txn = UUID.Random();
12479
12480 Util.FireAndForget(delegate(object x)
12481 {
12482 int replycode = 0;
12483 string replydata = destination + "," + amount.ToString();
12484
12485 try
12486 {
12487 TaskInventoryItem item = m_item;
12488 if (item == null)
12489 {
12490 replydata = "SERVICE_ERROR";
12491 return;
12492 }
12493
12494 m_host.AddScriptLPS(1);
12495
12496 if (item.PermsGranter == UUID.Zero)
12497 {
12498 replydata = "MISSING_PERMISSION_DEBIT";
12499 return;
12500 }
12501
12502 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12503 {
12504 replydata = "MISSING_PERMISSION_DEBIT";
12505 return;
12506 }
12507
12508 UUID toID = new UUID();
12509
12510 if (!UUID.TryParse(destination, out toID))
12511 {
12512 replydata = "INVALID_AGENT";
12513 return;
12514 }
12515
12516 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12517
12518 if (money == null)
12519 {
12520 replydata = "TRANSFERS_DISABLED";
12521 return;
12522 }
12523
12524 bool result = money.ObjectGiveMoney(
12525 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12526
12527 if (result)
12528 {
12529 replycode = 1;
12530 return;
12531 }
12532
12533 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12534 }
12535 finally
12536 {
12537 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12538 "transaction_result", new Object[] {
12539 new LSL_String(txn.ToString()),
12540 new LSL_Integer(replycode),
12541 new LSL_String(replydata) },
12542 new DetectParams[0]));
12543 }
12544 });
12545
12546 return txn.ToString();
11443 } 12547 }
11444 12548
11445 #endregion 12549 #endregion
12550
12551 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12552 {
12553 SceneObjectGroup group = m_host.ParentGroup;
12554
12555 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12556 return;
12557 if (group.IsAttachment)
12558 return;
12559
12560 if (frames.Data.Length > 0) // We are getting a new motion
12561 {
12562 if (group.RootPart.KeyframeMotion != null)
12563 group.RootPart.KeyframeMotion.Delete();
12564 group.RootPart.KeyframeMotion = null;
12565
12566 int idx = 0;
12567
12568 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12569 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12570
12571 while (idx < options.Data.Length)
12572 {
12573 int option = (int)options.GetLSLIntegerItem(idx++);
12574 int remain = options.Data.Length - idx;
12575
12576 switch (option)
12577 {
12578 case ScriptBaseClass.KFM_MODE:
12579 if (remain < 1)
12580 break;
12581 int modeval = (int)options.GetLSLIntegerItem(idx++);
12582 switch(modeval)
12583 {
12584 case ScriptBaseClass.KFM_FORWARD:
12585 mode = KeyframeMotion.PlayMode.Forward;
12586 break;
12587 case ScriptBaseClass.KFM_REVERSE:
12588 mode = KeyframeMotion.PlayMode.Reverse;
12589 break;
12590 case ScriptBaseClass.KFM_LOOP:
12591 mode = KeyframeMotion.PlayMode.Loop;
12592 break;
12593 case ScriptBaseClass.KFM_PING_PONG:
12594 mode = KeyframeMotion.PlayMode.PingPong;
12595 break;
12596 }
12597 break;
12598 case ScriptBaseClass.KFM_DATA:
12599 if (remain < 1)
12600 break;
12601 int dataval = (int)options.GetLSLIntegerItem(idx++);
12602 data = (KeyframeMotion.DataFormat)dataval;
12603 break;
12604 }
12605 }
12606
12607 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12608
12609 idx = 0;
12610
12611 int elemLength = 2;
12612 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12613 elemLength = 3;
12614
12615 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12616 while (idx < frames.Data.Length)
12617 {
12618 int remain = frames.Data.Length - idx;
12619
12620 if (remain < elemLength)
12621 break;
12622
12623 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12624 frame.Position = null;
12625 frame.Rotation = null;
12626
12627 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12628 {
12629 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12630 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12631 }
12632 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12633 {
12634 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12635 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12636 }
12637
12638 float tempf = (float)frames.GetLSLFloatItem(idx++);
12639 frame.TimeMS = (int)(tempf * 1000.0f);
12640
12641 keyframes.Add(frame);
12642 }
12643
12644 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12645 group.RootPart.KeyframeMotion.Start();
12646 }
12647 else
12648 {
12649 if (group.RootPart.KeyframeMotion == null)
12650 return;
12651
12652 if (options.Data.Length == 0)
12653 {
12654 group.RootPart.KeyframeMotion.Stop();
12655 return;
12656 }
12657
12658 int code = (int)options.GetLSLIntegerItem(0);
12659
12660 int idx = 0;
12661
12662 while (idx < options.Data.Length)
12663 {
12664 int option = (int)options.GetLSLIntegerItem(idx++);
12665 int remain = options.Data.Length - idx;
12666
12667 switch (option)
12668 {
12669 case ScriptBaseClass.KFM_COMMAND:
12670 int cmd = (int)options.GetLSLIntegerItem(idx++);
12671 switch (cmd)
12672 {
12673 case ScriptBaseClass.KFM_CMD_PLAY:
12674 group.RootPart.KeyframeMotion.Start();
12675 break;
12676 case ScriptBaseClass.KFM_CMD_STOP:
12677 group.RootPart.KeyframeMotion.Stop();
12678 break;
12679 case ScriptBaseClass.KFM_CMD_PAUSE:
12680 group.RootPart.KeyframeMotion.Pause();
12681 break;
12682 }
12683 break;
12684 }
12685 }
12686 }
12687 }
12688
12689 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12690 {
12691 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12692
12693 int idx = 0;
12694 int idxStart = 0;
12695
12696 bool positionChanged = false;
12697 Vector3 finalPos = Vector3.Zero;
12698
12699 try
12700 {
12701 while (idx < rules.Length)
12702 {
12703 ++rulesParsed;
12704 int code = rules.GetLSLIntegerItem(idx++);
12705
12706 int remain = rules.Length - idx;
12707 idxStart = idx;
12708
12709 switch (code)
12710 {
12711 case (int)ScriptBaseClass.PRIM_POSITION:
12712 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12713 {
12714 if (remain < 1)
12715 return null;
12716
12717 LSL_Vector v;
12718 v = rules.GetVector3Item(idx++);
12719
12720 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12721 if (part == null)
12722 break;
12723
12724 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12725 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12726 if (part.LinkNum > 1)
12727 {
12728 localRot = GetPartLocalRot(part);
12729 localPos = GetPartLocalPos(part);
12730 }
12731
12732 v -= localPos;
12733 v /= localRot;
12734
12735 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12736
12737 v = v + 2 * sitOffset;
12738
12739 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12740 av.SendAvatarDataToAllAgents();
12741
12742 }
12743 break;
12744
12745 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12746 case (int)ScriptBaseClass.PRIM_ROTATION:
12747 {
12748 if (remain < 1)
12749 return null;
12750
12751 LSL_Rotation r;
12752 r = rules.GetQuaternionItem(idx++);
12753
12754 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12755 if (part == null)
12756 break;
12757
12758 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12759 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12760
12761 if (part.LinkNum > 1)
12762 localRot = GetPartLocalRot(part);
12763
12764 r = r * llGetRootRotation() / localRot;
12765 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12766 av.SendAvatarDataToAllAgents();
12767 }
12768 break;
12769
12770 // parse rest doing nothing but number of parameters error check
12771 case (int)ScriptBaseClass.PRIM_SIZE:
12772 case (int)ScriptBaseClass.PRIM_MATERIAL:
12773 case (int)ScriptBaseClass.PRIM_PHANTOM:
12774 case (int)ScriptBaseClass.PRIM_PHYSICS:
12775 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12776 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12777 case (int)ScriptBaseClass.PRIM_NAME:
12778 case (int)ScriptBaseClass.PRIM_DESC:
12779 if (remain < 1)
12780 return null;
12781 idx++;
12782 break;
12783
12784 case (int)ScriptBaseClass.PRIM_GLOW:
12785 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12786 case (int)ScriptBaseClass.PRIM_TEXGEN:
12787 if (remain < 2)
12788 return null;
12789 idx += 2;
12790 break;
12791
12792 case (int)ScriptBaseClass.PRIM_TYPE:
12793 if (remain < 3)
12794 return null;
12795 code = (int)rules.GetLSLIntegerItem(idx++);
12796 remain = rules.Length - idx;
12797 switch (code)
12798 {
12799 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12800 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12801 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12802 if (remain < 6)
12803 return null;
12804 idx += 6;
12805 break;
12806
12807 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12808 if (remain < 5)
12809 return null;
12810 idx += 5;
12811 break;
12812
12813 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12814 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12815 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12816 if (remain < 11)
12817 return null;
12818 idx += 11;
12819 break;
12820
12821 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12822 if (remain < 2)
12823 return null;
12824 idx += 2;
12825 break;
12826 }
12827 break;
12828
12829 case (int)ScriptBaseClass.PRIM_COLOR:
12830 case (int)ScriptBaseClass.PRIM_TEXT:
12831 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12832 case (int)ScriptBaseClass.PRIM_OMEGA:
12833 if (remain < 3)
12834 return null;
12835 idx += 3;
12836 break;
12837
12838 case (int)ScriptBaseClass.PRIM_TEXTURE:
12839 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12840 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12841 if (remain < 5)
12842 return null;
12843 idx += 5;
12844 break;
12845
12846 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12847 if (remain < 7)
12848 return null;
12849
12850 idx += 7;
12851 break;
12852
12853 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12854 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12855 return null;
12856
12857 return rules.GetSublist(idx, -1);
12858 }
12859 }
12860 }
12861 catch (InvalidCastException e)
12862 {
12863 ShoutError(string.Format(
12864 "{0} error running rule #{1}: arg #{2} ",
12865 originFunc, rulesParsed, idx - idxStart) + e.Message);
12866 }
12867 finally
12868 {
12869 if (positionChanged)
12870 {
12871 av.OffsetPosition = finalPos;
12872// av.SendAvatarDataToAllAgents();
12873 av.SendTerseUpdateToAllClients();
12874 positionChanged = false;
12875 }
12876 }
12877 return null;
12878 }
12879
12880 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12881 {
12882 // avatars case
12883 // replies as SL wiki
12884
12885// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12886 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12887
12888 int idx = 0;
12889 while (idx < rules.Length)
12890 {
12891 int code = (int)rules.GetLSLIntegerItem(idx++);
12892 int remain = rules.Length - idx;
12893
12894 switch (code)
12895 {
12896 case (int)ScriptBaseClass.PRIM_MATERIAL:
12897 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12898 break;
12899
12900 case (int)ScriptBaseClass.PRIM_PHYSICS:
12901 res.Add(new LSL_Integer(0));
12902 break;
12903
12904 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12905 res.Add(new LSL_Integer(0));
12906 break;
12907
12908 case (int)ScriptBaseClass.PRIM_PHANTOM:
12909 res.Add(new LSL_Integer(0));
12910 break;
12911
12912 case (int)ScriptBaseClass.PRIM_POSITION:
12913
12914 Vector3 pos = avatar.OffsetPosition;
12915
12916 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12917 pos -= sitOffset;
12918
12919 if( sitPart != null)
12920 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12921
12922 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12923 break;
12924
12925 case (int)ScriptBaseClass.PRIM_SIZE:
12926 // as in llGetAgentSize above
12927 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12928 break;
12929
12930 case (int)ScriptBaseClass.PRIM_ROTATION:
12931 Quaternion rot = avatar.Rotation;
12932 if (sitPart != null)
12933 {
12934 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12935 }
12936
12937 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12938 break;
12939
12940 case (int)ScriptBaseClass.PRIM_TYPE:
12941 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12942 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12943 res.Add(new LSL_Vector(0f,1.0f,0f));
12944 res.Add(new LSL_Float(0.0f));
12945 res.Add(new LSL_Vector(0, 0, 0));
12946 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12947 res.Add(new LSL_Vector(0, 0, 0));
12948 break;
12949
12950 case (int)ScriptBaseClass.PRIM_TEXTURE:
12951 if (remain < 1)
12952 return null;
12953
12954 int face = (int)rules.GetLSLIntegerItem(idx++);
12955 if (face == ScriptBaseClass.ALL_SIDES)
12956 {
12957 for (face = 0; face < 21; face++)
12958 {
12959 res.Add(new LSL_String(""));
12960 res.Add(new LSL_Vector(0,0,0));
12961 res.Add(new LSL_Vector(0,0,0));
12962 res.Add(new LSL_Float(0.0));
12963 }
12964 }
12965 else
12966 {
12967 if (face >= 0 && face < 21)
12968 {
12969 res.Add(new LSL_String(""));
12970 res.Add(new LSL_Vector(0,0,0));
12971 res.Add(new LSL_Vector(0,0,0));
12972 res.Add(new LSL_Float(0.0));
12973 }
12974 }
12975 break;
12976
12977 case (int)ScriptBaseClass.PRIM_COLOR:
12978 if (remain < 1)
12979 return null;
12980
12981 face = (int)rules.GetLSLIntegerItem(idx++);
12982
12983 if (face == ScriptBaseClass.ALL_SIDES)
12984 {
12985 for (face = 0; face < 21; face++)
12986 {
12987 res.Add(new LSL_Vector(0,0,0));
12988 res.Add(new LSL_Float(0));
12989 }
12990 }
12991 else
12992 {
12993 res.Add(new LSL_Vector(0,0,0));
12994 res.Add(new LSL_Float(0));
12995 }
12996 break;
12997
12998 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12999 if (remain < 1)
13000 return null;
13001 face = (int)rules.GetLSLIntegerItem(idx++);
13002
13003 if (face == ScriptBaseClass.ALL_SIDES)
13004 {
13005 for (face = 0; face < 21; face++)
13006 {
13007 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13008 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13009 }
13010 }
13011 else
13012 {
13013 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13014 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13015 }
13016 break;
13017
13018 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13019 if (remain < 1)
13020 return null;
13021 face = (int)rules.GetLSLIntegerItem(idx++);
13022
13023 if (face == ScriptBaseClass.ALL_SIDES)
13024 {
13025 for (face = 0; face < 21; face++)
13026 {
13027 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13028 }
13029 }
13030 else
13031 {
13032 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13033 }
13034 break;
13035
13036 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13037 res.Add(new LSL_Integer(0));
13038 res.Add(new LSL_Integer(0));// softness
13039 res.Add(new LSL_Float(0.0f)); // gravity
13040 res.Add(new LSL_Float(0.0f)); // friction
13041 res.Add(new LSL_Float(0.0f)); // wind
13042 res.Add(new LSL_Float(0.0f)); // tension
13043 res.Add(new LSL_Vector(0f,0f,0f));
13044 break;
13045
13046 case (int)ScriptBaseClass.PRIM_TEXGEN:
13047 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13048 if (remain < 1)
13049 return null;
13050 face = (int)rules.GetLSLIntegerItem(idx++);
13051
13052 if (face == ScriptBaseClass.ALL_SIDES)
13053 {
13054 for (face = 0; face < 21; face++)
13055 {
13056 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13057 }
13058 }
13059 else
13060 {
13061 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13062 }
13063 break;
13064
13065 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13066 res.Add(new LSL_Integer(0));
13067 res.Add(new LSL_Vector(0f,0f,0f));
13068 res.Add(new LSL_Float(0f)); // intensity
13069 res.Add(new LSL_Float(0f)); // radius
13070 res.Add(new LSL_Float(0f)); // falloff
13071 break;
13072
13073 case (int)ScriptBaseClass.PRIM_GLOW:
13074 if (remain < 1)
13075 return null;
13076 face = (int)rules.GetLSLIntegerItem(idx++);
13077
13078 if (face == ScriptBaseClass.ALL_SIDES)
13079 {
13080 for (face = 0; face < 21; face++)
13081 {
13082 res.Add(new LSL_Float(0f));
13083 }
13084 }
13085 else
13086 {
13087 res.Add(new LSL_Float(0f));
13088 }
13089 break;
13090
13091 case (int)ScriptBaseClass.PRIM_TEXT:
13092 res.Add(new LSL_String(""));
13093 res.Add(new LSL_Vector(0f,0f,0f));
13094 res.Add(new LSL_Float(1.0f));
13095 break;
13096
13097 case (int)ScriptBaseClass.PRIM_NAME:
13098 res.Add(new LSL_String(avatar.Name));
13099 break;
13100
13101 case (int)ScriptBaseClass.PRIM_DESC:
13102 res.Add(new LSL_String(""));
13103 break;
13104
13105 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13106 Quaternion lrot = avatar.Rotation;
13107
13108 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13109 {
13110 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13111 }
13112 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13113 break;
13114
13115 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13116 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13117 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13118 lpos -= lsitOffset;
13119
13120 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13121 {
13122 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13123 }
13124 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13125 break;
13126
13127 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13128 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13129 return null;
13130
13131 return rules.GetSublist(idx, -1);
13132 }
13133 }
13134
13135 return null;
13136 }
11446 } 13137 }
11447 13138
11448 public class NotecardCache 13139 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 828288d..51c8c7e 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 ScriptException("OSSL Runtime Error: " + msg); 215 if (m_debuggerSafe)
216 {
217 OSSLShoutError(msg);
218 }
219 else
220 {
221 throw new ScriptException("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);
@@ -1814,6 +1823,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1814 1823
1815 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1824 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1816 { 1825 {
1826 m_host.TaskInventory.LockItemsForRead(true);
1817 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1827 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1818 { 1828 {
1819 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1829 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1821,6 +1831,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1821 assetID = item.AssetID; 1831 assetID = item.AssetID;
1822 } 1832 }
1823 } 1833 }
1834 m_host.TaskInventory.LockItemsForRead(false);
1824 } 1835 }
1825 1836
1826 if (assetID == UUID.Zero) 1837 if (assetID == UUID.Zero)
@@ -2306,7 +2317,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2306 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2317 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2307 m_host.AddScriptLPS(1); 2318 m_host.AddScriptLPS(1);
2308 2319
2309 return NpcCreate(firstname, lastname, position, notecard, false, false); 2320 return NpcCreate(firstname, lastname, position, notecard, true, false);
2310 } 2321 }
2311 2322
2312 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2323 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2317,24 +2328,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2317 return NpcCreate( 2328 return NpcCreate(
2318 firstname, lastname, position, notecard, 2329 firstname, lastname, position, notecard,
2319 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2330 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2320 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2331 false);
2332// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2321 } 2333 }
2322 2334
2323 private LSL_Key NpcCreate( 2335 private LSL_Key NpcCreate(
2324 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2336 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2325 { 2337 {
2338 if (!owned)
2339 OSSLError("Unowned NPCs are unsupported");
2340
2341 string groupTitle = String.Empty;
2342
2343 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2344 return new LSL_Key(UUID.Zero.ToString());
2345
2346 if (firstname != String.Empty || lastname != String.Empty)
2347 {
2348 if (firstname != "Shown outfit:")
2349 groupTitle = "- NPC -";
2350 }
2351
2326 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2352 INPCModule module = World.RequestModuleInterface<INPCModule>();
2327 if (module != null) 2353 if (module != null)
2328 { 2354 {
2329 AvatarAppearance appearance = null; 2355 AvatarAppearance appearance = null;
2330 2356
2331 UUID id; 2357// UUID id;
2332 if (UUID.TryParse(notecard, out id)) 2358// if (UUID.TryParse(notecard, out id))
2333 { 2359// {
2334 ScenePresence clonePresence = World.GetScenePresence(id); 2360// ScenePresence clonePresence = World.GetScenePresence(id);
2335 if (clonePresence != null) 2361// if (clonePresence != null)
2336 appearance = clonePresence.Appearance; 2362// appearance = clonePresence.Appearance;
2337 } 2363// }
2338 2364
2339 if (appearance == null) 2365 if (appearance == null)
2340 { 2366 {
@@ -2342,9 +2368,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2342 2368
2343 if (appearanceSerialized != null) 2369 if (appearanceSerialized != null)
2344 { 2370 {
2345 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2371 try
2346 appearance = new AvatarAppearance(); 2372 {
2347 appearance.Unpack(appearanceOsd); 2373 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2374 appearance = new AvatarAppearance();
2375 appearance.Unpack(appearanceOsd);
2376 }
2377 catch
2378 {
2379 return UUID.Zero.ToString();
2380 }
2348 } 2381 }
2349 else 2382 else
2350 { 2383 {
@@ -2363,6 +2396,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2363 World, 2396 World,
2364 appearance); 2397 appearance);
2365 2398
2399 ScenePresence sp;
2400 if (World.TryGetScenePresence(x, out sp))
2401 {
2402 sp.Grouptitle = groupTitle;
2403 sp.SendAvatarDataToAllAgents();
2404 }
2366 return new LSL_Key(x.ToString()); 2405 return new LSL_Key(x.ToString());
2367 } 2406 }
2368 2407
@@ -2666,16 +2705,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2666 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2705 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2667 m_host.AddScriptLPS(1); 2706 m_host.AddScriptLPS(1);
2668 2707
2669 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2708 ManualResetEvent ev = new ManualResetEvent(false);
2670 if (module != null)
2671 {
2672 UUID npcId = new UUID(npc.m_string);
2673 2709
2674 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2710 Util.FireAndForget(delegate(object x) {
2675 return; 2711 try
2712 {
2713 INPCModule module = World.RequestModuleInterface<INPCModule>();
2714 if (module != null)
2715 {
2716 UUID npcId = new UUID(npc.m_string);
2676 2717
2677 module.DeleteNPC(npcId, World); 2718 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2678 } 2719 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2720 {
2721 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2722 return;
2723 }
2724
2725 module.DeleteNPC(npcId, World);
2726 }
2727 }
2728 finally
2729 {
2730 ev.Set();
2731 }
2732 });
2733 ev.WaitOne();
2679 } 2734 }
2680 2735
2681 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2736 public void osNpcPlayAnimation(LSL_Key npc, string animation)
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 cdd9ea8..c447d1f 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 880841b..0dd5a57 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;
@@ -643,6 +644,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
643 public const int PRIM_MEDIA_PERM_OWNER = 1; 644 public const int PRIM_MEDIA_PERM_OWNER = 1;
644 public const int PRIM_MEDIA_PERM_GROUP = 2; 645 public const int PRIM_MEDIA_PERM_GROUP = 2;
645 public const int PRIM_MEDIA_PERM_ANYONE = 4; 646 public const int PRIM_MEDIA_PERM_ANYONE = 4;
647
648 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
649 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
650 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
651 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
652
653 public const int PRIM_PHYSICS_MATERIAL = 31;
654 public const int DENSITY = 1;
655 public const int FRICTION = 2;
656 public const int RESTITUTION = 4;
657 public const int GRAVITY_MULTIPLIER = 8;
646 658
647 // extra constants for llSetPrimMediaParams 659 // extra constants for llSetPrimMediaParams
648 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 660 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -715,7 +727,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
715 727
716 public static readonly LSLInteger RCERR_UNKNOWN = -1; 728 public static readonly LSLInteger RCERR_UNKNOWN = -1;
717 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 729 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
718 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 730 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
731
732 public const int KFM_MODE = 1;
733 public const int KFM_LOOP = 1;
734 public const int KFM_REVERSE = 3;
735 public const int KFM_FORWARD = 0;
736 public const int KFM_PING_PONG = 2;
737 public const int KFM_DATA = 2;
738 public const int KFM_TRANSLATION = 2;
739 public const int KFM_ROTATION = 1;
740 public const int KFM_COMMAND = 0;
741 public const int KFM_CMD_PLAY = 0;
742 public const int KFM_CMD_STOP = 1;
743 public const int KFM_CMD_PAUSE = 2;
719 744
720 /// <summary> 745 /// <summary>
721 /// process name parameter as regex 746 /// process name parameter as regex
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 {