aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3163
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs105
-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, 3215 insertions, 1024 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 be22cb4..efeca26 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,14 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -103,15 +107,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
103 protected int m_notecardLineReadCharsMax = 255; 107 protected int m_notecardLineReadCharsMax = 255;
104 protected int m_scriptConsoleChannel = 0; 108 protected int m_scriptConsoleChannel = 0;
105 protected bool m_scriptConsoleChannelEnabled = false; 109 protected bool m_scriptConsoleChannelEnabled = false;
110 protected bool m_debuggerSafe = false;
106 protected IUrlModule m_UrlModule = null; 111 protected IUrlModule m_UrlModule = null;
107 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 112 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
108 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 113 new Dictionary<UUID, UserInfoCacheEntry>();
114 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
115
116// protected Timer m_ShoutSayTimer;
117 protected int m_SayShoutCount = 0;
118 DateTime m_lastSayShoutCheck;
119
120 private Dictionary<string, string> MovementAnimationsForLSL =
121 new Dictionary<string, string> {
122 {"FLY", "Flying"},
123 {"FLYSLOW", "FlyingSlow"},
124 {"HOVER_UP", "Hovering Up"},
125 {"HOVER_DOWN", "Hovering Down"},
126 {"HOVER", "Hovering"},
127 {"LAND", "Landing"},
128 {"FALLDOWN", "Falling Down"},
129 {"PREJUMP", "PreJumping"},
130 {"JUMP", "Jumping"},
131 {"STANDUP", "Standing Up"},
132 {"SOFT_LAND", "Soft Landing"},
133 {"STAND", "Standing"},
134 {"CROUCHWALK", "CrouchWalking"},
135 {"RUN", "Running"},
136 {"WALK", "Walking"},
137 {"CROUCH", "Crouching"},
138 {"TURNLEFT", "Turning Left"},
139 {"TURNRIGHT", "Turning Right"}
140 };
109 141
110 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
111 { 143 {
144/*
145 m_ShoutSayTimer = new Timer(1000);
146 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
147 m_ShoutSayTimer.AutoReset = true;
148 m_ShoutSayTimer.Start();
149*/
150 m_lastSayShoutCheck = DateTime.UtcNow;
151
112 m_ScriptEngine = ScriptEngine; 152 m_ScriptEngine = ScriptEngine;
113 m_host = host; 153 m_host = host;
114 m_item = item; 154 m_item = item;
155 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
115 156
116 LoadLimits(); // read script limits from config. 157 LoadLimits(); // read script limits from config.
117 158
@@ -171,6 +212,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
171 get { return m_ScriptEngine.World; } 212 get { return m_ScriptEngine.World; }
172 } 213 }
173 214
215 [DebuggerNonUserCode]
174 public void state(string newState) 216 public void state(string newState)
175 { 217 {
176 m_ScriptEngine.SetState(m_item.ItemID, newState); 218 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -180,6 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
180 /// Reset the named script. The script must be present 222 /// Reset the named script. The script must be present
181 /// in the same prim. 223 /// in the same prim.
182 /// </summary> 224 /// </summary>
225 [DebuggerNonUserCode]
183 public void llResetScript() 226 public void llResetScript()
184 { 227 {
185 m_host.AddScriptLPS(1); 228 m_host.AddScriptLPS(1);
@@ -242,6 +285,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
242 } 285 }
243 } 286 }
244 287
288 public List<ScenePresence> GetLinkAvatars(int linkType)
289 {
290 List<ScenePresence> ret = new List<ScenePresence>();
291 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
292 return ret;
293
294 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
295
296 switch (linkType)
297 {
298 case ScriptBaseClass.LINK_SET:
299 return avs;
300
301 case ScriptBaseClass.LINK_ROOT:
302 return ret;
303
304 case ScriptBaseClass.LINK_ALL_OTHERS:
305 return avs;
306
307 case ScriptBaseClass.LINK_ALL_CHILDREN:
308 return avs;
309
310 case ScriptBaseClass.LINK_THIS:
311 return ret;
312
313 default:
314 if (linkType < 0)
315 return ret;
316
317 int partCount = m_host.ParentGroup.GetPartCount();
318
319 if (linkType <= partCount)
320 {
321 return ret;
322 }
323 else
324 {
325 linkType = linkType - partCount;
326 if (linkType > avs.Count)
327 {
328 return ret;
329 }
330 else
331 {
332 ret.Add(avs[linkType-1]);
333 return ret;
334 }
335 }
336 }
337 }
338
245 public List<SceneObjectPart> GetLinkParts(int linkType) 339 public List<SceneObjectPart> GetLinkParts(int linkType)
246 { 340 {
247 return GetLinkParts(m_host, linkType); 341 return GetLinkParts(m_host, linkType);
@@ -250,6 +344,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
250 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 344 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
251 { 345 {
252 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 346 List<SceneObjectPart> ret = new List<SceneObjectPart>();
347 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
348 return ret;
253 ret.Add(part); 349 ret.Add(part);
254 350
255 switch (linkType) 351 switch (linkType)
@@ -440,31 +536,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
440 536
441 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 537 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
442 538
443 /// <summary> 539 // Utility function for llRot2Euler
444 /// Convert an LSL rotation to a Euler vector. 540
445 /// </summary> 541 // normalize an angle between -PI and PI (-180 to +180 degrees)
446 /// <remarks> 542 protected double NormalizeAngle(double angle)
447 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
448 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
449 /// </remarks>
450 /// <param name="r"></param>
451 /// <returns></returns>
452 public LSL_Vector llRot2Euler(LSL_Rotation r)
453 { 543 {
454 m_host.AddScriptLPS(1); 544 if (angle > -Math.PI && angle < Math.PI)
545 return angle;
455 546
456 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 547 int numPis = (int)(Math.PI / angle);
457 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 548 double remainder = angle - Math.PI * numPis;
458 if (m == 0.0) return new LSL_Vector(); 549 if (numPis % 2 == 1)
459 double x = Math.Atan2(-v.y, v.z); 550 return Math.PI - angle;
460 double sin = v.x / m; 551 return remainder;
461 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 552 }
462 double y = Math.Asin(sin);
463 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
464 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)));
465 double z = Math.Atan2(v.y, v.x);
466 553
467 return new LSL_Vector(x, y, z); 554 public LSL_Vector llRot2Euler(LSL_Rotation q1)
555 {
556 m_host.AddScriptLPS(1);
557 LSL_Vector eul = new LSL_Vector();
558
559 double sqw = q1.s*q1.s;
560 double sqx = q1.x*q1.x;
561 double sqy = q1.z*q1.z;
562 double sqz = q1.y*q1.y;
563 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
564 double test = q1.x*q1.z + q1.y*q1.s;
565 if (test > 0.4999*unit) { // singularity at north pole
566 eul.z = 2 * Math.Atan2(q1.x,q1.s);
567 eul.y = Math.PI/2;
568 eul.x = 0;
569 return eul;
570 }
571 if (test < -0.4999*unit) { // singularity at south pole
572 eul.z = -2 * Math.Atan2(q1.x,q1.s);
573 eul.y = -Math.PI/2;
574 eul.x = 0;
575 return eul;
576 }
577 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
578 eul.y = Math.Asin(2*test/unit);
579 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
580 return eul;
468 } 581 }
469 582
470 /* From wiki: 583 /* From wiki:
@@ -517,18 +630,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
517 m_host.AddScriptLPS(1); 630 m_host.AddScriptLPS(1);
518 631
519 double x,y,z,s; 632 double x,y,z,s;
520 633 v.x *= 0.5;
521 double c1 = Math.Cos(v.x * 0.5); 634 v.y *= 0.5;
522 double c2 = Math.Cos(v.y * 0.5); 635 v.z *= 0.5;
523 double c3 = Math.Cos(v.z * 0.5); 636 double c1 = Math.Cos(v.x);
524 double s1 = Math.Sin(v.x * 0.5); 637 double c2 = Math.Cos(v.y);
525 double s2 = Math.Sin(v.y * 0.5); 638 double c1c2 = c1 * c2;
526 double s3 = Math.Sin(v.z * 0.5); 639 double s1 = Math.Sin(v.x);
527 640 double s2 = Math.Sin(v.y);
528 x = s1 * c2 * c3 + c1 * s2 * s3; 641 double s1s2 = s1 * s2;
529 y = c1 * s2 * c3 - s1 * c2 * s3; 642 double c1s2 = c1 * s2;
530 z = s1 * s2 * c3 + c1 * c2 * s3; 643 double s1c2 = s1 * c2;
531 s = c1 * c2 * c3 - s1 * s2 * s3; 644 double c3 = Math.Cos(v.z);
645 double s3 = Math.Sin(v.z);
646
647 x = s1c2 * c3 + c1s2 * s3;
648 y = c1s2 * c3 - s1c2 * s3;
649 z = s1s2 * c3 + c1c2 * s3;
650 s = c1c2 * c3 - s1s2 * s3;
532 651
533 return new LSL_Rotation(x, y, z, s); 652 return new LSL_Rotation(x, y, z, s);
534 } 653 }
@@ -666,77 +785,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
666 { 785 {
667 //A and B should both be normalized 786 //A and B should both be normalized
668 m_host.AddScriptLPS(1); 787 m_host.AddScriptLPS(1);
669 LSL_Rotation rotBetween; 788 /* This method is more accurate than the SL one, and thus causes problems
670 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 789 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
671 // continue calculation. 790
672 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 791 double dotProduct = LSL_Vector.Dot(a, b);
792 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
793 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
794 double angle = Math.Acos(dotProduct / magProduct);
795 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
796 double s = Math.Sin(angle / 2);
797
798 double x = axis.x * s;
799 double y = axis.y * s;
800 double z = axis.z * s;
801 double w = Math.Cos(angle / 2);
802
803 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
804 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
805
806 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
807 */
808
809 // This method mimics the 180 errors found in SL
810 // See www.euclideanspace.com... angleBetween
811 LSL_Vector vec_a = a;
812 LSL_Vector vec_b = b;
813
814 // Eliminate zero length
815 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
816 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
817 if (vec_a_mag < 0.00001 ||
818 vec_b_mag < 0.00001)
673 { 819 {
674 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 820 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
675 } 821 }
676 else 822
823 // Normalize
824 vec_a = llVecNorm(vec_a);
825 vec_b = llVecNorm(vec_b);
826
827 // Calculate axis and rotation angle
828 LSL_Vector axis = vec_a % vec_b;
829 LSL_Float cos_theta = vec_a * vec_b;
830
831 // Check if parallel
832 if (cos_theta > 0.99999)
677 { 833 {
678 a = LSL_Vector.Norm(a); 834 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
679 b = LSL_Vector.Norm(b); 835 }
680 double dotProduct = LSL_Vector.Dot(a, b); 836
681 // There are two degenerate cases possible. These are for vectors 180 or 837 // Check if anti-parallel
682 // 0 degrees apart. These have to be detected and handled individually. 838 else if (cos_theta < -0.99999)
683 // 839 {
684 // Check for vectors 180 degrees apart. 840 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
685 // A dot product of -1 would mean the angle between vectors is 180 degrees. 841 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
686 if (dotProduct < -0.9999999f) 842 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
687 { 843 }
688 // First assume X axis is orthogonal to the vectors. 844 else // other rotation
689 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 845 {
690 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 846 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
691 // Check for near zero vector. A very small non-zero number here will create 847 axis = llVecNorm(axis);
692 // a rotation in an undesired direction. 848 double x, y, z, s, t;
693 if (LSL_Vector.Mag(orthoVector) > 0.0001) 849 s = Math.Cos(theta);
694 { 850 t = Math.Sin(theta);
695 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 851 x = axis.x * t;
696 } 852 y = axis.y * t;
697 // If the magnitude of the vector was near zero, then assume the X axis is not 853 z = axis.z * t;
698 // orthogonal and use the Z axis instead. 854 return new LSL_Rotation(x,y,z,s);
699 else
700 {
701 // Set 180 z rotation.
702 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
703 }
704 }
705 // Check for parallel vectors.
706 // A dot product of 1 would mean the angle between vectors is 0 degrees.
707 else if (dotProduct > 0.9999999f)
708 {
709 // Set zero rotation.
710 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
711 }
712 else
713 {
714 // All special checks have been performed so get the axis of rotation.
715 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
716 // Quarternion s value is the length of the unit vector + dot product.
717 double qs = 1.0 + dotProduct;
718 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
719 // Normalize the rotation.
720 double mag = LSL_Rotation.Mag(rotBetween);
721 // We shouldn't have to worry about a divide by zero here. The qs value will be
722 // non-zero because we already know if we're here, then the dotProduct is not -1 so
723 // qs will not be zero. Also, we've already handled the input vectors being zero so the
724 // crossProduct vector should also not be zero.
725 rotBetween.x = rotBetween.x / mag;
726 rotBetween.y = rotBetween.y / mag;
727 rotBetween.z = rotBetween.z / mag;
728 rotBetween.s = rotBetween.s / mag;
729 // Check for undefined values and set zero rotation if any found. This code might not actually be required
730 // any longer since zero vectors are checked for at the top.
731 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
732 {
733 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
734 }
735 }
736 } 855 }
737 return rotBetween;
738 } 856 }
739 857
740 public void llWhisper(int channelID, string text) 858 public void llWhisper(int channelID, string text)
741 { 859 {
742 m_host.AddScriptLPS(1); 860 m_host.AddScriptLPS(1);
@@ -752,10 +870,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
752 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 870 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
753 } 871 }
754 872
873 private void CheckSayShoutTime()
874 {
875 DateTime now = DateTime.UtcNow;
876 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
877 {
878 m_lastSayShoutCheck = now;
879 m_SayShoutCount = 0;
880 }
881 else
882 m_SayShoutCount++;
883 }
884
755 public void llSay(int channelID, string text) 885 public void llSay(int channelID, string text)
756 { 886 {
757 m_host.AddScriptLPS(1); 887 m_host.AddScriptLPS(1);
758 888
889 if (channelID == 0)
890// m_SayShoutCount++;
891 CheckSayShoutTime();
892
893 if (m_SayShoutCount >= 11)
894 ScriptSleep(2000);
895
759 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 896 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
760 { 897 {
761 Console.WriteLine(text); 898 Console.WriteLine(text);
@@ -778,6 +915,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
778 { 915 {
779 m_host.AddScriptLPS(1); 916 m_host.AddScriptLPS(1);
780 917
918 if (channelID == 0)
919// m_SayShoutCount++;
920 CheckSayShoutTime();
921
922 if (m_SayShoutCount >= 11)
923 ScriptSleep(2000);
924
781 if (text.Length > 1023) 925 if (text.Length > 1023)
782 text = text.Substring(0, 1023); 926 text = text.Substring(0, 1023);
783 927
@@ -809,22 +953,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
809 953
810 public void llRegionSayTo(string target, int channel, string msg) 954 public void llRegionSayTo(string target, int channel, string msg)
811 { 955 {
956 string error = String.Empty;
957
812 if (msg.Length > 1023) 958 if (msg.Length > 1023)
813 msg = msg.Substring(0, 1023); 959 msg = msg.Substring(0, 1023);
814 960
815 m_host.AddScriptLPS(1); 961 m_host.AddScriptLPS(1);
816 962
817 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
818 {
819 return;
820 }
821
822 UUID TargetID; 963 UUID TargetID;
823 UUID.TryParse(target, out TargetID); 964 UUID.TryParse(target, out TargetID);
824 965
825 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 966 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
826 if (wComm != null) 967 if (wComm != null)
827 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 968 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
969 LSLError(error);
828 } 970 }
829 971
830 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 972 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1080,10 +1222,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1080 return detectedParams.TouchUV; 1222 return detectedParams.TouchUV;
1081 } 1223 }
1082 1224
1225 [DebuggerNonUserCode]
1083 public virtual void llDie() 1226 public virtual void llDie()
1084 { 1227 {
1085 m_host.AddScriptLPS(1); 1228 m_host.AddScriptLPS(1);
1086 throw new SelfDeleteException(); 1229 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1087 } 1230 }
1088 1231
1089 public LSL_Float llGround(LSL_Vector offset) 1232 public LSL_Float llGround(LSL_Vector offset)
@@ -1154,6 +1297,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1154 1297
1155 public void llSetStatus(int status, int value) 1298 public void llSetStatus(int status, int value)
1156 { 1299 {
1300 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1301 return;
1157 m_host.AddScriptLPS(1); 1302 m_host.AddScriptLPS(1);
1158 1303
1159 int statusrotationaxis = 0; 1304 int statusrotationaxis = 0;
@@ -1177,6 +1322,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 if (!allow) 1322 if (!allow)
1178 return; 1323 return;
1179 1324
1325 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1326 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1327 return;
1328
1180 m_host.ScriptSetPhysicsStatus(true); 1329 m_host.ScriptSetPhysicsStatus(true);
1181 } 1330 }
1182 else 1331 else
@@ -1376,6 +1525,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1376 { 1525 {
1377 m_host.AddScriptLPS(1); 1526 m_host.AddScriptLPS(1);
1378 1527
1528 SetColor(m_host, color, face);
1529 }
1530
1531 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1532 {
1533 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1534 return;
1535
1536 Primitive.TextureEntry tex = part.Shape.Textures;
1537 Color4 texcolor;
1538 if (face >= 0 && face < GetNumberOfSides(part))
1539 {
1540 texcolor = tex.CreateFace((uint)face).RGBA;
1541 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1542 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1543 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1544 tex.FaceTextures[face].RGBA = texcolor;
1545 part.UpdateTextureEntry(tex.GetBytes());
1546 return;
1547 }
1548 else if (face == ScriptBaseClass.ALL_SIDES)
1549 {
1550 for (uint i = 0; i < GetNumberOfSides(part); i++)
1551 {
1552 if (tex.FaceTextures[i] != null)
1553 {
1554 texcolor = tex.FaceTextures[i].RGBA;
1555 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1556 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1557 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1558 tex.FaceTextures[i].RGBA = texcolor;
1559 }
1560 texcolor = tex.DefaultTexture.RGBA;
1561 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1562 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1563 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1564 tex.DefaultTexture.RGBA = texcolor;
1565 }
1566 part.UpdateTextureEntry(tex.GetBytes());
1567 return;
1568 }
1569
1379 if (face == ScriptBaseClass.ALL_SIDES) 1570 if (face == ScriptBaseClass.ALL_SIDES)
1380 face = SceneObjectPart.ALL_SIDES; 1571 face = SceneObjectPart.ALL_SIDES;
1381 1572
@@ -1384,6 +1575,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1384 1575
1385 public void SetTexGen(SceneObjectPart part, int face,int style) 1576 public void SetTexGen(SceneObjectPart part, int face,int style)
1386 { 1577 {
1578 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1579 return;
1580
1387 Primitive.TextureEntry tex = part.Shape.Textures; 1581 Primitive.TextureEntry tex = part.Shape.Textures;
1388 MappingType textype; 1582 MappingType textype;
1389 textype = MappingType.Default; 1583 textype = MappingType.Default;
@@ -1414,6 +1608,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1414 1608
1415 public void SetGlow(SceneObjectPart part, int face, float glow) 1609 public void SetGlow(SceneObjectPart part, int face, float glow)
1416 { 1610 {
1611 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1612 return;
1613
1417 Primitive.TextureEntry tex = part.Shape.Textures; 1614 Primitive.TextureEntry tex = part.Shape.Textures;
1418 if (face >= 0 && face < GetNumberOfSides(part)) 1615 if (face >= 0 && face < GetNumberOfSides(part))
1419 { 1616 {
@@ -1439,6 +1636,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1439 1636
1440 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1637 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1441 { 1638 {
1639 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1640 return;
1442 1641
1443 Shininess sval = new Shininess(); 1642 Shininess sval = new Shininess();
1444 1643
@@ -1489,6 +1688,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1489 1688
1490 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1689 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1491 { 1690 {
1691 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1692 return;
1693
1492 Primitive.TextureEntry tex = part.Shape.Textures; 1694 Primitive.TextureEntry tex = part.Shape.Textures;
1493 if (face >= 0 && face < GetNumberOfSides(part)) 1695 if (face >= 0 && face < GetNumberOfSides(part))
1494 { 1696 {
@@ -1549,13 +1751,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1549 m_host.AddScriptLPS(1); 1751 m_host.AddScriptLPS(1);
1550 1752
1551 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1753 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1552 1754 if (parts.Count > 0)
1553 foreach (SceneObjectPart part in parts) 1755 {
1554 SetAlpha(part, alpha, face); 1756 try
1757 {
1758 foreach (SceneObjectPart part in parts)
1759 SetAlpha(part, alpha, face);
1760 }
1761 finally
1762 {
1763 }
1764 }
1555 } 1765 }
1556 1766
1557 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1767 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1558 { 1768 {
1769 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1770 return;
1771
1559 Primitive.TextureEntry tex = part.Shape.Textures; 1772 Primitive.TextureEntry tex = part.Shape.Textures;
1560 Color4 texcolor; 1773 Color4 texcolor;
1561 if (face >= 0 && face < GetNumberOfSides(part)) 1774 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1608,7 +1821,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1608 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1821 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1609 float wind, float tension, LSL_Vector Force) 1822 float wind, float tension, LSL_Vector Force)
1610 { 1823 {
1611 if (part == null) 1824 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1612 return; 1825 return;
1613 1826
1614 if (flexi) 1827 if (flexi)
@@ -1642,7 +1855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1642 /// <param name="falloff"></param> 1855 /// <param name="falloff"></param>
1643 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1856 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1644 { 1857 {
1645 if (part == null) 1858 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1646 return; 1859 return;
1647 1860
1648 if (light) 1861 if (light)
@@ -1675,11 +1888,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1675 Primitive.TextureEntry tex = part.Shape.Textures; 1888 Primitive.TextureEntry tex = part.Shape.Textures;
1676 Color4 texcolor; 1889 Color4 texcolor;
1677 LSL_Vector rgb = new LSL_Vector(); 1890 LSL_Vector rgb = new LSL_Vector();
1891 int nsides = GetNumberOfSides(part);
1892
1678 if (face == ScriptBaseClass.ALL_SIDES) 1893 if (face == ScriptBaseClass.ALL_SIDES)
1679 { 1894 {
1680 int i; 1895 int i;
1681 1896 for (i = 0; i < nsides; i++)
1682 for (i = 0 ; i < GetNumberOfSides(part); i++)
1683 { 1897 {
1684 texcolor = tex.GetFace((uint)i).RGBA; 1898 texcolor = tex.GetFace((uint)i).RGBA;
1685 rgb.x += texcolor.R; 1899 rgb.x += texcolor.R;
@@ -1687,14 +1901,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1687 rgb.z += texcolor.B; 1901 rgb.z += texcolor.B;
1688 } 1902 }
1689 1903
1690 rgb.x /= (float)GetNumberOfSides(part); 1904 float invnsides = 1.0f / (float)nsides;
1691 rgb.y /= (float)GetNumberOfSides(part); 1905
1692 rgb.z /= (float)GetNumberOfSides(part); 1906 rgb.x *= invnsides;
1907 rgb.y *= invnsides;
1908 rgb.z *= invnsides;
1693 1909
1694 return rgb; 1910 return rgb;
1695 } 1911 }
1696 1912 if (face >= 0 && face < nsides)
1697 if (face >= 0 && face < GetNumberOfSides(part))
1698 { 1913 {
1699 texcolor = tex.GetFace((uint)face).RGBA; 1914 texcolor = tex.GetFace((uint)face).RGBA;
1700 rgb.x = texcolor.R; 1915 rgb.x = texcolor.R;
@@ -1721,15 +1936,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1721 m_host.AddScriptLPS(1); 1936 m_host.AddScriptLPS(1);
1722 1937
1723 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1938 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1724 1939 if (parts.Count > 0)
1725 foreach (SceneObjectPart part in parts) 1940 {
1726 SetTexture(part, texture, face); 1941 try
1727 1942 {
1943 foreach (SceneObjectPart part in parts)
1944 SetTexture(part, texture, face);
1945 }
1946 finally
1947 {
1948 }
1949 }
1728 ScriptSleep(200); 1950 ScriptSleep(200);
1729 } 1951 }
1730 1952
1731 protected void SetTexture(SceneObjectPart part, string texture, int face) 1953 protected void SetTexture(SceneObjectPart part, string texture, int face)
1732 { 1954 {
1955 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1956 return;
1957
1733 UUID textureID = new UUID(); 1958 UUID textureID = new UUID();
1734 1959
1735 textureID = InventoryKey(texture, (int)AssetType.Texture); 1960 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1774,6 +1999,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1774 1999
1775 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2000 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1776 { 2001 {
2002 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2003 return;
2004
1777 Primitive.TextureEntry tex = part.Shape.Textures; 2005 Primitive.TextureEntry tex = part.Shape.Textures;
1778 if (face >= 0 && face < GetNumberOfSides(part)) 2006 if (face >= 0 && face < GetNumberOfSides(part))
1779 { 2007 {
@@ -1810,6 +2038,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1810 2038
1811 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2039 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1812 { 2040 {
2041 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2042 return;
2043
1813 Primitive.TextureEntry tex = part.Shape.Textures; 2044 Primitive.TextureEntry tex = part.Shape.Textures;
1814 if (face >= 0 && face < GetNumberOfSides(part)) 2045 if (face >= 0 && face < GetNumberOfSides(part))
1815 { 2046 {
@@ -1846,6 +2077,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1846 2077
1847 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2078 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1848 { 2079 {
2080 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2081 return;
2082
1849 Primitive.TextureEntry tex = part.Shape.Textures; 2083 Primitive.TextureEntry tex = part.Shape.Textures;
1850 if (face >= 0 && face < GetNumberOfSides(part)) 2084 if (face >= 0 && face < GetNumberOfSides(part))
1851 { 2085 {
@@ -2016,24 +2250,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2016 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2250 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2017 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2251 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2018 { 2252 {
2019 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2253 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2254 return;
2255
2020 LSL_Vector currentPos = GetPartLocalPos(part); 2256 LSL_Vector currentPos = GetPartLocalPos(part);
2257 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2021 2258
2022 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2023 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2024 2259
2025 if (part.ParentGroup.RootPart == part) 2260 if (part.ParentGroup.RootPart == part)
2026 { 2261 {
2027 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2028 targetPos.z = ground;
2029 SceneObjectGroup parent = part.ParentGroup; 2262 SceneObjectGroup parent = part.ParentGroup;
2030 parent.UpdateGroupPosition(!adjust ? targetPos : 2263 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2031 SetPosAdjust(currentPos, targetPos)); 2264 return;
2265 Util.FireAndForget(delegate(object x) {
2266 parent.UpdateGroupPosition((Vector3)toPos);
2267 });
2032 } 2268 }
2033 else 2269 else
2034 { 2270 {
2035 part.OffsetPosition = !adjust ? targetPos : 2271 part.OffsetPosition = (Vector3)toPos;
2036 SetPosAdjust(currentPos, targetPos);
2037 SceneObjectGroup parent = part.ParentGroup; 2272 SceneObjectGroup parent = part.ParentGroup;
2038 parent.HasGroupChanged = true; 2273 parent.HasGroupChanged = true;
2039 parent.ScheduleGroupForTerseUpdate(); 2274 parent.ScheduleGroupForTerseUpdate();
@@ -2066,13 +2301,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2066 else 2301 else
2067 { 2302 {
2068 if (part.ParentGroup.IsAttachment) 2303 if (part.ParentGroup.IsAttachment)
2069 {
2070 pos = part.AttachedPos; 2304 pos = part.AttachedPos;
2071 }
2072 else 2305 else
2073 {
2074 pos = part.AbsolutePosition; 2306 pos = part.AbsolutePosition;
2075 }
2076 } 2307 }
2077 2308
2078// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2309// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2112,25 +2343,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2112 2343
2113 protected void SetRot(SceneObjectPart part, Quaternion rot) 2344 protected void SetRot(SceneObjectPart part, Quaternion rot)
2114 { 2345 {
2115 part.UpdateRotation(rot); 2346 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2116 // Update rotation does not move the object in the physics scene if it's a linkset. 2347 return;
2117 2348
2118//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2349 bool isroot = (part == part.ParentGroup.RootPart);
2119// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2350 bool isphys;
2120 2351
2121 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2122 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2123 // It's perfectly okay when the object is not an active physical body though.
2124 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2125 // but only if the object is not physial and active. This is important for rotating doors.
2126 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2127 // scene
2128 PhysicsActor pa = part.PhysActor; 2352 PhysicsActor pa = part.PhysActor;
2129 2353
2130 if (pa != null && !pa.IsPhysical) 2354 // keep using physactor ideia of isphysical
2355 // it should be SOP ideia of that
2356 // not much of a issue with ubitODE
2357 if (pa != null && pa.IsPhysical)
2358 isphys = true;
2359 else
2360 isphys = false;
2361
2362 // SL doesn't let scripts rotate root of physical linksets
2363 if (isroot && isphys)
2364 return;
2365
2366 part.UpdateRotation(rot);
2367
2368 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2369 // so do a nasty update of parts positions if is a root part rotation
2370 if (isroot && pa != null) // with if above implies non physical root part
2131 { 2371 {
2132 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2372 part.ParentGroup.ResetChildPrimPhysicsPositions();
2133 } 2373 }
2374 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2375 {
2376 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2377 if (sittingavas.Count > 0)
2378 {
2379 foreach (ScenePresence av in sittingavas)
2380 {
2381 if (isroot || part.LocalId == av.ParentID)
2382 av.SendTerseUpdateToAllClients();
2383 }
2384 }
2385 }
2134 } 2386 }
2135 2387
2136 /// <summary> 2388 /// <summary>
@@ -2178,8 +2430,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2178 2430
2179 public LSL_Rotation llGetLocalRot() 2431 public LSL_Rotation llGetLocalRot()
2180 { 2432 {
2433 return GetPartLocalRot(m_host);
2434 }
2435
2436 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2437 {
2181 m_host.AddScriptLPS(1); 2438 m_host.AddScriptLPS(1);
2182 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2439 Quaternion rot = part.RotationOffset;
2440 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2183 } 2441 }
2184 2442
2185 public void llSetForce(LSL_Vector force, int local) 2443 public void llSetForce(LSL_Vector force, int local)
@@ -2259,16 +2517,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2259 m_host.ApplyImpulse(v, local != 0); 2517 m_host.ApplyImpulse(v, local != 0);
2260 } 2518 }
2261 2519
2520
2262 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2521 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2263 { 2522 {
2264 m_host.AddScriptLPS(1); 2523 m_host.AddScriptLPS(1);
2265 m_host.ApplyAngularImpulse(force, local != 0); 2524 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2266 } 2525 }
2267 2526
2268 public void llSetTorque(LSL_Vector torque, int local) 2527 public void llSetTorque(LSL_Vector torque, int local)
2269 { 2528 {
2270 m_host.AddScriptLPS(1); 2529 m_host.AddScriptLPS(1);
2271 m_host.SetAngularImpulse(torque, local != 0); 2530 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2272 } 2531 }
2273 2532
2274 public LSL_Vector llGetTorque() 2533 public LSL_Vector llGetTorque()
@@ -2285,20 +2544,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2285 llSetTorque(torque, local); 2544 llSetTorque(torque, local);
2286 } 2545 }
2287 2546
2547 public void llSetVelocity(LSL_Vector vel, int local)
2548 {
2549 m_host.AddScriptLPS(1);
2550 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2551 }
2552
2288 public LSL_Vector llGetVel() 2553 public LSL_Vector llGetVel()
2289 { 2554 {
2290 m_host.AddScriptLPS(1); 2555 m_host.AddScriptLPS(1);
2291 2556
2292 Vector3 vel; 2557 Vector3 vel = Vector3.Zero;
2293 2558
2294 if (m_host.ParentGroup.IsAttachment) 2559 if (m_host.ParentGroup.IsAttachment)
2295 { 2560 {
2296 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2561 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2297 vel = avatar.Velocity; 2562 if (avatar != null)
2563 vel = avatar.Velocity;
2298 } 2564 }
2299 else 2565 else
2300 { 2566 {
2301 vel = m_host.Velocity; 2567 vel = m_host.ParentGroup.RootPart.Velocity;
2302 } 2568 }
2303 2569
2304 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2570 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2310,10 +2576,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2310 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2576 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2311 } 2577 }
2312 2578
2579 public void llSetAngularVelocity(LSL_Vector avel, int local)
2580 {
2581 m_host.AddScriptLPS(1);
2582 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2583 }
2584
2313 public LSL_Vector llGetOmega() 2585 public LSL_Vector llGetOmega()
2314 { 2586 {
2315 m_host.AddScriptLPS(1); 2587 m_host.AddScriptLPS(1);
2316 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2588 Vector3 avel = m_host.AngularVelocity;
2589 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2317 } 2590 }
2318 2591
2319 public LSL_Float llGetTimeOfDay() 2592 public LSL_Float llGetTimeOfDay()
@@ -2839,16 +3112,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2839 new_group.RootPart.UUID.ToString()) }, 3112 new_group.RootPart.UUID.ToString()) },
2840 new DetectParams[0])); 3113 new DetectParams[0]));
2841 3114
2842 float groupmass = new_group.GetMass(); 3115 // do recoil
3116 SceneObjectGroup hostgrp = m_host.ParentGroup;
3117 if (hostgrp == null)
3118 return;
3119
3120 if (hostgrp.IsAttachment) // don't recoil avatars
3121 return;
2843 3122
2844 PhysicsActor pa = new_group.RootPart.PhysActor; 3123 PhysicsActor pa = new_group.RootPart.PhysActor;
2845 3124
2846 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3125 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2847 { 3126 {
2848 //Recoil. 3127 float groupmass = new_group.GetMass();
2849 llApplyImpulse(vel * groupmass, 0); 3128 vel *= -groupmass;
3129 llApplyImpulse(vel, 0);
2850 } 3130 }
2851 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3131 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3132 return;
3133
2852 }); 3134 });
2853 3135
2854 //ScriptSleep((int)((groupmass * velmag) / 10)); 3136 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2863,35 +3145,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2863 public void llLookAt(LSL_Vector target, double strength, double damping) 3145 public void llLookAt(LSL_Vector target, double strength, double damping)
2864 { 3146 {
2865 m_host.AddScriptLPS(1); 3147 m_host.AddScriptLPS(1);
2866 // Determine where we are looking from
2867 LSL_Vector from = llGetPos();
2868 3148
2869 // Work out the normalised vector from the source to the target 3149 // Get the normalized vector to the target
2870 LSL_Vector delta = llVecNorm(target - from); 3150 LSL_Vector d1 = llVecNorm(target - llGetPos());
2871 LSL_Vector angle = new LSL_Vector(0,0,0);
2872 3151
2873 // Calculate the yaw 3152 // Get the bearing (yaw)
2874 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3153 LSL_Vector a1 = new LSL_Vector(0,0,0);
2875 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3154 a1.z = llAtan2(d1.y, d1.x);
2876 3155
2877 // Calculate pitch 3156 // Get the elevation (pitch)
2878 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3157 LSL_Vector a2 = new LSL_Vector(0,0,0);
3158 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2879 3159
2880 // we need to convert from a vector describing 3160 LSL_Rotation r1 = llEuler2Rot(a1);
2881 // the angles of rotation in radians into rotation value 3161 LSL_Rotation r2 = llEuler2Rot(a2);
2882 LSL_Rotation rot = llEuler2Rot(angle); 3162 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2883
2884 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2885 // set the rotation of the object, copy that behavior
2886 PhysicsActor pa = m_host.PhysActor;
2887 3163
2888 if (strength == 0 || pa == null || !pa.IsPhysical) 3164 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2889 { 3165 {
2890 llSetRot(rot); 3166 // Do nothing if either value is 0 (this has been checked in SL)
3167 if (strength <= 0.0 || damping <= 0.0)
3168 return;
3169
3170 llSetRot(r3 * r2 * r1);
2891 } 3171 }
2892 else 3172 else
2893 { 3173 {
2894 m_host.StartLookAt(rot, (float)strength, (float)damping); 3174 if (strength == 0)
3175 {
3176 llSetRot(r3 * r2 * r1);
3177 return;
3178 }
3179
3180 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2895 } 3181 }
2896 } 3182 }
2897 3183
@@ -2937,17 +3223,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2937 } 3223 }
2938 else 3224 else
2939 { 3225 {
2940 if (m_host.IsRoot) 3226 // new SL always returns object mass
2941 { 3227// if (m_host.IsRoot)
3228// {
2942 return m_host.ParentGroup.GetMass(); 3229 return m_host.ParentGroup.GetMass();
2943 } 3230// }
2944 else 3231// else
2945 { 3232// {
2946 return m_host.GetMass(); 3233// return m_host.GetMass();
2947 } 3234// }
2948 } 3235 }
2949 } 3236 }
2950 3237
3238
3239 public LSL_Float llGetMassMKS()
3240 {
3241 return 100f * llGetMass();
3242 }
3243
2951 public void llCollisionFilter(string name, string id, int accept) 3244 public void llCollisionFilter(string name, string id, int accept)
2952 { 3245 {
2953 m_host.AddScriptLPS(1); 3246 m_host.AddScriptLPS(1);
@@ -2995,8 +3288,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2995 { 3288 {
2996 // Unregister controls from Presence 3289 // Unregister controls from Presence
2997 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3290 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2998 // Remove Take Control permission.
2999 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3000 } 3291 }
3001 } 3292 }
3002 } 3293 }
@@ -3022,7 +3313,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3022 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3313 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3023 3314
3024 if (attachmentsModule != null) 3315 if (attachmentsModule != null)
3025 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3316 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3026 else 3317 else
3027 return false; 3318 return false;
3028 } 3319 }
@@ -3052,9 +3343,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3052 { 3343 {
3053 m_host.AddScriptLPS(1); 3344 m_host.AddScriptLPS(1);
3054 3345
3055// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3056// return;
3057
3058 if (m_item.PermsGranter != m_host.OwnerID) 3346 if (m_item.PermsGranter != m_host.OwnerID)
3059 return; 3347 return;
3060 3348
@@ -3097,6 +3385,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3097 3385
3098 public void llInstantMessage(string user, string message) 3386 public void llInstantMessage(string user, string message)
3099 { 3387 {
3388 UUID result;
3389 if (!UUID.TryParse(user, out result))
3390 {
3391 ShoutError("An invalid key was passed to llInstantMessage");
3392 ScriptSleep(2000);
3393 return;
3394 }
3395
3396
3100 m_host.AddScriptLPS(1); 3397 m_host.AddScriptLPS(1);
3101 3398
3102 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3399 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3111,14 +3408,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3111 UUID friendTransactionID = UUID.Random(); 3408 UUID friendTransactionID = UUID.Random();
3112 3409
3113 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3410 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3114 3411
3115 GridInstantMessage msg = new GridInstantMessage(); 3412 GridInstantMessage msg = new GridInstantMessage();
3116 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3413 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3117 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3414 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3118 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3415 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3119// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3416// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3120// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3417// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3121 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3418// DateTime dt = DateTime.UtcNow;
3419//
3420// // Ticks from UtcNow, but make it look like local. Evil, huh?
3421// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3422//
3423// try
3424// {
3425// // Convert that to the PST timezone
3426// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3427// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3428// }
3429// catch
3430// {
3431// // No logging here, as it could be VERY spammy
3432// }
3433//
3434// // And make it look local again to fool the unix time util
3435// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3436
3437 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3438
3122 //if (client != null) 3439 //if (client != null)
3123 //{ 3440 //{
3124 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3441 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3132,12 +3449,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3132 msg.message = message.Substring(0, 1024); 3449 msg.message = message.Substring(0, 1024);
3133 else 3450 else
3134 msg.message = message; 3451 msg.message = message;
3135 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3452 msg.dialog = (byte)19; // MessageFromObject
3136 msg.fromGroup = false;// fromGroup; 3453 msg.fromGroup = false;// fromGroup;
3137 msg.offline = (byte)0; //offline; 3454 msg.offline = (byte)0; //offline;
3138 msg.ParentEstateID = 0; //ParentEstateID; 3455 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3139 msg.Position = new Vector3(m_host.AbsolutePosition); 3456 msg.Position = new Vector3(m_host.AbsolutePosition);
3140 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3457 msg.RegionID = World.RegionInfo.RegionID.Guid;
3141 msg.binaryBucket 3458 msg.binaryBucket
3142 = Util.StringToBytes256( 3459 = Util.StringToBytes256(
3143 "{0}/{1}/{2}/{3}", 3460 "{0}/{1}/{2}/{3}",
@@ -3165,7 +3482,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3165 } 3482 }
3166 3483
3167 emailModule.SendEmail(m_host.UUID, address, subject, message); 3484 emailModule.SendEmail(m_host.UUID, address, subject, message);
3168 llSleep(EMAIL_PAUSE_TIME); 3485 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3169 } 3486 }
3170 3487
3171 public void llGetNextEmail(string address, string subject) 3488 public void llGetNextEmail(string address, string subject)
@@ -3411,7 +3728,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3411 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3728 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3412 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3729 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3413 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3730 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3731 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3414 ScriptBaseClass.PERMISSION_ATTACH; 3732 ScriptBaseClass.PERMISSION_ATTACH;
3733
3415 } 3734 }
3416 else 3735 else
3417 { 3736 {
@@ -3446,11 +3765,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3446 3765
3447 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3766 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3448 { 3767 {
3449 lock (m_host.TaskInventory) 3768 m_host.TaskInventory.LockItemsForWrite(true);
3450 { 3769 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3451 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3770 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3452 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3771 m_host.TaskInventory.LockItemsForWrite(false);
3453 }
3454 3772
3455 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3773 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3456 "run_time_permissions", new Object[] { 3774 "run_time_permissions", new Object[] {
@@ -3493,11 +3811,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3493 3811
3494 if (!m_waitingForScriptAnswer) 3812 if (!m_waitingForScriptAnswer)
3495 { 3813 {
3496 lock (m_host.TaskInventory) 3814 m_host.TaskInventory.LockItemsForWrite(true);
3497 { 3815 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3498 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3816 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3499 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3817 m_host.TaskInventory.LockItemsForWrite(false);
3500 }
3501 3818
3502 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3819 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3503 m_waitingForScriptAnswer=true; 3820 m_waitingForScriptAnswer=true;
@@ -3526,14 +3843,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3526 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3843 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3527 llReleaseControls(); 3844 llReleaseControls();
3528 3845
3529 lock (m_host.TaskInventory) 3846 m_host.TaskInventory.LockItemsForWrite(true);
3530 { 3847 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3531 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3848 m_host.TaskInventory.LockItemsForWrite(false);
3532 } 3849
3533 3850 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3534 m_ScriptEngine.PostScriptEvent( 3851 "run_time_permissions", new Object[] {
3535 m_item.ItemID, 3852 new LSL_Integer(answer) },
3536 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3853 new DetectParams[0]));
3537 } 3854 }
3538 3855
3539 public LSL_String llGetPermissionsKey() 3856 public LSL_String llGetPermissionsKey()
@@ -3572,14 +3889,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3572 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3889 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3573 { 3890 {
3574 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3891 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3575 3892 if (parts.Count > 0)
3576 foreach (SceneObjectPart part in parts) 3893 {
3577 part.SetFaceColorAlpha(face, color, null); 3894 try
3895 {
3896 foreach (SceneObjectPart part in parts)
3897 part.SetFaceColorAlpha(face, color, null);
3898 }
3899 finally
3900 {
3901 }
3902 }
3578 } 3903 }
3579 3904
3580 public void llCreateLink(string target, int parent) 3905 public void llCreateLink(string target, int parent)
3581 { 3906 {
3582 m_host.AddScriptLPS(1); 3907 m_host.AddScriptLPS(1);
3908
3583 UUID targetID; 3909 UUID targetID;
3584 3910
3585 if (!UUID.TryParse(target, out targetID)) 3911 if (!UUID.TryParse(target, out targetID))
@@ -3685,10 +4011,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3685 // Restructuring Multiple Prims. 4011 // Restructuring Multiple Prims.
3686 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4012 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3687 parts.Remove(parentPrim.RootPart); 4013 parts.Remove(parentPrim.RootPart);
3688 foreach (SceneObjectPart part in parts) 4014 if (parts.Count > 0)
3689 { 4015 {
3690 parentPrim.DelinkFromGroup(part.LocalId, true); 4016 try
4017 {
4018 foreach (SceneObjectPart part in parts)
4019 {
4020 parentPrim.DelinkFromGroup(part.LocalId, true);
4021 }
4022 }
4023 finally
4024 {
4025 }
3691 } 4026 }
4027
3692 parentPrim.HasGroupChanged = true; 4028 parentPrim.HasGroupChanged = true;
3693 parentPrim.ScheduleGroupForFullUpdate(); 4029 parentPrim.ScheduleGroupForFullUpdate();
3694 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4030 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3697,12 +4033,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3697 { 4033 {
3698 SceneObjectPart newRoot = parts[0]; 4034 SceneObjectPart newRoot = parts[0];
3699 parts.Remove(newRoot); 4035 parts.Remove(newRoot);
3700 foreach (SceneObjectPart part in parts) 4036
4037 try
3701 { 4038 {
3702 // Required for linking 4039 foreach (SceneObjectPart part in parts)
3703 part.ClearUpdateSchedule(); 4040 {
3704 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4041 part.ClearUpdateSchedule();
4042 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4043 }
3705 } 4044 }
4045 finally
4046 {
4047 }
4048
4049
3706 newRoot.ParentGroup.HasGroupChanged = true; 4050 newRoot.ParentGroup.HasGroupChanged = true;
3707 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4051 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3708 } 4052 }
@@ -3722,6 +4066,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3722 public void llBreakAllLinks() 4066 public void llBreakAllLinks()
3723 { 4067 {
3724 m_host.AddScriptLPS(1); 4068 m_host.AddScriptLPS(1);
4069
4070 TaskInventoryItem item = m_item;
4071
4072 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4073 && !m_automaticLinkPermission)
4074 {
4075 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4076 return;
4077 }
4078
3725 SceneObjectGroup parentPrim = m_host.ParentGroup; 4079 SceneObjectGroup parentPrim = m_host.ParentGroup;
3726 if (parentPrim.AttachmentPoint != 0) 4080 if (parentPrim.AttachmentPoint != 0)
3727 return; // Fail silently if attached 4081 return; // Fail silently if attached
@@ -3741,25 +4095,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3741 public LSL_String llGetLinkKey(int linknum) 4095 public LSL_String llGetLinkKey(int linknum)
3742 { 4096 {
3743 m_host.AddScriptLPS(1); 4097 m_host.AddScriptLPS(1);
3744 List<UUID> keytable = new List<UUID>();
3745 // parse for sitting avatare-uuids
3746 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3747 {
3748 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3749 keytable.Add(presence.UUID);
3750 });
3751
3752 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3753 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3754 {
3755 return keytable[totalprims - linknum].ToString();
3756 }
3757
3758 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3759 {
3760 return m_host.UUID.ToString();
3761 }
3762
3763 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4098 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3764 if (part != null) 4099 if (part != null)
3765 { 4100 {
@@ -3767,6 +4102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3767 } 4102 }
3768 else 4103 else
3769 { 4104 {
4105 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4106 {
4107 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4108
4109 if (linknum < 0)
4110 return UUID.Zero.ToString();
4111
4112 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4113 if (avatars.Count > linknum)
4114 {
4115 return avatars[linknum].UUID.ToString();
4116 }
4117 }
3770 return UUID.Zero.ToString(); 4118 return UUID.Zero.ToString();
3771 } 4119 }
3772 } 4120 }
@@ -3866,17 +4214,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3866 m_host.AddScriptLPS(1); 4214 m_host.AddScriptLPS(1);
3867 int count = 0; 4215 int count = 0;
3868 4216
3869 lock (m_host.TaskInventory) 4217 m_host.TaskInventory.LockItemsForRead(true);
4218 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3870 { 4219 {
3871 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4220 if (inv.Value.Type == type || type == -1)
3872 { 4221 {
3873 if (inv.Value.Type == type || type == -1) 4222 count = count + 1;
3874 {
3875 count = count + 1;
3876 }
3877 } 4223 }
3878 } 4224 }
3879 4225
4226 m_host.TaskInventory.LockItemsForRead(false);
3880 return count; 4227 return count;
3881 } 4228 }
3882 4229
@@ -3885,16 +4232,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3885 m_host.AddScriptLPS(1); 4232 m_host.AddScriptLPS(1);
3886 ArrayList keys = new ArrayList(); 4233 ArrayList keys = new ArrayList();
3887 4234
3888 lock (m_host.TaskInventory) 4235 m_host.TaskInventory.LockItemsForRead(true);
4236 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3889 { 4237 {
3890 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4238 if (inv.Value.Type == type || type == -1)
3891 { 4239 {
3892 if (inv.Value.Type == type || type == -1) 4240 keys.Add(inv.Value.Name);
3893 {
3894 keys.Add(inv.Value.Name);
3895 }
3896 } 4241 }
3897 } 4242 }
4243 m_host.TaskInventory.LockItemsForRead(false);
3898 4244
3899 if (keys.Count == 0) 4245 if (keys.Count == 0)
3900 { 4246 {
@@ -3932,7 +4278,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3932 if (item == null) 4278 if (item == null)
3933 { 4279 {
3934 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4280 llSay(0, String.Format("Could not find object '{0}'", inventory));
3935 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4281 return;
4282// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3936 } 4283 }
3937 4284
3938 UUID objId = item.ItemID; 4285 UUID objId = item.ItemID;
@@ -3960,33 +4307,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3960 return; 4307 return;
3961 } 4308 }
3962 } 4309 }
4310
3963 // destination is an avatar 4311 // destination is an avatar
3964 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4312 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3965 4313
3966 if (agentItem == null) 4314 if (agentItem == null)
3967 return; 4315 return;
3968 4316
3969 if (m_TransferModule != null) 4317 byte[] bucket = new byte[1];
3970 { 4318 bucket[0] = (byte)item.Type;
3971 byte[] bucket = new byte[] { (byte)item.Type }; 4319 //byte[] objBytes = agentItem.ID.GetBytes();
4320 //Array.Copy(objBytes, 0, bucket, 1, 16);
3972 4321
3973 GridInstantMessage msg = new GridInstantMessage(World, 4322 GridInstantMessage msg = new GridInstantMessage(World,
3974 m_host.UUID, m_host.Name + ", an object owned by " + 4323 m_host.OwnerID, m_host.Name, destId,
3975 resolveName(m_host.OwnerID) + ",", destId, 4324 (byte)InstantMessageDialog.TaskInventoryOffered,
3976 (byte)InstantMessageDialog.TaskInventoryOffered, 4325 false, item.Name+". "+m_host.Name+" is located at "+
3977 false, item.Name + "\n" + m_host.Name + " is located at " + 4326 World.RegionInfo.RegionName+" "+
3978 World.RegionInfo.RegionName+" "+ 4327 m_host.AbsolutePosition.ToString(),
3979 m_host.AbsolutePosition.ToString(), 4328 agentItem.ID, true, m_host.AbsolutePosition,
3980 agentItem.ID, true, m_host.AbsolutePosition, 4329 bucket);
3981 bucket);
3982 4330
3983 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4331 ScenePresence sp;
3984 }
3985 4332
4333 if (World.TryGetScenePresence(destId, out sp))
4334 {
4335 sp.ControllingClient.SendInstantMessage(msg);
4336 }
4337 else
4338 {
4339 if (m_TransferModule != null)
4340 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4341 }
4342
4343 //This delay should only occur when giving inventory to avatars.
3986 ScriptSleep(3000); 4344 ScriptSleep(3000);
3987 } 4345 }
3988 } 4346 }
3989 4347
4348 [DebuggerNonUserCode]
3990 public void llRemoveInventory(string name) 4349 public void llRemoveInventory(string name)
3991 { 4350 {
3992 m_host.AddScriptLPS(1); 4351 m_host.AddScriptLPS(1);
@@ -4030,109 +4389,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4030 { 4389 {
4031 m_host.AddScriptLPS(1); 4390 m_host.AddScriptLPS(1);
4032 4391
4033 UUID uuid = (UUID)id; 4392 UUID uuid;
4034 PresenceInfo pinfo = null; 4393 if (UUID.TryParse(id, out uuid))
4035 UserAccount account;
4036
4037 UserInfoCacheEntry ce;
4038 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4039 { 4394 {
4040 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4395 PresenceInfo pinfo = null;
4041 if (account == null) 4396 UserAccount account;
4397
4398 UserInfoCacheEntry ce;
4399 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4042 { 4400 {
4043 m_userInfoCache[uuid] = null; // Cache negative 4401 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4044 return UUID.Zero.ToString(); 4402 if (account == null)
4045 } 4403 {
4404 m_userInfoCache[uuid] = null; // Cache negative
4405 return UUID.Zero.ToString();
4406 }
4046 4407
4047 4408
4048 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4409 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4049 if (pinfos != null && pinfos.Length > 0) 4410 if (pinfos != null && pinfos.Length > 0)
4050 {
4051 foreach (PresenceInfo p in pinfos)
4052 { 4411 {
4053 if (p.RegionID != UUID.Zero) 4412 foreach (PresenceInfo p in pinfos)
4054 { 4413 {
4055 pinfo = p; 4414 if (p.RegionID != UUID.Zero)
4415 {
4416 pinfo = p;
4417 }
4056 } 4418 }
4057 } 4419 }
4058 }
4059 4420
4060 ce = new UserInfoCacheEntry(); 4421 ce = new UserInfoCacheEntry();
4061 ce.time = Util.EnvironmentTickCount(); 4422 ce.time = Util.EnvironmentTickCount();
4062 ce.account = account; 4423 ce.account = account;
4063 ce.pinfo = pinfo; 4424 ce.pinfo = pinfo;
4064 } 4425 m_userInfoCache[uuid] = ce;
4065 else 4426 }
4066 { 4427 else
4067 if (ce == null) 4428 {
4068 return UUID.Zero.ToString(); 4429 if (ce == null)
4430 return UUID.Zero.ToString();
4069 4431
4070 account = ce.account; 4432 account = ce.account;
4071 pinfo = ce.pinfo; 4433 pinfo = ce.pinfo;
4072 } 4434 }
4073 4435
4074 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4436 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4075 {
4076 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4077 if (pinfos != null && pinfos.Length > 0)
4078 { 4437 {
4079 foreach (PresenceInfo p in pinfos) 4438 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4439 if (pinfos != null && pinfos.Length > 0)
4080 { 4440 {
4081 if (p.RegionID != UUID.Zero) 4441 foreach (PresenceInfo p in pinfos)
4082 { 4442 {
4083 pinfo = p; 4443 if (p.RegionID != UUID.Zero)
4444 {
4445 pinfo = p;
4446 }
4084 } 4447 }
4085 } 4448 }
4086 } 4449 else
4087 else 4450 pinfo = null;
4088 pinfo = null;
4089 4451
4090 ce.time = Util.EnvironmentTickCount(); 4452 ce.time = Util.EnvironmentTickCount();
4091 ce.pinfo = pinfo; 4453 ce.pinfo = pinfo;
4092 } 4454 }
4093 4455
4094 string reply = String.Empty; 4456 string reply = String.Empty;
4095 4457
4096 switch (data) 4458 switch (data)
4097 { 4459 {
4098 case 1: // DATA_ONLINE (0|1) 4460 case 1: // DATA_ONLINE (0|1)
4099 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4461 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4100 reply = "1"; 4462 reply = "1";
4101 else 4463 else
4102 reply = "0"; 4464 reply = "0";
4103 break; 4465 break;
4104 case 2: // DATA_NAME (First Last) 4466 case 2: // DATA_NAME (First Last)
4105 reply = account.FirstName + " " + account.LastName; 4467 reply = account.FirstName + " " + account.LastName;
4106 break; 4468 break;
4107 case 3: // DATA_BORN (YYYY-MM-DD) 4469 case 3: // DATA_BORN (YYYY-MM-DD)
4108 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4470 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4109 born = born.AddSeconds(account.Created); 4471 born = born.AddSeconds(account.Created);
4110 reply = born.ToString("yyyy-MM-dd"); 4472 reply = born.ToString("yyyy-MM-dd");
4111 break; 4473 break;
4112 case 4: // DATA_RATING (0,0,0,0,0,0) 4474 case 4: // DATA_RATING (0,0,0,0,0,0)
4113 reply = "0,0,0,0,0,0"; 4475 reply = "0,0,0,0,0,0";
4114 break; 4476 break;
4115 case 7: // DATA_USERLEVEL (integer) 4477 case 8: // DATA_PAYINFO (0|1|2|3)
4116 reply = account.UserLevel.ToString(); 4478 reply = "0";
4117 break; 4479 break;
4118 case 8: // DATA_PAYINFO (0|1|2|3) 4480 default:
4119 reply = "0"; 4481 return UUID.Zero.ToString(); // Raise no event
4120 break; 4482 }
4121 default:
4122 return UUID.Zero.ToString(); // Raise no event
4123 }
4124 4483
4125 UUID rq = UUID.Random(); 4484 UUID rq = UUID.Random();
4126 4485
4127 UUID tid = AsyncCommands. 4486 UUID tid = AsyncCommands.
4128 DataserverPlugin.RegisterRequest(m_host.LocalId, 4487 DataserverPlugin.RegisterRequest(m_host.LocalId,
4129 m_item.ItemID, rq.ToString()); 4488 m_item.ItemID, rq.ToString());
4130 4489
4131 AsyncCommands. 4490 AsyncCommands.
4132 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4491 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4133 4492
4134 ScriptSleep(100); 4493 ScriptSleep(100);
4135 return tid.ToString(); 4494 return tid.ToString();
4495 }
4496 else
4497 {
4498 ShoutError("Invalid UUID passed to llRequestAgentData.");
4499 }
4500 return "";
4136 } 4501 }
4137 4502
4138 public LSL_String llRequestInventoryData(string name) 4503 public LSL_String llRequestInventoryData(string name)
@@ -4189,13 +4554,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4189 if (UUID.TryParse(agent, out agentId)) 4554 if (UUID.TryParse(agent, out agentId))
4190 { 4555 {
4191 ScenePresence presence = World.GetScenePresence(agentId); 4556 ScenePresence presence = World.GetScenePresence(agentId);
4192 if (presence != null) 4557 if (presence != null && presence.PresenceType != PresenceType.Npc)
4193 { 4558 {
4559 // agent must not be a god
4560 if (presence.UserLevel >= 200) return;
4561
4194 // agent must be over the owners land 4562 // agent must be over the owners land
4195 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4563 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4196 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4564 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4197 { 4565 {
4198 World.TeleportClientHome(agentId, presence.ControllingClient); 4566 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4567 {
4568 // They can't be teleported home for some reason
4569 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4570 if (regionInfo != null)
4571 {
4572 World.RequestTeleportLocation(
4573 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4574 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4575 }
4576 }
4199 } 4577 }
4200 } 4578 }
4201 } 4579 }
@@ -4302,7 +4680,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4302 UUID av = new UUID(); 4680 UUID av = new UUID();
4303 if (!UUID.TryParse(agent,out av)) 4681 if (!UUID.TryParse(agent,out av))
4304 { 4682 {
4305 LSLError("First parameter to llDialog needs to be a key"); 4683 //LSLError("First parameter to llDialog needs to be a key");
4306 return; 4684 return;
4307 } 4685 }
4308 4686
@@ -4334,7 +4712,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4334 public void llCollisionSound(string impact_sound, double impact_volume) 4712 public void llCollisionSound(string impact_sound, double impact_volume)
4335 { 4713 {
4336 m_host.AddScriptLPS(1); 4714 m_host.AddScriptLPS(1);
4337 4715
4716 if(impact_sound == "")
4717 {
4718 m_host.CollisionSoundVolume = (float)impact_volume;
4719 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4720 m_host.CollisionSoundType = 0;
4721 return;
4722 }
4338 // TODO: Parameter check logic required. 4723 // TODO: Parameter check logic required.
4339 UUID soundId = UUID.Zero; 4724 UUID soundId = UUID.Zero;
4340 if (!UUID.TryParse(impact_sound, out soundId)) 4725 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4347,6 +4732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4347 4732
4348 m_host.CollisionSound = soundId; 4733 m_host.CollisionSound = soundId;
4349 m_host.CollisionSoundVolume = (float)impact_volume; 4734 m_host.CollisionSoundVolume = (float)impact_volume;
4735 m_host.CollisionSoundType = 1;
4350 } 4736 }
4351 4737
4352 public LSL_String llGetAnimation(string id) 4738 public LSL_String llGetAnimation(string id)
@@ -4360,14 +4746,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4360 4746
4361 if (m_host.RegionHandle == presence.RegionHandle) 4747 if (m_host.RegionHandle == presence.RegionHandle)
4362 { 4748 {
4363 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4364
4365 if (presence != null) 4749 if (presence != null)
4366 { 4750 {
4367 AnimationSet currentAnims = presence.Animator.Animations; 4751 if (presence.SitGround)
4368 string currentAnimationState = String.Empty; 4752 return "Sitting on Ground";
4369 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4753 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4370 return currentAnimationState; 4754 return "Sitting";
4755
4756 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4757 string lslMovementAnimation;
4758
4759 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4760 return lslMovementAnimation;
4371 } 4761 }
4372 } 4762 }
4373 4763
@@ -4514,7 +4904,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4514 { 4904 {
4515 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4905 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4516 float distance_term = distance * distance * distance; // Script Energy 4906 float distance_term = distance * distance * distance; // Script Energy
4517 float pusher_mass = m_host.GetMass(); 4907 // use total object mass and not part
4908 float pusher_mass = m_host.ParentGroup.GetMass();
4518 4909
4519 float PUSH_ATTENUATION_DISTANCE = 17f; 4910 float PUSH_ATTENUATION_DISTANCE = 17f;
4520 float PUSH_ATTENUATION_SCALE = 5f; 4911 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4764,6 +5155,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4764 { 5155 {
4765 return item.AssetID.ToString(); 5156 return item.AssetID.ToString();
4766 } 5157 }
5158 m_host.TaskInventory.LockItemsForRead(false);
4767 5159
4768 return UUID.Zero.ToString(); 5160 return UUID.Zero.ToString();
4769 } 5161 }
@@ -4897,7 +5289,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4897 public LSL_Vector llGetCenterOfMass() 5289 public LSL_Vector llGetCenterOfMass()
4898 { 5290 {
4899 m_host.AddScriptLPS(1); 5291 m_host.AddScriptLPS(1);
4900 Vector3 center = m_host.GetGeometricCenter(); 5292 Vector3 center = m_host.GetCenterOfMass();
4901 return new LSL_Vector(center.X,center.Y,center.Z); 5293 return new LSL_Vector(center.X,center.Y,center.Z);
4902 } 5294 }
4903 5295
@@ -4916,14 +5308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4916 { 5308 {
4917 m_host.AddScriptLPS(1); 5309 m_host.AddScriptLPS(1);
4918 5310
4919 if (src == null) 5311 return src.Length;
4920 {
4921 return 0;
4922 }
4923 else
4924 {
4925 return src.Length;
4926 }
4927 } 5312 }
4928 5313
4929 public LSL_Integer llList2Integer(LSL_List src, int index) 5314 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4994,7 +5379,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4994 else if (src.Data[index] is LSL_Float) 5379 else if (src.Data[index] is LSL_Float)
4995 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5380 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4996 else if (src.Data[index] is LSL_String) 5381 else if (src.Data[index] is LSL_String)
4997 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5382 {
5383 string str = ((LSL_String) src.Data[index]).m_string;
5384 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5385 if (m != Match.Empty)
5386 {
5387 str = m.Value;
5388 double d = 0.0;
5389 if (!Double.TryParse(str, out d))
5390 return 0.0;
5391
5392 return d;
5393 }
5394 return 0.0;
5395 }
4998 return Convert.ToDouble(src.Data[index]); 5396 return Convert.ToDouble(src.Data[index]);
4999 } 5397 }
5000 catch (FormatException) 5398 catch (FormatException)
@@ -5036,7 +5434,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5036 // for completion and should LSL_Key ever be implemented 5434 // for completion and should LSL_Key ever be implemented
5037 // as it's own struct 5435 // as it's own struct
5038 else if (!(src.Data[index] is LSL_String || 5436 else if (!(src.Data[index] is LSL_String ||
5039 src.Data[index] is LSL_Key)) 5437 src.Data[index] is LSL_Key ||
5438 src.Data[index] is String))
5040 { 5439 {
5041 return ""; 5440 return "";
5042 } 5441 }
@@ -5294,7 +5693,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5294 } 5693 }
5295 } 5694 }
5296 } 5695 }
5297 else { 5696 else
5697 {
5298 object[] array = new object[src.Length]; 5698 object[] array = new object[src.Length];
5299 Array.Copy(src.Data, 0, array, 0, src.Length); 5699 Array.Copy(src.Data, 0, array, 0, src.Length);
5300 result = new LSL_List(array); 5700 result = new LSL_List(array);
@@ -5401,7 +5801,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5401 public LSL_Integer llGetRegionAgentCount() 5801 public LSL_Integer llGetRegionAgentCount()
5402 { 5802 {
5403 m_host.AddScriptLPS(1); 5803 m_host.AddScriptLPS(1);
5404 return new LSL_Integer(World.GetRootAgentCount()); 5804
5805 int count = 0;
5806 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5807 count++;
5808 });
5809
5810 return new LSL_Integer(count);
5405 } 5811 }
5406 5812
5407 public LSL_Vector llGetRegionCorner() 5813 public LSL_Vector llGetRegionCorner()
@@ -5634,6 +6040,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5634 flags |= ScriptBaseClass.AGENT_AWAY; 6040 flags |= ScriptBaseClass.AGENT_AWAY;
5635 } 6041 }
5636 6042
6043 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6044 UUID[] anims = agent.Animator.GetAnimationArray();
6045 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6046 {
6047 flags |= ScriptBaseClass.AGENT_BUSY;
6048 }
6049
5637 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6050 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5638 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6051 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5639 { 6052 {
@@ -5681,6 +6094,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5681 flags |= ScriptBaseClass.AGENT_SITTING; 6094 flags |= ScriptBaseClass.AGENT_SITTING;
5682 } 6095 }
5683 6096
6097 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6098 {
6099 flags |= ScriptBaseClass.AGENT_MALE;
6100 }
6101
5684 return flags; 6102 return flags;
5685 } 6103 }
5686 6104
@@ -5828,9 +6246,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5828 6246
5829 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6247 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5830 6248
5831 foreach (SceneObjectPart part in parts) 6249 try
6250 {
6251 foreach (SceneObjectPart part in parts)
6252 {
6253 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6254 }
6255 }
6256 finally
5832 { 6257 {
5833 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5834 } 6258 }
5835 } 6259 }
5836 6260
@@ -5882,13 +6306,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5882 6306
5883 if (m_host.OwnerID == land.LandData.OwnerID) 6307 if (m_host.OwnerID == land.LandData.OwnerID)
5884 { 6308 {
5885 World.TeleportClientHome(agentID, presence.ControllingClient); 6309 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6310 presence.TeleportWithMomentum(pos, null);
6311 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5886 } 6312 }
5887 } 6313 }
5888 } 6314 }
5889 ScriptSleep(5000); 6315 ScriptSleep(5000);
5890 } 6316 }
5891 6317
6318 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6319 {
6320 return ParseString2List(str, separators, in_spacers, false);
6321 }
6322
5892 public LSL_Integer llOverMyLand(string id) 6323 public LSL_Integer llOverMyLand(string id)
5893 { 6324 {
5894 m_host.AddScriptLPS(1); 6325 m_host.AddScriptLPS(1);
@@ -5947,20 +6378,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5947 return agentSize; 6378 return agentSize;
5948 } 6379 }
5949 6380
5950 public LSL_Integer llSameGroup(string agent) 6381 public LSL_Integer llSameGroup(string id)
5951 { 6382 {
5952 m_host.AddScriptLPS(1); 6383 m_host.AddScriptLPS(1);
5953 UUID agentId = new UUID(); 6384 UUID uuid = new UUID();
5954 if (!UUID.TryParse(agent, out agentId)) 6385 if (!UUID.TryParse(id, out uuid))
5955 return new LSL_Integer(0); 6386 return new LSL_Integer(0);
5956 ScenePresence presence = World.GetScenePresence(agentId); 6387
5957 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6388 // Check if it's a group key
5958 return new LSL_Integer(0); 6389 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5959 IClientAPI client = presence.ControllingClient;
5960 if (m_host.GroupID == client.ActiveGroupId)
5961 return new LSL_Integer(1); 6390 return new LSL_Integer(1);
5962 else 6391
6392 // We got passed a UUID.Zero
6393 if (uuid == UUID.Zero)
5963 return new LSL_Integer(0); 6394 return new LSL_Integer(0);
6395
6396 // Handle the case where id names an avatar
6397 ScenePresence presence = World.GetScenePresence(uuid);
6398 if (presence != null)
6399 {
6400 if (presence.IsChildAgent)
6401 return new LSL_Integer(0);
6402
6403 IClientAPI client = presence.ControllingClient;
6404 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6405 return new LSL_Integer(1);
6406
6407 return new LSL_Integer(0);
6408 }
6409
6410 // Handle object case
6411 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6412 if (part != null)
6413 {
6414 // This will handle both deed and non-deed and also the no
6415 // group case
6416 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6417 return new LSL_Integer(1);
6418
6419 return new LSL_Integer(0);
6420 }
6421
6422 return new LSL_Integer(0);
5964 } 6423 }
5965 6424
5966 public void llUnSit(string id) 6425 public void llUnSit(string id)
@@ -6085,7 +6544,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6085 return m_host.ParentGroup.AttachmentPoint; 6544 return m_host.ParentGroup.AttachmentPoint;
6086 } 6545 }
6087 6546
6088 public LSL_Integer llGetFreeMemory() 6547 public virtual LSL_Integer llGetFreeMemory()
6089 { 6548 {
6090 m_host.AddScriptLPS(1); 6549 m_host.AddScriptLPS(1);
6091 // Make scripts designed for LSO happy 6550 // Make scripts designed for LSO happy
@@ -6202,7 +6661,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6202 SetParticleSystem(m_host, rules); 6661 SetParticleSystem(m_host, rules);
6203 } 6662 }
6204 6663
6205 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6664 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6665 {
6206 6666
6207 6667
6208 if (rules.Length == 0) 6668 if (rules.Length == 0)
@@ -6516,6 +6976,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6516 6976
6517 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6977 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6518 { 6978 {
6979 // LSL quaternions can normalize to 0, normal Quaternions can't.
6980 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6981 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6982
6519 part.SitTargetPosition = offset; 6983 part.SitTargetPosition = offset;
6520 part.SitTargetOrientation = rot; 6984 part.SitTargetOrientation = rot;
6521 part.ParentGroup.HasGroupChanged = true; 6985 part.ParentGroup.HasGroupChanged = true;
@@ -6671,13 +7135,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6671 UUID av = new UUID(); 7135 UUID av = new UUID();
6672 if (!UUID.TryParse(avatar,out av)) 7136 if (!UUID.TryParse(avatar,out av))
6673 { 7137 {
6674 LSLError("First parameter to llDialog needs to be a key"); 7138 //LSLError("First parameter to llDialog needs to be a key");
6675 return; 7139 return;
6676 } 7140 }
6677 if (buttons.Length < 1) 7141 if (buttons.Length < 1)
6678 { 7142 {
6679 LSLError("No less than 1 button can be shown"); 7143 buttons.Add("OK");
6680 return;
6681 } 7144 }
6682 if (buttons.Length > 12) 7145 if (buttons.Length > 12)
6683 { 7146 {
@@ -6694,7 +7157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6694 } 7157 }
6695 if (buttons.Data[i].ToString().Length > 24) 7158 if (buttons.Data[i].ToString().Length > 24)
6696 { 7159 {
6697 LSLError("button label cannot be longer than 24 characters"); 7160 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6698 return; 7161 return;
6699 } 7162 }
6700 buts[i] = buttons.Data[i].ToString(); 7163 buts[i] = buttons.Data[i].ToString();
@@ -6761,9 +7224,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6761 return; 7224 return;
6762 } 7225 }
6763 7226
6764 // the rest of the permission checks are done in RezScript, so check the pin there as well 7227 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6765 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7228 if (dest != null)
7229 {
7230 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7231 {
7232 // the rest of the permission checks are done in RezScript, so check the pin there as well
7233 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6766 7234
7235 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7236 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7237 }
7238 }
6767 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7239 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6768 ScriptSleep(3000); 7240 ScriptSleep(3000);
6769 } 7241 }
@@ -6826,19 +7298,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6826 public LSL_String llMD5String(string src, int nonce) 7298 public LSL_String llMD5String(string src, int nonce)
6827 { 7299 {
6828 m_host.AddScriptLPS(1); 7300 m_host.AddScriptLPS(1);
6829 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7301 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6830 } 7302 }
6831 7303
6832 public LSL_String llSHA1String(string src) 7304 public LSL_String llSHA1String(string src)
6833 { 7305 {
6834 m_host.AddScriptLPS(1); 7306 m_host.AddScriptLPS(1);
6835 return Util.SHA1Hash(src).ToLower(); 7307 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6836 } 7308 }
6837 7309
6838 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7310 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6839 { 7311 {
6840 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7312 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6841 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7313 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7314 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7315 return shapeBlock;
6842 7316
6843 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7317 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6844 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7318 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6943,6 +7417,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6943 // Prim type box, cylinder and prism. 7417 // Prim type box, cylinder and prism.
6944 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) 7418 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)
6945 { 7419 {
7420 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7421 return;
7422
6946 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7423 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6947 ObjectShapePacket.ObjectDataBlock shapeBlock; 7424 ObjectShapePacket.ObjectDataBlock shapeBlock;
6948 7425
@@ -6996,6 +7473,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6996 // Prim type sphere. 7473 // Prim type sphere.
6997 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7474 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6998 { 7475 {
7476 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7477 return;
7478
6999 ObjectShapePacket.ObjectDataBlock shapeBlock; 7479 ObjectShapePacket.ObjectDataBlock shapeBlock;
7000 7480
7001 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7481 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7037,6 +7517,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7037 // Prim type torus, tube and ring. 7517 // Prim type torus, tube and ring.
7038 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) 7518 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)
7039 { 7519 {
7520 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7521 return;
7522
7040 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7523 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7041 ObjectShapePacket.ObjectDataBlock shapeBlock; 7524 ObjectShapePacket.ObjectDataBlock shapeBlock;
7042 7525
@@ -7172,6 +7655,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7172 // Prim type sculpt. 7655 // Prim type sculpt.
7173 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7656 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7174 { 7657 {
7658 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7659 return;
7660
7175 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7661 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7176 UUID sculptId; 7662 UUID sculptId;
7177 7663
@@ -7196,7 +7682,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7196 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7682 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7197 { 7683 {
7198 // default 7684 // default
7199 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7685 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7200 } 7686 }
7201 7687
7202 part.Shape.SetSculptProperties((byte)type, sculptId); 7688 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7213,48 +7699,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7213 ScriptSleep(200); 7699 ScriptSleep(200);
7214 } 7700 }
7215 7701
7216 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7702 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7217 { 7703 {
7218 m_host.AddScriptLPS(1); 7704 m_host.AddScriptLPS(1);
7219 7705
7220 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7706 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7221 7707
7222 ScriptSleep(200); 7708 ScriptSleep(200);
7223 } 7709 }
7224 7710
7225 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7711 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7226 { 7712 {
7227 m_host.AddScriptLPS(1); 7713 List<object> parts = new List<object>();
7714 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7715 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7716 foreach (SceneObjectPart p in prims)
7717 parts.Add(p);
7718 foreach (ScenePresence p in avatars)
7719 parts.Add(p);
7228 7720
7229 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7721 LSL_List remaining = null;
7722 uint rulesParsed = 0;
7723
7724 if (parts.Count > 0)
7725 {
7726 foreach (object part in parts)
7727 {
7728 if (part is SceneObjectPart)
7729 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7730 else
7731 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7732 }
7733
7734 while ((object)remaining != null && remaining.Length > 2)
7735 {
7736 linknumber = remaining.GetLSLIntegerItem(0);
7737 rules = remaining.GetSublist(1, -1);
7738 parts.Clear();
7739 prims = GetLinkParts(linknumber);
7740 avatars = GetLinkAvatars(linknumber);
7741 foreach (SceneObjectPart p in prims)
7742 parts.Add(p);
7743 foreach (ScenePresence p in avatars)
7744 parts.Add(p);
7745
7746 remaining = null;
7747 foreach (object part in parts)
7748 {
7749 if (part is SceneObjectPart)
7750 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7751 else
7752 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7753 }
7754 }
7755 }
7230 } 7756 }
7231 7757
7232 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7758 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7759 float material_density, float material_friction,
7760 float material_restitution, float material_gravity_modifier)
7233 { 7761 {
7234 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7762 ExtraPhysicsData physdata = new ExtraPhysicsData();
7763 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7764 physdata.Density = part.Density;
7765 physdata.Friction = part.Friction;
7766 physdata.Bounce = part.Bounciness;
7767 physdata.GravitationModifier = part.GravityModifier;
7235 7768
7236 LSL_List remaining = null; 7769 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7237 uint rulesParsed = 0; 7770 physdata.Density = material_density;
7771 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7772 physdata.Friction = material_friction;
7773 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7774 physdata.Bounce = material_restitution;
7775 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7776 physdata.GravitationModifier = material_gravity_modifier;
7238 7777
7239 foreach (SceneObjectPart part in parts) 7778 part.UpdateExtraPhysics(physdata);
7240 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7779 }
7241 7780
7242 while (remaining != null && remaining.Length > 2) 7781 public void llSetPhysicsMaterial(int material_bits,
7243 { 7782 float material_gravity_modifier, float material_restitution,
7244 linknumber = remaining.GetLSLIntegerItem(0); 7783 float material_friction, float material_density)
7245 rules = remaining.GetSublist(1, -1); 7784 {
7246 parts = GetLinkParts(linknumber); 7785 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7786 }
7247 7787
7248 foreach (SceneObjectPart part in parts) 7788 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7249 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7789 {
7790 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7791 llSetLinkPrimitiveParamsFast(linknumber, rules);
7792 ScriptSleep(200);
7793 }
7794
7795 // vector up using libomv (c&p from sop )
7796 // vector up rotated by r
7797 private Vector3 Zrot(Quaternion r)
7798 {
7799 double x, y, z, m;
7800
7801 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7802 if (Math.Abs(1.0 - m) > 0.000001)
7803 {
7804 m = 1.0 / Math.Sqrt(m);
7805 r.X *= (float)m;
7806 r.Y *= (float)m;
7807 r.Z *= (float)m;
7808 r.W *= (float)m;
7250 } 7809 }
7810
7811 x = 2 * (r.X * r.Z + r.Y * r.W);
7812 y = 2 * (-r.X * r.W + r.Y * r.Z);
7813 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7814
7815 return new Vector3((float)x, (float)y, (float)z);
7251 } 7816 }
7252 7817
7253 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7818 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7254 { 7819 {
7820 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7821 return null;
7822
7255 int idx = 0; 7823 int idx = 0;
7256 int idxStart = 0; 7824 int idxStart = 0;
7257 7825
7826 SceneObjectGroup parentgrp = part.ParentGroup;
7827
7258 bool positionChanged = false; 7828 bool positionChanged = false;
7259 LSL_Vector currentPosition = GetPartLocalPos(part); 7829 LSL_Vector currentPosition = GetPartLocalPos(part);
7260 7830
@@ -7279,8 +7849,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7279 return null; 7849 return null;
7280 7850
7281 v=rules.GetVector3Item(idx++); 7851 v=rules.GetVector3Item(idx++);
7282 positionChanged = true;
7283 currentPosition = GetSetPosTarget(part, v, currentPosition); 7852 currentPosition = GetSetPosTarget(part, v, currentPosition);
7853 positionChanged = true;
7284 7854
7285 break; 7855 break;
7286 case (int)ScriptBaseClass.PRIM_SIZE: 7856 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7557,7 +8127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7557 return null; 8127 return null;
7558 8128
7559 string ph = rules.Data[idx++].ToString(); 8129 string ph = rules.Data[idx++].ToString();
7560 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8130 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7561 8131
7562 break; 8132 break;
7563 8133
@@ -7575,12 +8145,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7575 part.ScriptSetPhysicsStatus(physics); 8145 part.ScriptSetPhysicsStatus(physics);
7576 break; 8146 break;
7577 8147
8148 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8149 if (remain < 1)
8150 return null;
8151
8152 int shape_type = rules.GetLSLIntegerItem(idx++);
8153
8154 ExtraPhysicsData physdata = new ExtraPhysicsData();
8155 physdata.Density = part.Density;
8156 physdata.Bounce = part.Bounciness;
8157 physdata.GravitationModifier = part.GravityModifier;
8158 physdata.PhysShapeType = (PhysShapeType)shape_type;
8159
8160 part.UpdateExtraPhysics(physdata);
8161
8162 break;
8163
8164 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8165 if (remain < 5)
8166 return null;
8167
8168 int material_bits = rules.GetLSLIntegerItem(idx++);
8169 float material_density = (float)rules.GetLSLFloatItem(idx++);
8170 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8171 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8172 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8173
8174 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8175
8176 break;
8177
7578 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8178 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7579 if (remain < 1) 8179 if (remain < 1)
7580 return null; 8180 return null;
7581 string temp = rules.Data[idx++].ToString(); 8181 string temp = rules.Data[idx++].ToString();
7582 8182
7583 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8183 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7584 8184
7585 break; 8185 break;
7586 8186
@@ -7654,7 +8254,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7654 if (part.ParentGroup.RootPart == part) 8254 if (part.ParentGroup.RootPart == part)
7655 { 8255 {
7656 SceneObjectGroup parent = part.ParentGroup; 8256 SceneObjectGroup parent = part.ParentGroup;
7657 parent.UpdateGroupPosition(currentPosition); 8257 Util.FireAndForget(delegate(object x) {
8258 parent.UpdateGroupPosition(currentPosition);
8259 });
7658 } 8260 }
7659 else 8261 else
7660 { 8262 {
@@ -7699,10 +8301,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7699 8301
7700 public LSL_String llXorBase64Strings(string str1, string str2) 8302 public LSL_String llXorBase64Strings(string str1, string str2)
7701 { 8303 {
7702 m_host.AddScriptLPS(1); 8304 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7703 Deprecated("llXorBase64Strings"); 8305
7704 ScriptSleep(300); 8306 ScriptSleep(300);
7705 return String.Empty; 8307 m_host.AddScriptLPS(1);
8308
8309 if (str1 == String.Empty)
8310 return String.Empty;
8311 if (str2 == String.Empty)
8312 return str1;
8313
8314 int len = str2.Length;
8315 if ((len % 4) != 0) // LL is EVIL!!!!
8316 {
8317 while (str2.EndsWith("="))
8318 str2 = str2.Substring(0, str2.Length - 1);
8319
8320 len = str2.Length;
8321 int mod = len % 4;
8322
8323 if (mod == 1)
8324 str2 = str2.Substring(0, str2.Length - 1);
8325 else if (mod == 2)
8326 str2 += "==";
8327 else if (mod == 3)
8328 str2 += "=";
8329 }
8330
8331 byte[] data1;
8332 byte[] data2;
8333 try
8334 {
8335 data1 = Convert.FromBase64String(str1);
8336 data2 = Convert.FromBase64String(str2);
8337 }
8338 catch (Exception)
8339 {
8340 return new LSL_String(String.Empty);
8341 }
8342
8343 // For cases where the decoded length of s2 is greater
8344 // than the decoded length of s1, simply perform a normal
8345 // decode and XOR
8346 //
8347 if (data2.Length >= data1.Length)
8348 {
8349 for (int pos = 0 ; pos < data1.Length ; pos++ )
8350 data1[pos] ^= data2[pos];
8351
8352 return Convert.ToBase64String(data1);
8353 }
8354
8355 // Remove padding
8356 while (str1.EndsWith("="))
8357 str1 = str1.Substring(0, str1.Length - 1);
8358 while (str2.EndsWith("="))
8359 str2 = str2.Substring(0, str2.Length - 1);
8360
8361 byte[] d1 = new byte[str1.Length];
8362 byte[] d2 = new byte[str2.Length];
8363
8364 for (int i = 0 ; i < str1.Length ; i++)
8365 {
8366 int idx = b64.IndexOf(str1.Substring(i, 1));
8367 if (idx == -1)
8368 idx = 0;
8369 d1[i] = (byte)idx;
8370 }
8371
8372 for (int i = 0 ; i < str2.Length ; i++)
8373 {
8374 int idx = b64.IndexOf(str2.Substring(i, 1));
8375 if (idx == -1)
8376 idx = 0;
8377 d2[i] = (byte)idx;
8378 }
8379
8380 string output = String.Empty;
8381
8382 for (int pos = 0 ; pos < d1.Length ; pos++)
8383 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8384
8385 while (output.Length % 3 > 0)
8386 output += "=";
8387
8388 return output;
7706 } 8389 }
7707 8390
7708 public void llRemoteDataSetRegion() 8391 public void llRemoteDataSetRegion()
@@ -7826,13 +8509,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7826 public LSL_Integer llGetNumberOfPrims() 8509 public LSL_Integer llGetNumberOfPrims()
7827 { 8510 {
7828 m_host.AddScriptLPS(1); 8511 m_host.AddScriptLPS(1);
7829 int avatarCount = 0; 8512 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7830 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8513
7831 {
7832 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7833 avatarCount++;
7834 });
7835
7836 return m_host.ParentGroup.PrimCount + avatarCount; 8514 return m_host.ParentGroup.PrimCount + avatarCount;
7837 } 8515 }
7838 8516
@@ -7848,55 +8526,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7848 m_host.AddScriptLPS(1); 8526 m_host.AddScriptLPS(1);
7849 UUID objID = UUID.Zero; 8527 UUID objID = UUID.Zero;
7850 LSL_List result = new LSL_List(); 8528 LSL_List result = new LSL_List();
8529
8530 // If the ID is not valid, return null result
7851 if (!UUID.TryParse(obj, out objID)) 8531 if (!UUID.TryParse(obj, out objID))
7852 { 8532 {
7853 result.Add(new LSL_Vector()); 8533 result.Add(new LSL_Vector());
7854 result.Add(new LSL_Vector()); 8534 result.Add(new LSL_Vector());
7855 return result; 8535 return result;
7856 } 8536 }
8537
8538 // Check if this is an attached prim. If so, replace
8539 // the UUID with the avatar UUID and report it's bounding box
8540 SceneObjectPart part = World.GetSceneObjectPart(objID);
8541 if (part != null && part.ParentGroup.IsAttachment)
8542 objID = part.ParentGroup.AttachedAvatar;
8543
8544 // Find out if this is an avatar ID. If so, return it's box
7857 ScenePresence presence = World.GetScenePresence(objID); 8545 ScenePresence presence = World.GetScenePresence(objID);
7858 if (presence != null) 8546 if (presence != null)
7859 { 8547 {
7860 if (presence.ParentID == 0) // not sat on an object 8548 // As per LSL Wiki, there is no difference between sitting
8549 // and standing avatar since server 1.36
8550 LSL_Vector lower;
8551 LSL_Vector upper;
8552 if (presence.Animator.Animations.DefaultAnimation.AnimID
8553 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7861 { 8554 {
7862 LSL_Vector lower; 8555 // This is for ground sitting avatars
7863 LSL_Vector upper; 8556 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7864 if (presence.Animator.Animations.DefaultAnimation.AnimID 8557 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7865 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8558 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7866 {
7867 // This is for ground sitting avatars
7868 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7869 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7870 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7871 }
7872 else
7873 {
7874 // This is for standing/flying avatars
7875 float height = presence.Appearance.AvatarHeight / 2.0f;
7876 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7877 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7878 }
7879 result.Add(lower);
7880 result.Add(upper);
7881 return result;
7882 } 8559 }
7883 else 8560 else
7884 { 8561 {
7885 // sitting on an object so we need the bounding box of that 8562 // This is for standing/flying avatars
7886 // which should include the avatar so set the UUID to the 8563 float height = presence.Appearance.AvatarHeight / 2.0f;
7887 // UUID of the object the avatar is sat on and allow it to fall through 8564 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7888 // to processing an object 8565 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7889 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7890 objID = p.UUID;
7891 } 8566 }
8567
8568 // Adjust to the documented error offsets (see LSL Wiki)
8569 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8570 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8571
8572 if (lower.x > upper.x)
8573 lower.x = upper.x;
8574 if (lower.y > upper.y)
8575 lower.y = upper.y;
8576 if (lower.z > upper.z)
8577 lower.z = upper.z;
8578
8579 result.Add(lower);
8580 result.Add(upper);
8581 return result;
7892 } 8582 }
7893 SceneObjectPart part = World.GetSceneObjectPart(objID); 8583
8584 part = World.GetSceneObjectPart(objID);
7894 // Currently only works for single prims without a sitting avatar 8585 // Currently only works for single prims without a sitting avatar
7895 if (part != null) 8586 if (part != null)
7896 { 8587 {
7897 Vector3 halfSize = part.Scale / 2.0f; 8588 float minX;
7898 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8589 float maxX;
7899 LSL_Vector upper = new LSL_Vector(halfSize); 8590 float minY;
8591 float maxY;
8592 float minZ;
8593 float maxZ;
8594
8595 // This BBox is in sim coordinates, with the offset being
8596 // a contained point.
8597 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8598 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8599
8600 minX -= offsets[0].X;
8601 maxX -= offsets[0].X;
8602 minY -= offsets[0].Y;
8603 maxY -= offsets[0].Y;
8604 minZ -= offsets[0].Z;
8605 maxZ -= offsets[0].Z;
8606
8607 LSL_Vector lower;
8608 LSL_Vector upper;
8609
8610 // Adjust to the documented error offsets (see LSL Wiki)
8611 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8612 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8613
8614 if (lower.x > upper.x)
8615 lower.x = upper.x;
8616 if (lower.y > upper.y)
8617 lower.y = upper.y;
8618 if (lower.z > upper.z)
8619 lower.z = upper.z;
8620
7900 result.Add(lower); 8621 result.Add(lower);
7901 result.Add(upper); 8622 result.Add(upper);
7902 return result; 8623 return result;
@@ -7910,7 +8631,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7910 8631
7911 public LSL_Vector llGetGeometricCenter() 8632 public LSL_Vector llGetGeometricCenter()
7912 { 8633 {
7913 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8634 Vector3 tmp = m_host.GetGeometricCenter();
8635 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7914 } 8636 }
7915 8637
7916 public LSL_List llGetPrimitiveParams(LSL_List rules) 8638 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7938,24 +8660,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7938 { 8660 {
7939 m_host.AddScriptLPS(1); 8661 m_host.AddScriptLPS(1);
7940 8662
7941 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8663 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8664 // keep other options as before
7942 8665
8666 List<SceneObjectPart> parts;
8667 List<ScenePresence> avatars;
8668
7943 LSL_List res = new LSL_List(); 8669 LSL_List res = new LSL_List();
7944 LSL_List remaining = null; 8670 LSL_List remaining = null;
7945 8671
7946 foreach (SceneObjectPart part in parts) 8672 while (rules.Length > 0)
7947 {
7948 remaining = GetPrimParams(part, rules, ref res);
7949 }
7950
7951 while (remaining != null && remaining.Length > 2)
7952 { 8673 {
7953 linknumber = remaining.GetLSLIntegerItem(0);
7954 rules = remaining.GetSublist(1, -1);
7955 parts = GetLinkParts(linknumber); 8674 parts = GetLinkParts(linknumber);
8675 avatars = GetLinkAvatars(linknumber);
7956 8676
8677 remaining = null;
7957 foreach (SceneObjectPart part in parts) 8678 foreach (SceneObjectPart part in parts)
8679 {
7958 remaining = GetPrimParams(part, rules, ref res); 8680 remaining = GetPrimParams(part, rules, ref res);
8681 }
8682 foreach (ScenePresence avatar in avatars)
8683 {
8684 remaining = GetPrimParams(avatar, rules, ref res);
8685 }
8686
8687 if (remaining != null && remaining.Length > 0)
8688 {
8689 linknumber = remaining.GetLSLIntegerItem(0);
8690 rules = remaining.GetSublist(1, -1);
8691 }
7959 } 8692 }
7960 8693
7961 return res; 8694 return res;
@@ -8000,13 +8733,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8000 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8733 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8001 part.AbsolutePosition.Y, 8734 part.AbsolutePosition.Y,
8002 part.AbsolutePosition.Z); 8735 part.AbsolutePosition.Z);
8003 // For some reason, the part.AbsolutePosition.* values do not change if the
8004 // linkset is rotated; they always reflect the child prim's world position
8005 // as though the linkset is unrotated. This is incompatible behavior with SL's
8006 // implementation, so will break scripts imported from there (not to mention it
8007 // makes it more difficult to determine a child prim's actual inworld position).
8008 if (part.ParentID != 0)
8009 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8010 res.Add(v); 8736 res.Add(v);
8011 break; 8737 break;
8012 8738
@@ -8178,30 +8904,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8178 if (remain < 1) 8904 if (remain < 1)
8179 return null; 8905 return null;
8180 8906
8181 face=(int)rules.GetLSLIntegerItem(idx++); 8907 face = (int)rules.GetLSLIntegerItem(idx++);
8182 8908
8183 tex = part.Shape.Textures; 8909 tex = part.Shape.Textures;
8910 int shiny;
8184 if (face == ScriptBaseClass.ALL_SIDES) 8911 if (face == ScriptBaseClass.ALL_SIDES)
8185 { 8912 {
8186 for (face = 0; face < GetNumberOfSides(part); face++) 8913 for (face = 0; face < GetNumberOfSides(part); face++)
8187 { 8914 {
8188 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8915 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8189 // Convert Shininess to PRIM_SHINY_* 8916 if (shinyness == Shininess.High)
8190 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8917 {
8191 // PRIM_BUMP_* 8918 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8192 res.Add(new LSL_Integer((int)texface.Bump)); 8919 }
8920 else if (shinyness == Shininess.Medium)
8921 {
8922 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8923 }
8924 else if (shinyness == Shininess.Low)
8925 {
8926 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8927 }
8928 else
8929 {
8930 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8931 }
8932 res.Add(new LSL_Integer(shiny));
8933 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8193 } 8934 }
8194 } 8935 }
8195 else 8936 else
8196 { 8937 {
8197 if (face >= 0 && face < GetNumberOfSides(part)) 8938 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8939 if (shinyness == Shininess.High)
8198 { 8940 {
8199 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8941 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8200 // Convert Shininess to PRIM_SHINY_*
8201 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8202 // PRIM_BUMP_*
8203 res.Add(new LSL_Integer((int)texface.Bump));
8204 } 8942 }
8943 else if (shinyness == Shininess.Medium)
8944 {
8945 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8946 }
8947 else if (shinyness == Shininess.Low)
8948 {
8949 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8950 }
8951 else
8952 {
8953 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8954 }
8955 res.Add(new LSL_Integer(shiny));
8956 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8205 } 8957 }
8206 break; 8958 break;
8207 8959
@@ -8209,24 +8961,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8209 if (remain < 1) 8961 if (remain < 1)
8210 return null; 8962 return null;
8211 8963
8212 face=(int)rules.GetLSLIntegerItem(idx++); 8964 face = (int)rules.GetLSLIntegerItem(idx++);
8213 8965
8214 tex = part.Shape.Textures; 8966 tex = part.Shape.Textures;
8967 int fullbright;
8215 if (face == ScriptBaseClass.ALL_SIDES) 8968 if (face == ScriptBaseClass.ALL_SIDES)
8216 { 8969 {
8217 for (face = 0; face < GetNumberOfSides(part); face++) 8970 for (face = 0; face < GetNumberOfSides(part); face++)
8218 { 8971 {
8219 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8972 if (tex.GetFace((uint)face).Fullbright == true)
8220 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8973 {
8974 fullbright = ScriptBaseClass.TRUE;
8975 }
8976 else
8977 {
8978 fullbright = ScriptBaseClass.FALSE;
8979 }
8980 res.Add(new LSL_Integer(fullbright));
8221 } 8981 }
8222 } 8982 }
8223 else 8983 else
8224 { 8984 {
8225 if (face >= 0 && face < GetNumberOfSides(part)) 8985 if (tex.GetFace((uint)face).Fullbright == true)
8226 { 8986 {
8227 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8987 fullbright = ScriptBaseClass.TRUE;
8228 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8988 }
8989 else
8990 {
8991 fullbright = ScriptBaseClass.FALSE;
8229 } 8992 }
8993 res.Add(new LSL_Integer(fullbright));
8230 } 8994 }
8231 break; 8995 break;
8232 8996
@@ -8248,27 +9012,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8248 break; 9012 break;
8249 9013
8250 case (int)ScriptBaseClass.PRIM_TEXGEN: 9014 case (int)ScriptBaseClass.PRIM_TEXGEN:
9015 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8251 if (remain < 1) 9016 if (remain < 1)
8252 return null; 9017 return null;
8253 9018
8254 face=(int)rules.GetLSLIntegerItem(idx++); 9019 face = (int)rules.GetLSLIntegerItem(idx++);
8255 9020
8256 tex = part.Shape.Textures; 9021 tex = part.Shape.Textures;
8257 if (face == ScriptBaseClass.ALL_SIDES) 9022 if (face == ScriptBaseClass.ALL_SIDES)
8258 { 9023 {
8259 for (face = 0; face < GetNumberOfSides(part); face++) 9024 for (face = 0; face < GetNumberOfSides(part); face++)
8260 { 9025 {
8261 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9026 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8262 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9027 {
8263 res.Add(new LSL_Integer((uint)texgen >> 1)); 9028 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9029 }
9030 else
9031 {
9032 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9033 }
8264 } 9034 }
8265 } 9035 }
8266 else 9036 else
8267 { 9037 {
8268 if (face >= 0 && face < GetNumberOfSides(part)) 9038 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9039 {
9040 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9041 }
9042 else
8269 { 9043 {
8270 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9044 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8271 res.Add(new LSL_Integer((uint)texgen >> 1));
8272 } 9045 }
8273 } 9046 }
8274 break; 9047 break;
@@ -8292,24 +9065,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8292 if (remain < 1) 9065 if (remain < 1)
8293 return null; 9066 return null;
8294 9067
8295 face=(int)rules.GetLSLIntegerItem(idx++); 9068 face = (int)rules.GetLSLIntegerItem(idx++);
8296 9069
8297 tex = part.Shape.Textures; 9070 tex = part.Shape.Textures;
9071 float primglow;
8298 if (face == ScriptBaseClass.ALL_SIDES) 9072 if (face == ScriptBaseClass.ALL_SIDES)
8299 { 9073 {
8300 for (face = 0; face < GetNumberOfSides(part); face++) 9074 for (face = 0; face < GetNumberOfSides(part); face++)
8301 { 9075 {
8302 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9076 primglow = tex.GetFace((uint)face).Glow;
8303 res.Add(new LSL_Float(texface.Glow)); 9077 res.Add(new LSL_Float(primglow));
8304 } 9078 }
8305 } 9079 }
8306 else 9080 else
8307 { 9081 {
8308 if (face >= 0 && face < GetNumberOfSides(part)) 9082 primglow = tex.GetFace((uint)face).Glow;
8309 { 9083 res.Add(new LSL_Float(primglow));
8310 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8311 res.Add(new LSL_Float(texface.Glow));
8312 }
8313 } 9084 }
8314 break; 9085 break;
8315 9086
@@ -8321,15 +9092,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8321 textColor.B)); 9092 textColor.B));
8322 res.Add(new LSL_Float(textColor.A)); 9093 res.Add(new LSL_Float(textColor.A));
8323 break; 9094 break;
9095
8324 case (int)ScriptBaseClass.PRIM_NAME: 9096 case (int)ScriptBaseClass.PRIM_NAME:
8325 res.Add(new LSL_String(part.Name)); 9097 res.Add(new LSL_String(part.Name));
8326 break; 9098 break;
9099
8327 case (int)ScriptBaseClass.PRIM_DESC: 9100 case (int)ScriptBaseClass.PRIM_DESC:
8328 res.Add(new LSL_String(part.Description)); 9101 res.Add(new LSL_String(part.Description));
8329 break; 9102 break;
9103
8330 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9104 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8331 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9105 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8332 break; 9106 break;
9107
8333 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9108 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8334 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9109 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8335 break; 9110 break;
@@ -8940,8 +9715,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8940 // The function returns an ordered list 9715 // The function returns an ordered list
8941 // representing the tokens found in the supplied 9716 // representing the tokens found in the supplied
8942 // sources string. If two successive tokenizers 9717 // sources string. If two successive tokenizers
8943 // are encountered, then a NULL entry is added 9718 // are encountered, then a null-string entry is
8944 // to the list. 9719 // added to the list.
8945 // 9720 //
8946 // It is a precondition that the source and 9721 // It is a precondition that the source and
8947 // toekizer lisst are non-null. If they are null, 9722 // toekizer lisst are non-null. If they are null,
@@ -8949,7 +9724,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8949 // while their lengths are being determined. 9724 // while their lengths are being determined.
8950 // 9725 //
8951 // A small amount of working memoryis required 9726 // A small amount of working memoryis required
8952 // of approximately 8*#tokenizers. 9727 // of approximately 8*#tokenizers + 8*srcstrlen.
8953 // 9728 //
8954 // There are many ways in which this function 9729 // There are many ways in which this function
8955 // can be implemented, this implementation is 9730 // can be implemented, this implementation is
@@ -8965,155 +9740,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8965 // and eliminates redundant tokenizers as soon 9740 // and eliminates redundant tokenizers as soon
8966 // as is possible. 9741 // as is possible.
8967 // 9742 //
8968 // The implementation tries to avoid any copying 9743 // The implementation tries to minimize temporary
8969 // of arrays or other objects. 9744 // garbage generation.
8970 // </remarks> 9745 // </remarks>
8971 9746
8972 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9747 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8973 { 9748 {
8974 int beginning = 0; 9749 return ParseString2List(src, separators, spacers, true);
8975 int srclen = src.Length; 9750 }
8976 int seplen = separators.Length;
8977 object[] separray = separators.Data;
8978 int spclen = spacers.Length;
8979 object[] spcarray = spacers.Data;
8980 int mlen = seplen+spclen;
8981
8982 int[] offset = new int[mlen+1];
8983 bool[] active = new bool[mlen];
8984
8985 int best;
8986 int j;
8987
8988 // Initial capacity reduces resize cost
8989 9751
8990 LSL_List tokens = new LSL_List(); 9752 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9753 {
9754 int srclen = src.Length;
9755 int seplen = separators.Length;
9756 object[] separray = separators.Data;
9757 int spclen = spacers.Length;
9758 object[] spcarray = spacers.Data;
9759 int dellen = 0;
9760 string[] delarray = new string[seplen+spclen];
8991 9761
8992 // All entries are initially valid 9762 int outlen = 0;
9763 string[] outarray = new string[srclen*2+1];
8993 9764
8994 for (int i = 0; i < mlen; i++) 9765 int i, j;
8995 active[i] = true; 9766 string d;
8996 9767
8997 offset[mlen] = srclen; 9768 m_host.AddScriptLPS(1);
8998 9769
8999 while (beginning < srclen) 9770 /*
9771 * Convert separator and spacer lists to C# strings.
9772 * Also filter out null strings so we don't hang.
9773 */
9774 for (i = 0; i < seplen; i ++)
9000 { 9775 {
9776 d = separray[i].ToString();
9777 if (d.Length > 0)
9778 {
9779 delarray[dellen++] = d;
9780 }
9781 }
9782 seplen = dellen;
9001 9783
9002 best = mlen; // as bad as it gets 9784 for (i = 0; i < spclen; i ++)
9785 {
9786 d = spcarray[i].ToString();
9787 if (d.Length > 0)
9788 {
9789 delarray[dellen++] = d;
9790 }
9791 }
9003 9792
9004 // Scan for separators 9793 /*
9794 * Scan through source string from beginning to end.
9795 */
9796 for (i = 0;;)
9797 {
9005 9798
9006 for (j = 0; j < seplen; j++) 9799 /*
9800 * Find earliest delimeter in src starting at i (if any).
9801 */
9802 int earliestDel = -1;
9803 int earliestSrc = srclen;
9804 string earliestStr = null;
9805 for (j = 0; j < dellen; j ++)
9007 { 9806 {
9008 if (separray[j].ToString() == String.Empty) 9807 d = delarray[j];
9009 active[j] = false; 9808 if (d != null)
9010
9011 if (active[j])
9012 { 9809 {
9013 // scan all of the markers 9810 int index = src.IndexOf(d, i);
9014 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9811 if (index < 0)
9015 { 9812 {
9016 // not present at all 9813 delarray[j] = null; // delim nowhere in src, don't check it anymore
9017 active[j] = false;
9018 } 9814 }
9019 else 9815 else if (index < earliestSrc)
9020 { 9816 {
9021 // present and correct 9817 earliestSrc = index; // where delimeter starts in source string
9022 if (offset[j] < offset[best]) 9818 earliestDel = j; // where delimeter is in delarray[]
9023 { 9819 earliestStr = d; // the delimeter string from delarray[]
9024 // closest so far 9820 if (index == i) break; // can't do any better than found at beg of string
9025 best = j;
9026 if (offset[best] == beginning)
9027 break;
9028 }
9029 } 9821 }
9030 } 9822 }
9031 } 9823 }
9032 9824
9033 // Scan for spacers 9825 /*
9034 9826 * Output source string starting at i through start of earliest delimeter.
9035 if (offset[best] != beginning) 9827 */
9828 if (keepNulls || (earliestSrc > i))
9036 { 9829 {
9037 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9830 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9038 {
9039 if (spcarray[j-seplen].ToString() == String.Empty)
9040 active[j] = false;
9041
9042 if (active[j])
9043 {
9044 // scan all of the markers
9045 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9046 {
9047 // not present at all
9048 active[j] = false;
9049 }
9050 else
9051 {
9052 // present and correct
9053 if (offset[j] < offset[best])
9054 {
9055 // closest so far
9056 best = j;
9057 }
9058 }
9059 }
9060 }
9061 } 9831 }
9062 9832
9063 // This is the normal exit from the scanning loop 9833 /*
9834 * If no delimeter found at or after i, we're done scanning.
9835 */
9836 if (earliestDel < 0) break;
9064 9837
9065 if (best == mlen) 9838 /*
9839 * If delimeter was a spacer, output the spacer.
9840 */
9841 if (earliestDel >= seplen)
9066 { 9842 {
9067 // no markers were found on this pass 9843 outarray[outlen++] = earliestStr;
9068 // so we're pretty much done
9069 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9070 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9071 break;
9072 } 9844 }
9073 9845
9074 // Otherwise we just add the newly delimited token 9846 /*
9075 // and recalculate where the search should continue. 9847 * Look at rest of src string following delimeter.
9076 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9848 */
9077 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9849 i = earliestSrc + earliestStr.Length;
9078
9079 if (best < seplen)
9080 {
9081 beginning = offset[best] + (separray[best].ToString()).Length;
9082 }
9083 else
9084 {
9085 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9086 string str = spcarray[best - seplen].ToString();
9087 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9088 tokens.Add(new LSL_String(str));
9089 }
9090 } 9850 }
9091 9851
9092 // This an awkward an not very intuitive boundary case. If the 9852 /*
9093 // last substring is a tokenizer, then there is an implied trailing 9853 * Make up an exact-sized output array suitable for an LSL_List object.
9094 // null list entry. Hopefully the single comparison will not be too 9854 */
9095 // arduous. Alternatively the 'break' could be replced with a return 9855 object[] outlist = new object[outlen];
9096 // but that's shabby programming. 9856 for (i = 0; i < outlen; i ++)
9097
9098 if ((beginning == srclen) && (keepNulls))
9099 { 9857 {
9100 if (srclen != 0) 9858 outlist[i] = new LSL_String(outarray[i]);
9101 tokens.Add(new LSL_String(""));
9102 } 9859 }
9103 9860 return new LSL_List(outlist);
9104 return tokens;
9105 }
9106
9107 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9108 {
9109 m_host.AddScriptLPS(1);
9110 return this.ParseString(src, separators, spacers, false);
9111 }
9112
9113 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9114 {
9115 m_host.AddScriptLPS(1);
9116 return this.ParseString(src, separators, spacers, true);
9117 } 9861 }
9118 9862
9119 public LSL_Integer llGetObjectPermMask(int mask) 9863 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9208,6 +9952,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9208 case 4: 9952 case 4:
9209 return (int)item.NextPermissions; 9953 return (int)item.NextPermissions;
9210 } 9954 }
9955 m_host.TaskInventory.LockItemsForRead(false);
9211 9956
9212 return -1; 9957 return -1;
9213 } 9958 }
@@ -9398,9 +10143,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9398 { 10143 {
9399 try 10144 try
9400 { 10145 {
10146 /*
9401 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10147 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9402 if (obj != null) 10148 if (obj != null)
9403 return (double)obj.GetMass(); 10149 return (double)obj.GetMass();
10150 */
10151 // return total object mass
10152 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10153 if (obj != null)
10154 return obj.GetMass();
10155
9404 // the object is null so the key is for an avatar 10156 // the object is null so the key is for an avatar
9405 ScenePresence avatar = World.GetScenePresence(key); 10157 ScenePresence avatar = World.GetScenePresence(key);
9406 if (avatar != null) 10158 if (avatar != null)
@@ -9420,7 +10172,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9420 } 10172 }
9421 10173
9422 /// <summary> 10174 /// <summary>
9423 /// illListReplaceList removes the sub-list defined by the inclusive indices 10175 /// llListReplaceList removes the sub-list defined by the inclusive indices
9424 /// start and end and inserts the src list in its place. The inclusive 10176 /// start and end and inserts the src list in its place. The inclusive
9425 /// nature of the indices means that at least one element must be deleted 10177 /// nature of the indices means that at least one element must be deleted
9426 /// if the indices are within the bounds of the existing list. I.e. 2,2 10178 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9477,16 +10229,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9477 // based upon end. Note that if end exceeds the upper 10229 // based upon end. Note that if end exceeds the upper
9478 // bound in this case, the entire destination list 10230 // bound in this case, the entire destination list
9479 // is removed. 10231 // is removed.
9480 else 10232 else if (start == 0)
9481 { 10233 {
9482 if (end + 1 < dest.Length) 10234 if (end + 1 < dest.Length)
9483 {
9484 return src + dest.GetSublist(end + 1, -1); 10235 return src + dest.GetSublist(end + 1, -1);
9485 }
9486 else 10236 else
9487 {
9488 return src; 10237 return src;
9489 } 10238 }
10239 else // Start < 0
10240 {
10241 if (end + 1 < dest.Length)
10242 return dest.GetSublist(end + 1, -1);
10243 else
10244 return new LSL_List();
9490 } 10245 }
9491 } 10246 }
9492 // Finally, if start > end, we strip away a prefix and 10247 // Finally, if start > end, we strip away a prefix and
@@ -9537,17 +10292,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9537 int width = 0; 10292 int width = 0;
9538 int height = 0; 10293 int height = 0;
9539 10294
9540 ParcelMediaCommandEnum? commandToSend = null; 10295 uint commandToSend = 0;
9541 float time = 0.0f; // default is from start 10296 float time = 0.0f; // default is from start
9542 10297
9543 ScenePresence presence = null; 10298 ScenePresence presence = null;
9544 10299
9545 for (int i = 0; i < commandList.Data.Length; i++) 10300 for (int i = 0; i < commandList.Data.Length; i++)
9546 { 10301 {
9547 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10302 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9548 switch (command) 10303 switch (command)
9549 { 10304 {
9550 case ParcelMediaCommandEnum.Agent: 10305 case (uint)ParcelMediaCommandEnum.Agent:
9551 // we send only to one agent 10306 // we send only to one agent
9552 if ((i + 1) < commandList.Length) 10307 if ((i + 1) < commandList.Length)
9553 { 10308 {
@@ -9564,25 +10319,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9564 } 10319 }
9565 break; 10320 break;
9566 10321
9567 case ParcelMediaCommandEnum.Loop: 10322 case (uint)ParcelMediaCommandEnum.Loop:
9568 loop = 1; 10323 loop = 1;
9569 commandToSend = command; 10324 commandToSend = command;
9570 update = true; //need to send the media update packet to set looping 10325 update = true; //need to send the media update packet to set looping
9571 break; 10326 break;
9572 10327
9573 case ParcelMediaCommandEnum.Play: 10328 case (uint)ParcelMediaCommandEnum.Play:
9574 loop = 0; 10329 loop = 0;
9575 commandToSend = command; 10330 commandToSend = command;
9576 update = true; //need to send the media update packet to make sure it doesn't loop 10331 update = true; //need to send the media update packet to make sure it doesn't loop
9577 break; 10332 break;
9578 10333
9579 case ParcelMediaCommandEnum.Pause: 10334 case (uint)ParcelMediaCommandEnum.Pause:
9580 case ParcelMediaCommandEnum.Stop: 10335 case (uint)ParcelMediaCommandEnum.Stop:
9581 case ParcelMediaCommandEnum.Unload: 10336 case (uint)ParcelMediaCommandEnum.Unload:
9582 commandToSend = command; 10337 commandToSend = command;
9583 break; 10338 break;
9584 10339
9585 case ParcelMediaCommandEnum.Url: 10340 case (uint)ParcelMediaCommandEnum.Url:
9586 if ((i + 1) < commandList.Length) 10341 if ((i + 1) < commandList.Length)
9587 { 10342 {
9588 if (commandList.Data[i + 1] is LSL_String) 10343 if (commandList.Data[i + 1] is LSL_String)
@@ -9595,7 +10350,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9595 } 10350 }
9596 break; 10351 break;
9597 10352
9598 case ParcelMediaCommandEnum.Texture: 10353 case (uint)ParcelMediaCommandEnum.Texture:
9599 if ((i + 1) < commandList.Length) 10354 if ((i + 1) < commandList.Length)
9600 { 10355 {
9601 if (commandList.Data[i + 1] is LSL_String) 10356 if (commandList.Data[i + 1] is LSL_String)
@@ -9608,7 +10363,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9608 } 10363 }
9609 break; 10364 break;
9610 10365
9611 case ParcelMediaCommandEnum.Time: 10366 case (uint)ParcelMediaCommandEnum.Time:
9612 if ((i + 1) < commandList.Length) 10367 if ((i + 1) < commandList.Length)
9613 { 10368 {
9614 if (commandList.Data[i + 1] is LSL_Float) 10369 if (commandList.Data[i + 1] is LSL_Float)
@@ -9620,7 +10375,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9620 } 10375 }
9621 break; 10376 break;
9622 10377
9623 case ParcelMediaCommandEnum.AutoAlign: 10378 case (uint)ParcelMediaCommandEnum.AutoAlign:
9624 if ((i + 1) < commandList.Length) 10379 if ((i + 1) < commandList.Length)
9625 { 10380 {
9626 if (commandList.Data[i + 1] is LSL_Integer) 10381 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9634,7 +10389,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9634 } 10389 }
9635 break; 10390 break;
9636 10391
9637 case ParcelMediaCommandEnum.Type: 10392 case (uint)ParcelMediaCommandEnum.Type:
9638 if ((i + 1) < commandList.Length) 10393 if ((i + 1) < commandList.Length)
9639 { 10394 {
9640 if (commandList.Data[i + 1] is LSL_String) 10395 if (commandList.Data[i + 1] is LSL_String)
@@ -9647,7 +10402,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9647 } 10402 }
9648 break; 10403 break;
9649 10404
9650 case ParcelMediaCommandEnum.Desc: 10405 case (uint)ParcelMediaCommandEnum.Desc:
9651 if ((i + 1) < commandList.Length) 10406 if ((i + 1) < commandList.Length)
9652 { 10407 {
9653 if (commandList.Data[i + 1] is LSL_String) 10408 if (commandList.Data[i + 1] is LSL_String)
@@ -9660,7 +10415,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9660 } 10415 }
9661 break; 10416 break;
9662 10417
9663 case ParcelMediaCommandEnum.Size: 10418 case (uint)ParcelMediaCommandEnum.Size:
9664 if ((i + 2) < commandList.Length) 10419 if ((i + 2) < commandList.Length)
9665 { 10420 {
9666 if (commandList.Data[i + 1] is LSL_Integer) 10421 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9730,7 +10485,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9730 } 10485 }
9731 } 10486 }
9732 10487
9733 if (commandToSend != null) 10488 if (commandToSend != 0)
9734 { 10489 {
9735 // the commandList contained a start/stop/... command, too 10490 // the commandList contained a start/stop/... command, too
9736 if (presence == null) 10491 if (presence == null)
@@ -9767,7 +10522,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9767 10522
9768 if (aList.Data[i] != null) 10523 if (aList.Data[i] != null)
9769 { 10524 {
9770 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10525 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9771 { 10526 {
9772 case ParcelMediaCommandEnum.Url: 10527 case ParcelMediaCommandEnum.Url:
9773 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10528 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9824,15 +10579,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9824 10579
9825 if (quick_pay_buttons.Data.Length < 4) 10580 if (quick_pay_buttons.Data.Length < 4)
9826 { 10581 {
9827 LSLError("List must have at least 4 elements"); 10582 int x;
9828 return; 10583 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10584 {
10585 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10586 }
9829 } 10587 }
9830 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10588 int[] nPrice = new int[5];
9831 10589 nPrice[0] = price;
9832 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10590 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9833 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10591 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9834 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10592 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9835 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10593 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10594 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9836 m_host.ParentGroup.HasGroupChanged = true; 10595 m_host.ParentGroup.HasGroupChanged = true;
9837 } 10596 }
9838 10597
@@ -9849,7 +10608,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9849 return new LSL_Vector(); 10608 return new LSL_Vector();
9850 } 10609 }
9851 10610
9852 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10611// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10612 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9853 if (presence != null) 10613 if (presence != null)
9854 { 10614 {
9855 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10615 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9871,7 +10631,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9871 return new LSL_Rotation(); 10631 return new LSL_Rotation();
9872 } 10632 }
9873 10633
9874 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10634// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10635 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9875 if (presence != null) 10636 if (presence != null)
9876 { 10637 {
9877 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10638 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9931,14 +10692,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9931 { 10692 {
9932 m_host.AddScriptLPS(1); 10693 m_host.AddScriptLPS(1);
9933 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10694 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9934 if (detectedParams == null) return; // only works on the first detected avatar 10695 if (detectedParams == null)
9935 10696 {
10697 if (m_host.ParentGroup.IsAttachment == true)
10698 {
10699 detectedParams = new DetectParams();
10700 detectedParams.Key = m_host.OwnerID;
10701 }
10702 else
10703 {
10704 return;
10705 }
10706 }
10707
9936 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10708 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9937 if (avatar != null) 10709 if (avatar != null)
9938 { 10710 {
9939 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10711 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9940 simname, pos, lookAt); 10712 simname, pos, lookAt);
9941 } 10713 }
10714
9942 ScriptSleep(1000); 10715 ScriptSleep(1000);
9943 } 10716 }
9944 10717
@@ -10062,12 +10835,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10062 10835
10063 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10836 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10064 object[] data = rules.Data; 10837 object[] data = rules.Data;
10065 for (int i = 0; i < data.Length; ++i) { 10838 for (int i = 0; i < data.Length; ++i)
10839 {
10066 int type = Convert.ToInt32(data[i++].ToString()); 10840 int type = Convert.ToInt32(data[i++].ToString());
10067 if (i >= data.Length) break; // odd number of entries => ignore the last 10841 if (i >= data.Length) break; // odd number of entries => ignore the last
10068 10842
10069 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10843 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10070 switch (type) { 10844 switch (type)
10845 {
10071 case ScriptBaseClass.CAMERA_FOCUS: 10846 case ScriptBaseClass.CAMERA_FOCUS:
10072 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10847 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10073 case ScriptBaseClass.CAMERA_POSITION: 10848 case ScriptBaseClass.CAMERA_POSITION:
@@ -10172,19 +10947,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10172 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10947 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10173 { 10948 {
10174 m_host.AddScriptLPS(1); 10949 m_host.AddScriptLPS(1);
10175 string ret = String.Empty; 10950
10176 string src1 = llBase64ToString(str1); 10951 if (str1 == String.Empty)
10177 string src2 = llBase64ToString(str2); 10952 return String.Empty;
10178 int c = 0; 10953 if (str2 == String.Empty)
10179 for (int i = 0; i < src1.Length; i++) 10954 return str1;
10955
10956 int len = str2.Length;
10957 if ((len % 4) != 0) // LL is EVIL!!!!
10180 { 10958 {
10181 ret += (char) (src1[i] ^ src2[c]); 10959 while (str2.EndsWith("="))
10960 str2 = str2.Substring(0, str2.Length - 1);
10961
10962 len = str2.Length;
10963 int mod = len % 4;
10182 10964
10183 c++; 10965 if (mod == 1)
10184 if (c >= src2.Length) 10966 str2 = str2.Substring(0, str2.Length - 1);
10185 c = 0; 10967 else if (mod == 2)
10968 str2 += "==";
10969 else if (mod == 3)
10970 str2 += "=";
10186 } 10971 }
10187 return llStringToBase64(ret); 10972
10973 byte[] data1;
10974 byte[] data2;
10975 try
10976 {
10977 data1 = Convert.FromBase64String(str1);
10978 data2 = Convert.FromBase64String(str2);
10979 }
10980 catch (Exception)
10981 {
10982 return new LSL_String(String.Empty);
10983 }
10984
10985 byte[] d2 = new Byte[data1.Length];
10986 int pos = 0;
10987
10988 if (data1.Length <= data2.Length)
10989 {
10990 Array.Copy(data2, 0, d2, 0, data1.Length);
10991 }
10992 else
10993 {
10994 while (pos < data1.Length)
10995 {
10996 len = data1.Length - pos;
10997 if (len > data2.Length)
10998 len = data2.Length;
10999
11000 Array.Copy(data2, 0, d2, pos, len);
11001 pos += len;
11002 }
11003 }
11004
11005 for (pos = 0 ; pos < data1.Length ; pos++ )
11006 data1[pos] ^= d2[pos];
11007
11008 return Convert.ToBase64String(data1);
10188 } 11009 }
10189 11010
10190 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11011 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10237,16 +11058,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10237 if (userAgent != null) 11058 if (userAgent != null)
10238 httpHeaders["User-Agent"] = userAgent; 11059 httpHeaders["User-Agent"] = userAgent;
10239 11060
11061 // See if the URL contains any header hacks
11062 string[] urlParts = url.Split(new char[] {'\n'});
11063 if (urlParts.Length > 1)
11064 {
11065 // Iterate the passed headers and parse them
11066 for (int i = 1 ; i < urlParts.Length ; i++ )
11067 {
11068 // The rest of those would be added to the body in SL.
11069 // Let's not do that.
11070 if (urlParts[i] == String.Empty)
11071 break;
11072
11073 // See if this could be a valid header
11074 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11075 if (headerParts.Length != 2)
11076 continue;
11077
11078 string headerName = headerParts[0].Trim();
11079 string headerValue = headerParts[1].Trim();
11080
11081 // Filter out headers that could be used to abuse
11082 // another system or cloak the request
11083 if (headerName.ToLower() == "x-secondlife-shard" ||
11084 headerName.ToLower() == "x-secondlife-object-name" ||
11085 headerName.ToLower() == "x-secondlife-object-key" ||
11086 headerName.ToLower() == "x-secondlife-region" ||
11087 headerName.ToLower() == "x-secondlife-local-position" ||
11088 headerName.ToLower() == "x-secondlife-local-velocity" ||
11089 headerName.ToLower() == "x-secondlife-local-rotation" ||
11090 headerName.ToLower() == "x-secondlife-owner-name" ||
11091 headerName.ToLower() == "x-secondlife-owner-key" ||
11092 headerName.ToLower() == "connection" ||
11093 headerName.ToLower() == "content-length" ||
11094 headerName.ToLower() == "from" ||
11095 headerName.ToLower() == "host" ||
11096 headerName.ToLower() == "proxy-authorization" ||
11097 headerName.ToLower() == "referer" ||
11098 headerName.ToLower() == "trailer" ||
11099 headerName.ToLower() == "transfer-encoding" ||
11100 headerName.ToLower() == "via" ||
11101 headerName.ToLower() == "authorization")
11102 continue;
11103
11104 httpHeaders[headerName] = headerValue;
11105 }
11106
11107 // Finally, strip any protocol specifier from the URL
11108 url = urlParts[0].Trim();
11109 int idx = url.IndexOf(" HTTP/");
11110 if (idx != -1)
11111 url = url.Substring(0, idx);
11112 }
11113
10240 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11114 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10241 Regex r = new Regex(authregex); 11115 Regex r = new Regex(authregex);
10242 int[] gnums = r.GetGroupNumbers(); 11116 int[] gnums = r.GetGroupNumbers();
10243 Match m = r.Match(url); 11117 Match m = r.Match(url);
10244 if (m.Success) { 11118 if (m.Success)
10245 for (int i = 1; i < gnums.Length; i++) { 11119 {
11120 for (int i = 1; i < gnums.Length; i++)
11121 {
10246 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11122 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10247 //CaptureCollection cc = g.Captures; 11123 //CaptureCollection cc = g.Captures;
10248 } 11124 }
10249 if (m.Groups.Count == 5) { 11125 if (m.Groups.Count == 5)
11126 {
10250 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11127 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10251 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11128 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10252 } 11129 }
@@ -10449,6 +11326,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10449 11326
10450 LSL_List ret = new LSL_List(); 11327 LSL_List ret = new LSL_List();
10451 UUID key = new UUID(); 11328 UUID key = new UUID();
11329
11330
10452 if (UUID.TryParse(id, out key)) 11331 if (UUID.TryParse(id, out key))
10453 { 11332 {
10454 ScenePresence av = World.GetScenePresence(key); 11333 ScenePresence av = World.GetScenePresence(key);
@@ -10466,13 +11345,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10466 ret.Add(new LSL_String("")); 11345 ret.Add(new LSL_String(""));
10467 break; 11346 break;
10468 case ScriptBaseClass.OBJECT_POS: 11347 case ScriptBaseClass.OBJECT_POS:
10469 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11348 Vector3 avpos;
11349
11350 if (av.ParentID != 0 && av.ParentPart != null)
11351 {
11352 avpos = av.OffsetPosition;
11353
11354 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11355 avpos -= sitOffset;
11356
11357 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11358 }
11359 else
11360 avpos = av.AbsolutePosition;
11361
11362 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10470 break; 11363 break;
10471 case ScriptBaseClass.OBJECT_ROT: 11364 case ScriptBaseClass.OBJECT_ROT:
10472 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11365 Quaternion avrot = av.Rotation;
11366 if (av.ParentID != 0 && av.ParentPart != null)
11367 {
11368 avrot = av.ParentPart.GetWorldRotation() * avrot;
11369 }
11370 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10473 break; 11371 break;
10474 case ScriptBaseClass.OBJECT_VELOCITY: 11372 case ScriptBaseClass.OBJECT_VELOCITY:
10475 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11373 Vector3 avvel = av.Velocity;
11374 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10476 break; 11375 break;
10477 case ScriptBaseClass.OBJECT_OWNER: 11376 case ScriptBaseClass.OBJECT_OWNER:
10478 ret.Add(new LSL_String(id)); 11377 ret.Add(new LSL_String(id));
@@ -10528,11 +11427,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10528 case ScriptBaseClass.OBJECT_NAME: 11427 case ScriptBaseClass.OBJECT_NAME:
10529 ret.Add(new LSL_String(obj.Name)); 11428 ret.Add(new LSL_String(obj.Name));
10530 break; 11429 break;
10531 case ScriptBaseClass.OBJECT_DESC: 11430 case ScriptBaseClass.OBJECT_DESC:
10532 ret.Add(new LSL_String(obj.Description)); 11431 ret.Add(new LSL_String(obj.Description));
10533 break; 11432 break;
10534 case ScriptBaseClass.OBJECT_POS: 11433 case ScriptBaseClass.OBJECT_POS:
10535 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11434 Vector3 opos = obj.AbsolutePosition;
11435 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10536 break; 11436 break;
10537 case ScriptBaseClass.OBJECT_ROT: 11437 case ScriptBaseClass.OBJECT_ROT:
10538 { 11438 {
@@ -10582,9 +11482,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10582 // The value returned in SL for normal prims is prim count 11482 // The value returned in SL for normal prims is prim count
10583 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11483 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10584 break; 11484 break;
10585 // The following 3 costs I have intentionaly coded to return zero. They are part of 11485
10586 // "Land Impact" calculations. These calculations are probably not applicable 11486 // costs below may need to be diferent for root parts, need to check
10587 // to OpenSim and are not yet complete in SL
10588 case ScriptBaseClass.OBJECT_SERVER_COST: 11487 case ScriptBaseClass.OBJECT_SERVER_COST:
10589 // The linden calculation is here 11488 // The linden calculation is here
10590 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11489 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10592,16 +11491,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10592 ret.Add(new LSL_Float(0)); 11491 ret.Add(new LSL_Float(0));
10593 break; 11492 break;
10594 case ScriptBaseClass.OBJECT_STREAMING_COST: 11493 case ScriptBaseClass.OBJECT_STREAMING_COST:
10595 // The linden calculation is here 11494 // The value returned in SL for normal prims is prim count * 0.06
10596 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11495 ret.Add(new LSL_Float(obj.StreamingCost));
10597 // The value returned in SL for normal prims looks like the prim count * 0.06
10598 ret.Add(new LSL_Float(0));
10599 break; 11496 break;
10600 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11497 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10601 // The linden calculation is here 11498 // The value returned in SL for normal prims is prim count
10602 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11499 ret.Add(new LSL_Float(obj.PhysicsCost));
10603 // The value returned in SL for normal prims looks like the prim count
10604 ret.Add(new LSL_Float(0));
10605 break; 11500 break;
10606 default: 11501 default:
10607 // Invalid or unhandled constant. 11502 // Invalid or unhandled constant.
@@ -10812,15 +11707,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10812 return result; 11707 return result;
10813 } 11708 }
10814 11709
10815 public void print(string str) 11710 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10816 { 11711 {
10817 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11712 List<SceneObjectPart> parts = GetLinkParts(link);
10818 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11713 if (parts.Count < 1)
10819 if (ossl != null) 11714 return 0;
10820 { 11715
10821 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11716 return GetNumberOfSides(parts[0]);
10822 m_log.Info("LSL print():" + str);
10823 }
10824 } 11717 }
10825 11718
10826 private string Name2Username(string name) 11719 private string Name2Username(string name)
@@ -10865,7 +11758,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10865 11758
10866 return rq.ToString(); 11759 return rq.ToString();
10867 } 11760 }
10868 11761/*
11762 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11763 {
11764 m_SayShoutCount = 0;
11765 }
11766*/
10869 private struct Tri 11767 private struct Tri
10870 { 11768 {
10871 public Vector3 p1; 11769 public Vector3 p1;
@@ -11005,9 +11903,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11005 11903
11006 ContactResult result = new ContactResult (); 11904 ContactResult result = new ContactResult ();
11007 result.ConsumerID = group.LocalId; 11905 result.ConsumerID = group.LocalId;
11008 result.Depth = intersection.distance; 11906// result.Depth = intersection.distance;
11009 result.Normal = intersection.normal; 11907 result.Normal = intersection.normal;
11010 result.Pos = intersection.ipoint; 11908 result.Pos = intersection.ipoint;
11909 result.Depth = Vector3.Mag(rayStart - result.Pos);
11011 11910
11012 contacts.Add(result); 11911 contacts.Add(result);
11013 }); 11912 });
@@ -11140,6 +12039,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11140 12039
11141 return contacts[0]; 12040 return contacts[0];
11142 } 12041 }
12042/*
12043 // not done:
12044 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12045 {
12046 ContactResult[] contacts = null;
12047 World.ForEachSOG(delegate(SceneObjectGroup group)
12048 {
12049 if (m_host.ParentGroup == group)
12050 return;
12051
12052 if (group.IsAttachment)
12053 return;
12054
12055 if(group.RootPart.PhysActor != null)
12056 return;
12057
12058 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12059 });
12060 return contacts;
12061 }
12062*/
11143 12063
11144 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12064 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11145 { 12065 {
@@ -11181,32 +12101,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11181 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12101 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11182 12102
11183 12103
11184 if (checkTerrain) 12104 if (World.SuportsRayCastFiltered())
11185 { 12105 {
11186 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12106 if (dist == 0)
11187 if (groundContact != null) 12107 return list;
11188 results.Add((ContactResult)groundContact);
11189 }
11190 12108
11191 if (checkAgents) 12109 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11192 { 12110 if (checkTerrain)
11193 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12111 rayfilter |= RayFilterFlags.land;
11194 foreach (ContactResult r in agentHits) 12112// if (checkAgents)
11195 results.Add(r); 12113// rayfilter |= RayFilterFlags.agent;
11196 } 12114 if (checkPhysical)
12115 rayfilter |= RayFilterFlags.physical;
12116 if (checkNonPhysical)
12117 rayfilter |= RayFilterFlags.nonphysical;
12118 if (detectPhantom)
12119 rayfilter |= RayFilterFlags.LSLPhanton;
12120
12121 Vector3 direction = dir * ( 1/dist);
12122
12123 if(rayfilter == 0)
12124 {
12125 list.Add(new LSL_Integer(0));
12126 return list;
12127 }
12128
12129 // get some more contacts to sort ???
12130 int physcount = 4 * count;
12131 if (physcount > 20)
12132 physcount = 20;
12133
12134 object physresults;
12135 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12136
12137 if (physresults == null)
12138 {
12139 list.Add(new LSL_Integer(-3)); // timeout error
12140 return list;
12141 }
11197 12142
11198 if (checkPhysical || checkNonPhysical || detectPhantom) 12143 results = (List<ContactResult>)physresults;
12144
12145 // for now physics doesn't detect sitted avatars so do it outside physics
12146 if (checkAgents)
12147 {
12148 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12149 foreach (ContactResult r in agentHits)
12150 results.Add(r);
12151 }
12152
12153 // TODO: Replace this with a better solution. ObjectIntersection can only
12154 // detect nonphysical phantoms. They are detected by virtue of being
12155 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12156 // physicsl phantoms as done by the physics scene
12157 // We don't want anything else but phantoms here.
12158 if (detectPhantom)
12159 {
12160 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12161 foreach (ContactResult r in objectHits)
12162 results.Add(r);
12163 }
12164 }
12165 else
11199 { 12166 {
11200 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12167 if (checkTerrain)
11201 foreach (ContactResult r in objectHits) 12168 {
11202 results.Add(r); 12169 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12170 if (groundContact != null)
12171 results.Add((ContactResult)groundContact);
12172 }
12173
12174 if (checkAgents)
12175 {
12176 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12177 foreach (ContactResult r in agentHits)
12178 results.Add(r);
12179 }
12180
12181 if (checkPhysical || checkNonPhysical || detectPhantom)
12182 {
12183 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12184 foreach (ContactResult r in objectHits)
12185 results.Add(r);
12186 }
11203 } 12187 }
11204 12188
11205 results.Sort(delegate(ContactResult a, ContactResult b) 12189 results.Sort(delegate(ContactResult a, ContactResult b)
11206 { 12190 {
11207 return a.Depth.CompareTo(b.Depth); 12191 return a.Depth.CompareTo(b.Depth);
11208 }); 12192 });
11209 12193
11210 int values = 0; 12194 int values = 0;
11211 SceneObjectGroup thisgrp = m_host.ParentGroup; 12195 SceneObjectGroup thisgrp = m_host.ParentGroup;
11212 12196
@@ -11299,7 +12283,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11299 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12283 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11300 if (!isAccount) return 0; 12284 if (!isAccount) return 0;
11301 if (estate.HasAccess(id)) return 1; 12285 if (estate.HasAccess(id)) return 1;
11302 if (estate.IsBanned(id)) 12286 if (estate.IsBanned(id, World.GetUserFlags(id)))
11303 estate.RemoveBan(id); 12287 estate.RemoveBan(id);
11304 estate.AddEstateUser(id); 12288 estate.AddEstateUser(id);
11305 break; 12289 break;
@@ -11318,14 +12302,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11318 break; 12302 break;
11319 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12303 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11320 if (!isAccount) return 0; 12304 if (!isAccount) return 0;
11321 if (estate.IsBanned(id)) return 1; 12305 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11322 EstateBan ban = new EstateBan(); 12306 EstateBan ban = new EstateBan();
11323 ban.EstateID = estate.EstateID; 12307 ban.EstateID = estate.EstateID;
11324 ban.BannedUserID = id; 12308 ban.BannedUserID = id;
11325 estate.AddBan(ban); 12309 estate.AddBan(ban);
11326 break; 12310 break;
11327 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12311 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11328 if (!isAccount || !estate.IsBanned(id)) return 0; 12312 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11329 estate.RemoveBan(id); 12313 estate.RemoveBan(id);
11330 break; 12314 break;
11331 default: return 0; 12315 default: return 0;
@@ -11354,7 +12338,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11354 return 16384; 12338 return 16384;
11355 } 12339 }
11356 12340
11357 public LSL_Integer llGetUsedMemory() 12341 public virtual LSL_Integer llGetUsedMemory()
11358 { 12342 {
11359 m_host.AddScriptLPS(1); 12343 m_host.AddScriptLPS(1);
11360 // The value returned for LSO scripts in SL 12344 // The value returned for LSO scripts in SL
@@ -11382,22 +12366,731 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11382 public void llSetSoundQueueing(int queue) 12366 public void llSetSoundQueueing(int queue)
11383 { 12367 {
11384 m_host.AddScriptLPS(1); 12368 m_host.AddScriptLPS(1);
11385 NotImplemented("llSetSoundQueueing");
11386 } 12369 }
11387 12370
11388 public void llCollisionSprite(string impact_sprite) 12371 public void llCollisionSprite(string impact_sprite)
11389 { 12372 {
11390 m_host.AddScriptLPS(1); 12373 m_host.AddScriptLPS(1);
11391 NotImplemented("llCollisionSprite"); 12374 // Viewer 2.0 broke this and it's likely LL has no intention
12375 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11392 } 12376 }
11393 12377
11394 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12378 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11395 { 12379 {
11396 m_host.AddScriptLPS(1); 12380 m_host.AddScriptLPS(1);
11397 NotImplemented("llGodLikeRezObject"); 12381
12382 if (!World.Permissions.IsGod(m_host.OwnerID))
12383 NotImplemented("llGodLikeRezObject");
12384
12385 AssetBase rezAsset = World.AssetService.Get(inventory);
12386 if (rezAsset == null)
12387 {
12388 llSay(0, "Asset not found");
12389 return;
12390 }
12391
12392 SceneObjectGroup group = null;
12393
12394 try
12395 {
12396 string xmlData = Utils.BytesToString(rezAsset.Data);
12397 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12398 }
12399 catch
12400 {
12401 llSay(0, "Asset not found");
12402 return;
12403 }
12404
12405 if (group == null)
12406 {
12407 llSay(0, "Asset not found");
12408 return;
12409 }
12410
12411 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12412 group.RootPart.AttachOffset = group.AbsolutePosition;
12413
12414 group.ResetIDs();
12415
12416 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12417 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12418 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12419 group.ScheduleGroupForFullUpdate();
12420
12421 // objects rezzed with this method are die_at_edge by default.
12422 group.RootPart.SetDieAtEdge(true);
12423
12424 group.ResumeScripts();
12425
12426 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12427 "object_rez", new Object[] {
12428 new LSL_String(
12429 group.RootPart.UUID.ToString()) },
12430 new DetectParams[0]));
12431 }
12432
12433 public LSL_String llTransferLindenDollars(string destination, int amount)
12434 {
12435 UUID txn = UUID.Random();
12436
12437 Util.FireAndForget(delegate(object x)
12438 {
12439 int replycode = 0;
12440 string replydata = destination + "," + amount.ToString();
12441
12442 try
12443 {
12444 TaskInventoryItem item = m_item;
12445 if (item == null)
12446 {
12447 replydata = "SERVICE_ERROR";
12448 return;
12449 }
12450
12451 m_host.AddScriptLPS(1);
12452
12453 if (item.PermsGranter == UUID.Zero)
12454 {
12455 replydata = "MISSING_PERMISSION_DEBIT";
12456 return;
12457 }
12458
12459 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12460 {
12461 replydata = "MISSING_PERMISSION_DEBIT";
12462 return;
12463 }
12464
12465 UUID toID = new UUID();
12466
12467 if (!UUID.TryParse(destination, out toID))
12468 {
12469 replydata = "INVALID_AGENT";
12470 return;
12471 }
12472
12473 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12474
12475 if (money == null)
12476 {
12477 replydata = "TRANSFERS_DISABLED";
12478 return;
12479 }
12480
12481 bool result = money.ObjectGiveMoney(
12482 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12483
12484 if (result)
12485 {
12486 replycode = 1;
12487 return;
12488 }
12489
12490 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12491 }
12492 finally
12493 {
12494 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12495 "transaction_result", new Object[] {
12496 new LSL_String(txn.ToString()),
12497 new LSL_Integer(replycode),
12498 new LSL_String(replydata) },
12499 new DetectParams[0]));
12500 }
12501 });
12502
12503 return txn.ToString();
11398 } 12504 }
11399 12505
11400 #endregion 12506 #endregion
12507
12508 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12509 {
12510 SceneObjectGroup group = m_host.ParentGroup;
12511
12512 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12513 return;
12514 if (group.IsAttachment)
12515 return;
12516
12517 if (frames.Data.Length > 0) // We are getting a new motion
12518 {
12519 if (group.RootPart.KeyframeMotion != null)
12520 group.RootPart.KeyframeMotion.Delete();
12521 group.RootPart.KeyframeMotion = null;
12522
12523 int idx = 0;
12524
12525 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12526 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12527
12528 while (idx < options.Data.Length)
12529 {
12530 int option = (int)options.GetLSLIntegerItem(idx++);
12531 int remain = options.Data.Length - idx;
12532
12533 switch (option)
12534 {
12535 case ScriptBaseClass.KFM_MODE:
12536 if (remain < 1)
12537 break;
12538 int modeval = (int)options.GetLSLIntegerItem(idx++);
12539 switch(modeval)
12540 {
12541 case ScriptBaseClass.KFM_FORWARD:
12542 mode = KeyframeMotion.PlayMode.Forward;
12543 break;
12544 case ScriptBaseClass.KFM_REVERSE:
12545 mode = KeyframeMotion.PlayMode.Reverse;
12546 break;
12547 case ScriptBaseClass.KFM_LOOP:
12548 mode = KeyframeMotion.PlayMode.Loop;
12549 break;
12550 case ScriptBaseClass.KFM_PING_PONG:
12551 mode = KeyframeMotion.PlayMode.PingPong;
12552 break;
12553 }
12554 break;
12555 case ScriptBaseClass.KFM_DATA:
12556 if (remain < 1)
12557 break;
12558 int dataval = (int)options.GetLSLIntegerItem(idx++);
12559 data = (KeyframeMotion.DataFormat)dataval;
12560 break;
12561 }
12562 }
12563
12564 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12565
12566 idx = 0;
12567
12568 int elemLength = 2;
12569 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12570 elemLength = 3;
12571
12572 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12573 while (idx < frames.Data.Length)
12574 {
12575 int remain = frames.Data.Length - idx;
12576
12577 if (remain < elemLength)
12578 break;
12579
12580 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12581 frame.Position = null;
12582 frame.Rotation = null;
12583
12584 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12585 {
12586 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12587 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12588 }
12589 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12590 {
12591 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12592 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12593 }
12594
12595 float tempf = (float)frames.GetLSLFloatItem(idx++);
12596 frame.TimeMS = (int)(tempf * 1000.0f);
12597
12598 keyframes.Add(frame);
12599 }
12600
12601 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12602 group.RootPart.KeyframeMotion.Start();
12603 }
12604 else
12605 {
12606 if (group.RootPart.KeyframeMotion == null)
12607 return;
12608
12609 if (options.Data.Length == 0)
12610 {
12611 group.RootPart.KeyframeMotion.Stop();
12612 return;
12613 }
12614
12615 int code = (int)options.GetLSLIntegerItem(0);
12616
12617 int idx = 0;
12618
12619 while (idx < options.Data.Length)
12620 {
12621 int option = (int)options.GetLSLIntegerItem(idx++);
12622 int remain = options.Data.Length - idx;
12623
12624 switch (option)
12625 {
12626 case ScriptBaseClass.KFM_COMMAND:
12627 int cmd = (int)options.GetLSLIntegerItem(idx++);
12628 switch (cmd)
12629 {
12630 case ScriptBaseClass.KFM_CMD_PLAY:
12631 group.RootPart.KeyframeMotion.Start();
12632 break;
12633 case ScriptBaseClass.KFM_CMD_STOP:
12634 group.RootPart.KeyframeMotion.Stop();
12635 break;
12636 case ScriptBaseClass.KFM_CMD_PAUSE:
12637 group.RootPart.KeyframeMotion.Pause();
12638 break;
12639 }
12640 break;
12641 }
12642 }
12643 }
12644 }
12645
12646 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12647 {
12648 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12649
12650 int idx = 0;
12651 int idxStart = 0;
12652
12653 bool positionChanged = false;
12654 Vector3 finalPos = Vector3.Zero;
12655
12656 try
12657 {
12658 while (idx < rules.Length)
12659 {
12660 ++rulesParsed;
12661 int code = rules.GetLSLIntegerItem(idx++);
12662
12663 int remain = rules.Length - idx;
12664 idxStart = idx;
12665
12666 switch (code)
12667 {
12668 case (int)ScriptBaseClass.PRIM_POSITION:
12669 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12670 {
12671 if (remain < 1)
12672 return null;
12673
12674 LSL_Vector v;
12675 v = rules.GetVector3Item(idx++);
12676
12677 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12678 if (part == null)
12679 break;
12680
12681 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12682 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12683 if (part.LinkNum > 1)
12684 {
12685 localRot = GetPartLocalRot(part);
12686 localPos = GetPartLocalPos(part);
12687 }
12688
12689 v -= localPos;
12690 v /= localRot;
12691
12692 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12693
12694 v = v + 2 * sitOffset;
12695
12696 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12697 av.SendAvatarDataToAllAgents();
12698
12699 }
12700 break;
12701
12702 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12703 case (int)ScriptBaseClass.PRIM_ROTATION:
12704 {
12705 if (remain < 1)
12706 return null;
12707
12708 LSL_Rotation r;
12709 r = rules.GetQuaternionItem(idx++);
12710
12711 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12712 if (part == null)
12713 break;
12714
12715 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12716 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12717
12718 if (part.LinkNum > 1)
12719 localRot = GetPartLocalRot(part);
12720
12721 r = r * llGetRootRotation() / localRot;
12722 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12723 av.SendAvatarDataToAllAgents();
12724 }
12725 break;
12726
12727 // parse rest doing nothing but number of parameters error check
12728 case (int)ScriptBaseClass.PRIM_SIZE:
12729 case (int)ScriptBaseClass.PRIM_MATERIAL:
12730 case (int)ScriptBaseClass.PRIM_PHANTOM:
12731 case (int)ScriptBaseClass.PRIM_PHYSICS:
12732 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12733 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12734 case (int)ScriptBaseClass.PRIM_NAME:
12735 case (int)ScriptBaseClass.PRIM_DESC:
12736 if (remain < 1)
12737 return null;
12738 idx++;
12739 break;
12740
12741 case (int)ScriptBaseClass.PRIM_GLOW:
12742 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12743 case (int)ScriptBaseClass.PRIM_TEXGEN:
12744 if (remain < 2)
12745 return null;
12746 idx += 2;
12747 break;
12748
12749 case (int)ScriptBaseClass.PRIM_TYPE:
12750 if (remain < 3)
12751 return null;
12752 code = (int)rules.GetLSLIntegerItem(idx++);
12753 remain = rules.Length - idx;
12754 switch (code)
12755 {
12756 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12757 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12758 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12759 if (remain < 6)
12760 return null;
12761 idx += 6;
12762 break;
12763
12764 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12765 if (remain < 5)
12766 return null;
12767 idx += 5;
12768 break;
12769
12770 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12771 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12772 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12773 if (remain < 11)
12774 return null;
12775 idx += 11;
12776 break;
12777
12778 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12779 if (remain < 2)
12780 return null;
12781 idx += 2;
12782 break;
12783 }
12784 break;
12785
12786 case (int)ScriptBaseClass.PRIM_COLOR:
12787 case (int)ScriptBaseClass.PRIM_TEXT:
12788 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12789 case (int)ScriptBaseClass.PRIM_OMEGA:
12790 if (remain < 3)
12791 return null;
12792 idx += 3;
12793 break;
12794
12795 case (int)ScriptBaseClass.PRIM_TEXTURE:
12796 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12797 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12798 if (remain < 5)
12799 return null;
12800 idx += 5;
12801 break;
12802
12803 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12804 if (remain < 7)
12805 return null;
12806
12807 idx += 7;
12808 break;
12809
12810 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12811 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12812 return null;
12813
12814 return rules.GetSublist(idx, -1);
12815 }
12816 }
12817 }
12818 catch (InvalidCastException e)
12819 {
12820 ShoutError(string.Format(
12821 "{0} error running rule #{1}: arg #{2} ",
12822 originFunc, rulesParsed, idx - idxStart) + e.Message);
12823 }
12824 finally
12825 {
12826 if (positionChanged)
12827 {
12828 av.OffsetPosition = finalPos;
12829// av.SendAvatarDataToAllAgents();
12830 av.SendTerseUpdateToAllClients();
12831 positionChanged = false;
12832 }
12833 }
12834 return null;
12835 }
12836
12837 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12838 {
12839 // avatars case
12840 // replies as SL wiki
12841
12842// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12843 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12844
12845 int idx = 0;
12846 while (idx < rules.Length)
12847 {
12848 int code = (int)rules.GetLSLIntegerItem(idx++);
12849 int remain = rules.Length - idx;
12850
12851 switch (code)
12852 {
12853 case (int)ScriptBaseClass.PRIM_MATERIAL:
12854 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12855 break;
12856
12857 case (int)ScriptBaseClass.PRIM_PHYSICS:
12858 res.Add(new LSL_Integer(0));
12859 break;
12860
12861 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12862 res.Add(new LSL_Integer(0));
12863 break;
12864
12865 case (int)ScriptBaseClass.PRIM_PHANTOM:
12866 res.Add(new LSL_Integer(0));
12867 break;
12868
12869 case (int)ScriptBaseClass.PRIM_POSITION:
12870
12871 Vector3 pos = avatar.OffsetPosition;
12872
12873 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12874 pos -= sitOffset;
12875
12876 if( sitPart != null)
12877 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12878
12879 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12880 break;
12881
12882 case (int)ScriptBaseClass.PRIM_SIZE:
12883 // as in llGetAgentSize above
12884 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12885 break;
12886
12887 case (int)ScriptBaseClass.PRIM_ROTATION:
12888 Quaternion rot = avatar.Rotation;
12889 if (sitPart != null)
12890 {
12891 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12892 }
12893
12894 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12895 break;
12896
12897 case (int)ScriptBaseClass.PRIM_TYPE:
12898 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12899 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12900 res.Add(new LSL_Vector(0f,1.0f,0f));
12901 res.Add(new LSL_Float(0.0f));
12902 res.Add(new LSL_Vector(0, 0, 0));
12903 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12904 res.Add(new LSL_Vector(0, 0, 0));
12905 break;
12906
12907 case (int)ScriptBaseClass.PRIM_TEXTURE:
12908 if (remain < 1)
12909 return null;
12910
12911 int face = (int)rules.GetLSLIntegerItem(idx++);
12912 if (face == ScriptBaseClass.ALL_SIDES)
12913 {
12914 for (face = 0; face < 21; face++)
12915 {
12916 res.Add(new LSL_String(""));
12917 res.Add(new LSL_Vector(0,0,0));
12918 res.Add(new LSL_Vector(0,0,0));
12919 res.Add(new LSL_Float(0.0));
12920 }
12921 }
12922 else
12923 {
12924 if (face >= 0 && face < 21)
12925 {
12926 res.Add(new LSL_String(""));
12927 res.Add(new LSL_Vector(0,0,0));
12928 res.Add(new LSL_Vector(0,0,0));
12929 res.Add(new LSL_Float(0.0));
12930 }
12931 }
12932 break;
12933
12934 case (int)ScriptBaseClass.PRIM_COLOR:
12935 if (remain < 1)
12936 return null;
12937
12938 face = (int)rules.GetLSLIntegerItem(idx++);
12939
12940 if (face == ScriptBaseClass.ALL_SIDES)
12941 {
12942 for (face = 0; face < 21; face++)
12943 {
12944 res.Add(new LSL_Vector(0,0,0));
12945 res.Add(new LSL_Float(0));
12946 }
12947 }
12948 else
12949 {
12950 res.Add(new LSL_Vector(0,0,0));
12951 res.Add(new LSL_Float(0));
12952 }
12953 break;
12954
12955 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12956 if (remain < 1)
12957 return null;
12958 face = (int)rules.GetLSLIntegerItem(idx++);
12959
12960 if (face == ScriptBaseClass.ALL_SIDES)
12961 {
12962 for (face = 0; face < 21; face++)
12963 {
12964 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12965 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12966 }
12967 }
12968 else
12969 {
12970 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12971 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12972 }
12973 break;
12974
12975 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12976 if (remain < 1)
12977 return null;
12978 face = (int)rules.GetLSLIntegerItem(idx++);
12979
12980 if (face == ScriptBaseClass.ALL_SIDES)
12981 {
12982 for (face = 0; face < 21; face++)
12983 {
12984 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12985 }
12986 }
12987 else
12988 {
12989 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12990 }
12991 break;
12992
12993 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12994 res.Add(new LSL_Integer(0));
12995 res.Add(new LSL_Integer(0));// softness
12996 res.Add(new LSL_Float(0.0f)); // gravity
12997 res.Add(new LSL_Float(0.0f)); // friction
12998 res.Add(new LSL_Float(0.0f)); // wind
12999 res.Add(new LSL_Float(0.0f)); // tension
13000 res.Add(new LSL_Vector(0f,0f,0f));
13001 break;
13002
13003 case (int)ScriptBaseClass.PRIM_TEXGEN:
13004 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13005 if (remain < 1)
13006 return null;
13007 face = (int)rules.GetLSLIntegerItem(idx++);
13008
13009 if (face == ScriptBaseClass.ALL_SIDES)
13010 {
13011 for (face = 0; face < 21; face++)
13012 {
13013 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13014 }
13015 }
13016 else
13017 {
13018 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13019 }
13020 break;
13021
13022 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13023 res.Add(new LSL_Integer(0));
13024 res.Add(new LSL_Vector(0f,0f,0f));
13025 res.Add(new LSL_Float(0f)); // intensity
13026 res.Add(new LSL_Float(0f)); // radius
13027 res.Add(new LSL_Float(0f)); // falloff
13028 break;
13029
13030 case (int)ScriptBaseClass.PRIM_GLOW:
13031 if (remain < 1)
13032 return null;
13033 face = (int)rules.GetLSLIntegerItem(idx++);
13034
13035 if (face == ScriptBaseClass.ALL_SIDES)
13036 {
13037 for (face = 0; face < 21; face++)
13038 {
13039 res.Add(new LSL_Float(0f));
13040 }
13041 }
13042 else
13043 {
13044 res.Add(new LSL_Float(0f));
13045 }
13046 break;
13047
13048 case (int)ScriptBaseClass.PRIM_TEXT:
13049 res.Add(new LSL_String(""));
13050 res.Add(new LSL_Vector(0f,0f,0f));
13051 res.Add(new LSL_Float(1.0f));
13052 break;
13053
13054 case (int)ScriptBaseClass.PRIM_NAME:
13055 res.Add(new LSL_String(avatar.Name));
13056 break;
13057
13058 case (int)ScriptBaseClass.PRIM_DESC:
13059 res.Add(new LSL_String(""));
13060 break;
13061
13062 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13063 Quaternion lrot = avatar.Rotation;
13064
13065 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13066 {
13067 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13068 }
13069 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13070 break;
13071
13072 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13073 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13074 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13075 lpos -= lsitOffset;
13076
13077 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13078 {
13079 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13080 }
13081 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13082 break;
13083
13084 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13085 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13086 return null;
13087
13088 return rules.GetSublist(idx, -1);
13089 }
13090 }
13091
13092 return null;
13093 }
11401 } 13094 }
11402 13095
11403 public class NotecardCache 13096 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 2e1e5b6..a44ced4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -138,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
139 internal float m_ScriptDelayFactor = 1.0f; 139 internal float m_ScriptDelayFactor = 1.0f;
140 internal float m_ScriptDistanceFactor = 1.0f; 140 internal float m_ScriptDistanceFactor = 1.0f;
141 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 143
143 protected IUrlModule m_UrlModule = null; 144 protected IUrlModule m_UrlModule = null;
@@ -147,6 +148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
147 m_ScriptEngine = ScriptEngine; 148 m_ScriptEngine = ScriptEngine;
148 m_host = host; 149 m_host = host;
149 m_item = item; 150 m_item = item;
151 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
150 152
151 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 153 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
152 154
@@ -210,7 +212,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
210 212
211 internal void OSSLError(string msg) 213 internal void OSSLError(string msg)
212 { 214 {
213 throw new Exception("OSSL Runtime Error: " + msg); 215 if (m_debuggerSafe)
216 {
217 OSSLShoutError(msg);
218 }
219 else
220 {
221 throw new Exception("OSSL Runtime Error: " + msg);
222 }
214 } 223 }
215 224
216 /// <summary> 225 /// <summary>
@@ -918,18 +927,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
918 if (target != null) 927 if (target != null)
919 { 928 {
920 UUID animID=UUID.Zero; 929 UUID animID=UUID.Zero;
921 lock (m_host.TaskInventory) 930 m_host.TaskInventory.LockItemsForRead(true);
931 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
922 { 932 {
923 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 933 if (inv.Value.Name == animation)
924 { 934 {
925 if (inv.Value.Name == animation) 935 if (inv.Value.Type == (int)AssetType.Animation)
926 { 936 animID = inv.Value.AssetID;
927 if (inv.Value.Type == (int)AssetType.Animation) 937 continue;
928 animID = inv.Value.AssetID;
929 continue;
930 }
931 } 938 }
932 } 939 }
940 m_host.TaskInventory.LockItemsForRead(false);
933 if (animID == UUID.Zero) 941 if (animID == UUID.Zero)
934 target.Animator.AddAnimation(animation, m_host.UUID); 942 target.Animator.AddAnimation(animation, m_host.UUID);
935 else 943 else
@@ -970,6 +978,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
970 else 978 else
971 animID = UUID.Zero; 979 animID = UUID.Zero;
972 } 980 }
981 m_host.TaskInventory.LockItemsForRead(false);
973 982
974 if (animID == UUID.Zero) 983 if (animID == UUID.Zero)
975 target.Animator.RemoveAnimation(animation); 984 target.Animator.RemoveAnimation(animation);
@@ -1808,6 +1817,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1808 1817
1809 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1818 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1810 { 1819 {
1820 m_host.TaskInventory.LockItemsForRead(true);
1811 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1821 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1812 { 1822 {
1813 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1823 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1815,6 +1825,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1815 assetID = item.AssetID; 1825 assetID = item.AssetID;
1816 } 1826 }
1817 } 1827 }
1828 m_host.TaskInventory.LockItemsForRead(false);
1818 } 1829 }
1819 1830
1820 if (assetID == UUID.Zero) 1831 if (assetID == UUID.Zero)
@@ -2300,7 +2311,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2300 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2311 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2301 m_host.AddScriptLPS(1); 2312 m_host.AddScriptLPS(1);
2302 2313
2303 return NpcCreate(firstname, lastname, position, notecard, false, false); 2314 return NpcCreate(firstname, lastname, position, notecard, true, false);
2304 } 2315 }
2305 2316
2306 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2317 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2311,24 +2322,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2311 return NpcCreate( 2322 return NpcCreate(
2312 firstname, lastname, position, notecard, 2323 firstname, lastname, position, notecard,
2313 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2324 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2314 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2325 false);
2326// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2315 } 2327 }
2316 2328
2317 private LSL_Key NpcCreate( 2329 private LSL_Key NpcCreate(
2318 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2330 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2319 { 2331 {
2332 if (!owned)
2333 OSSLError("Unowned NPCs are unsupported");
2334
2335 string groupTitle = String.Empty;
2336
2337 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2338 return new LSL_Key(UUID.Zero.ToString());
2339
2340 if (firstname != String.Empty || lastname != String.Empty)
2341 {
2342 if (firstname != "Shown outfit:")
2343 groupTitle = "- NPC -";
2344 }
2345
2320 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2346 INPCModule module = World.RequestModuleInterface<INPCModule>();
2321 if (module != null) 2347 if (module != null)
2322 { 2348 {
2323 AvatarAppearance appearance = null; 2349 AvatarAppearance appearance = null;
2324 2350
2325 UUID id; 2351// UUID id;
2326 if (UUID.TryParse(notecard, out id)) 2352// if (UUID.TryParse(notecard, out id))
2327 { 2353// {
2328 ScenePresence clonePresence = World.GetScenePresence(id); 2354// ScenePresence clonePresence = World.GetScenePresence(id);
2329 if (clonePresence != null) 2355// if (clonePresence != null)
2330 appearance = clonePresence.Appearance; 2356// appearance = clonePresence.Appearance;
2331 } 2357// }
2332 2358
2333 if (appearance == null) 2359 if (appearance == null)
2334 { 2360 {
@@ -2356,6 +2382,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2356 World, 2382 World,
2357 appearance); 2383 appearance);
2358 2384
2385 ScenePresence sp;
2386 if (World.TryGetScenePresence(x, out sp))
2387 {
2388 sp.Grouptitle = groupTitle;
2389 sp.SendAvatarDataToAllAgents();
2390 }
2359 return new LSL_Key(x.ToString()); 2391 return new LSL_Key(x.ToString());
2360 } 2392 }
2361 2393
@@ -2655,16 +2687,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2655 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2687 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2656 m_host.AddScriptLPS(1); 2688 m_host.AddScriptLPS(1);
2657 2689
2658 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2690 ManualResetEvent ev = new ManualResetEvent(false);
2659 if (module != null)
2660 {
2661 UUID npcId = new UUID(npc.m_string);
2662 2691
2663 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2692 Util.FireAndForget(delegate(object x) {
2664 return; 2693 try
2694 {
2695 INPCModule module = World.RequestModuleInterface<INPCModule>();
2696 if (module != null)
2697 {
2698 UUID npcId = new UUID(npc.m_string);
2665 2699
2666 module.DeleteNPC(npcId, World); 2700 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2667 } 2701 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2702 {
2703 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2704 return;
2705 }
2706
2707 module.DeleteNPC(npcId, World);
2708 }
2709 }
2710 finally
2711 {
2712 ev.Set();
2713 }
2714 });
2715 ev.WaitOne();
2668 } 2716 }
2669 2717
2670 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2718 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3549,6 +3597,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3549 if (m_UrlModule != null) 3597 if (m_UrlModule != null)
3550 m_UrlModule.HttpContentType(new UUID(id),type); 3598 m_UrlModule.HttpContentType(new UUID(id),type);
3551 } 3599 }
3552 3600 }
3553 } 3601}
3554} \ No newline at end of file
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 3985e66..0ea363a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -144,7 +144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
144 // Avatar Info Commands 144 // Avatar Info Commands
145 string osGetAgentIP(string agent); 145 string osGetAgentIP(string agent);
146 LSL_List osGetAgents(); 146 LSL_List osGetAgents();
147 147
148 // Teleport commands 148 // Teleport commands
149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 60a7e14..c788407 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -56,7 +56,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
56 public const int ACTIVE = 2; 56 public const int ACTIVE = 2;
57 public const int PASSIVE = 4; 57 public const int PASSIVE = 4;
58 public const int SCRIPTED = 8; 58 public const int SCRIPTED = 8;
59 public const int OS_NPC = 0x01000000;
60 59
61 public const int CONTROL_FWD = 1; 60 public const int CONTROL_FWD = 1;
62 public const int CONTROL_BACK = 2; 61 public const int CONTROL_BACK = 2;
@@ -95,6 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
95 public const int AGENT_CROUCHING = 1024; 94 public const int AGENT_CROUCHING = 1024;
96 public const int AGENT_BUSY = 2048; 95 public const int AGENT_BUSY = 2048;
97 public const int AGENT_ALWAYS_RUN = 4096; 96 public const int AGENT_ALWAYS_RUN = 4096;
97 public const int AGENT_MALE = 8192;
98 98
99 //Particle Systems 99 //Particle Systems
100 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 100 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -337,6 +337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
337 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 337 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
338 public const int CHANGED_MEDIA = 2048; 338 public const int CHANGED_MEDIA = 2048;
339 public const int CHANGED_ANIMATION = 16384; 339 public const int CHANGED_ANIMATION = 16384;
340 public const int CHANGED_POSITION = 32768;
340 public const int TYPE_INVALID = 0; 341 public const int TYPE_INVALID = 0;
341 public const int TYPE_INTEGER = 1; 342 public const int TYPE_INTEGER = 1;
342 public const int TYPE_FLOAT = 2; 343 public const int TYPE_FLOAT = 2;
@@ -642,6 +643,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
642 public const int PRIM_MEDIA_PERM_OWNER = 1; 643 public const int PRIM_MEDIA_PERM_OWNER = 1;
643 public const int PRIM_MEDIA_PERM_GROUP = 2; 644 public const int PRIM_MEDIA_PERM_GROUP = 2;
644 public const int PRIM_MEDIA_PERM_ANYONE = 4; 645 public const int PRIM_MEDIA_PERM_ANYONE = 4;
646
647 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
648 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
649 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
650 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
651
652 public const int PRIM_PHYSICS_MATERIAL = 31;
653 public const int DENSITY = 1;
654 public const int FRICTION = 2;
655 public const int RESTITUTION = 4;
656 public const int GRAVITY_MULTIPLIER = 8;
645 657
646 // extra constants for llSetPrimMediaParams 658 // extra constants for llSetPrimMediaParams
647 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 659 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -714,6 +726,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
714 726
715 public static readonly LSLInteger RCERR_UNKNOWN = -1; 727 public static readonly LSLInteger RCERR_UNKNOWN = -1;
716 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 728 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
717 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 729 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
730
731 public const int KFM_MODE = 1;
732 public const int KFM_LOOP = 1;
733 public const int KFM_REVERSE = 3;
734 public const int KFM_FORWARD = 0;
735 public const int KFM_PING_PONG = 2;
736 public const int KFM_DATA = 2;
737 public const int KFM_TRANSLATION = 2;
738 public const int KFM_ROTATION = 1;
739 public const int KFM_COMMAND = 0;
740 public const int KFM_CMD_PLAY = 0;
741 public const int KFM_CMD_STOP = 1;
742 public const int KFM_CMD_PAUSE = 2;
718 } 743 }
719} 744}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index c457880..89b6eff 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -314,6 +315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 315 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 316 }
316 317
318 [DebuggerNonUserCode]
317 public void llDie() 319 public void llDie()
318 { 320 {
319 m_LSL_Functions.llDie(); 321 m_LSL_Functions.llDie();
@@ -474,6 +476,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
474 return m_LSL_Functions.llGetFreeMemory(); 476 return m_LSL_Functions.llGetFreeMemory();
475 } 477 }
476 478
479 public LSL_Integer llGetUsedMemory()
480 {
481 return m_LSL_Functions.llGetUsedMemory();
482 }
483
477 public LSL_Integer llGetFreeURLs() 484 public LSL_Integer llGetFreeURLs()
478 { 485 {
479 return m_LSL_Functions.llGetFreeURLs(); 486 return m_LSL_Functions.llGetFreeURLs();
@@ -579,6 +586,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
579 return m_LSL_Functions.llGetMass(); 586 return m_LSL_Functions.llGetMass();
580 } 587 }
581 588
589 public LSL_Float llGetMassMKS()
590 {
591 return m_LSL_Functions.llGetMassMKS();
592 }
593
582 public LSL_Integer llGetMemoryLimit() 594 public LSL_Integer llGetMemoryLimit()
583 { 595 {
584 return m_LSL_Functions.llGetMemoryLimit(); 596 return m_LSL_Functions.llGetMemoryLimit();
@@ -844,11 +856,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
844 return m_LSL_Functions.llGetUnixTime(); 856 return m_LSL_Functions.llGetUnixTime();
845 } 857 }
846 858
847 public LSL_Integer llGetUsedMemory()
848 {
849 return m_LSL_Functions.llGetUsedMemory();
850 }
851
852 public LSL_Vector llGetVel() 859 public LSL_Vector llGetVel()
853 { 860 {
854 return m_LSL_Functions.llGetVel(); 861 return m_LSL_Functions.llGetVel();
@@ -874,6 +881,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
874 return m_LSL_Functions.llGiveMoney(destination, amount); 881 return m_LSL_Functions.llGiveMoney(destination, amount);
875 } 882 }
876 883
884 public LSL_String llTransferLindenDollars(string destination, int amount)
885 {
886 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
887 }
888
877 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 889 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
878 { 890 {
879 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 891 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1483,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1483 m_LSL_Functions.llSetAlpha(alpha, face); 1495 m_LSL_Functions.llSetAlpha(alpha, face);
1484 } 1496 }
1485 1497
1498 public void llSetAngularVelocity(LSL_Vector angvelocity, int local)
1499 {
1500 m_LSL_Functions.llSetAngularVelocity(angvelocity, local);
1501 }
1502
1486 public void llSetBuoyancy(double buoyancy) 1503 public void llSetBuoyancy(double buoyancy)
1487 { 1504 {
1488 m_LSL_Functions.llSetBuoyancy(buoyancy); 1505 m_LSL_Functions.llSetBuoyancy(buoyancy);
@@ -1603,6 +1620,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1603 m_LSL_Functions.llSetPos(pos); 1620 m_LSL_Functions.llSetPos(pos);
1604 } 1621 }
1605 1622
1623 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1624 {
1625 return m_LSL_Functions.llSetRegionPos(pos);
1626 }
1627
1606 public void llSetPrimitiveParams(LSL_List rules) 1628 public void llSetPrimitiveParams(LSL_List rules)
1607 { 1629 {
1608 m_LSL_Functions.llSetPrimitiveParams(rules); 1630 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1618,11 +1640,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1618 m_LSL_Functions.llSetPrimURL(url); 1640 m_LSL_Functions.llSetPrimURL(url);
1619 } 1641 }
1620 1642
1621 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1622 {
1623 return m_LSL_Functions.llSetRegionPos(pos);
1624 }
1625
1626 public void llSetRemoteScriptAccessPin(int pin) 1643 public void llSetRemoteScriptAccessPin(int pin)
1627 { 1644 {
1628 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1645 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1718,6 +1735,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1718 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1735 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1719 } 1736 }
1720 1737
1738 public void llSetVelocity(LSL_Vector velocity, int local)
1739 {
1740 m_LSL_Functions.llSetVelocity(velocity, local);
1741 }
1742
1721 public void llShout(int channelID, string text) 1743 public void llShout(int channelID, string text)
1722 { 1744 {
1723 m_LSL_Functions.llShout(channelID, text); 1745 m_LSL_Functions.llShout(channelID, text);
@@ -1968,9 +1990,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1968 return m_LSL_Functions.llClearLinkMedia(link, face); 1990 return m_LSL_Functions.llClearLinkMedia(link, face);
1969 } 1991 }
1970 1992
1971 public void print(string str) 1993 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1994 {
1995 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1996 }
1997
1998 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1999 {
2000 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2001 }
2002
2003 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1972 { 2004 {
1973 m_LSL_Functions.print(str); 2005 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1974 } 2006 }
1975 } 2007 }
1976} 2008}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 5a58f73..22804f5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
39 40
40namespace OpenSim.Region.ScriptEngine.Shared 41namespace OpenSim.Region.ScriptEngine.Shared
@@ -102,6 +103,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
102 Type = 0; 103 Type = 0;
103 Velocity = new LSL_Types.Vector3(); 104 Velocity = new LSL_Types.Vector3();
104 initializeSurfaceTouch(); 105 initializeSurfaceTouch();
106 Country = String.Empty;
105 } 107 }
106 108
107 public UUID Key; 109 public UUID Key;
@@ -133,6 +135,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
133 private int touchFace; 135 private int touchFace;
134 public int TouchFace { get { return touchFace; } } 136 public int TouchFace { get { return touchFace; } }
135 137
138 public string Country;
139
136 // This can be done in two places including the constructor 140 // This can be done in two places including the constructor
137 // so be carefull what gets added here 141 // so be carefull what gets added here
138 private void initializeSurfaceTouch() 142 private void initializeSurfaceTouch()
@@ -180,6 +184,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
180 return; 184 return;
181 185
182 Name = presence.Firstname + " " + presence.Lastname; 186 Name = presence.Firstname + " " + presence.Lastname;
187 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
188 if (account != null)
189 Country = account.UserCountry;
190
183 Owner = Key; 191 Owner = Key;
184 Position = new LSL_Types.Vector3(presence.AbsolutePosition); 192 Position = new LSL_Types.Vector3(presence.AbsolutePosition);
185 Rotation = new LSL_Types.Quaternion( 193 Rotation = new LSL_Types.Quaternion(
@@ -189,22 +197,27 @@ namespace OpenSim.Region.ScriptEngine.Shared
189 presence.Rotation.W); 197 presence.Rotation.W);
190 Velocity = new LSL_Types.Vector3(presence.Velocity); 198 Velocity = new LSL_Types.Vector3(presence.Velocity);
191 199
192 if (presence.PresenceType != PresenceType.Npc) 200 Type = 0x01; // Avatar
193 { 201 if (presence.PresenceType == PresenceType.Npc)
194 Type = AGENT; 202 Type = 0x20;
195 } 203
196 else 204 // Cope Impl. We don't use OS_NPC.
197 { 205 //if (presence.PresenceType != PresenceType.Npc)
198 Type = OS_NPC; 206 //{
199 207 // Type = AGENT;
200 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 208 //}
201 INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); 209 //else
202 210 //{
203 if (npcData.SenseAsAgent) 211 // Type = OS_NPC;
204 { 212
205 Type |= AGENT; 213 // INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
206 } 214 // INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
207 } 215
216 // if (npcData.SenseAsAgent)
217 // {
218 // Type |= AGENT;
219 // }
220 //}
208 221
209 if (presence.Velocity != Vector3.Zero) 222 if (presence.Velocity != Vector3.Zero)
210 Type |= ACTIVE; 223 Type |= ACTIVE;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 5793cc9..771db0c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Reflection; 34using System.Reflection;
34using System.Runtime.Remoting; 35using System.Runtime.Remoting;
35using System.Runtime.Remoting.Lifetime; 36using System.Runtime.Remoting.Lifetime;
@@ -219,13 +220,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
219 220
220 if (part != null) 221 if (part != null)
221 { 222 {
222 lock (part.TaskInventory) 223 part.TaskInventory.LockItemsForRead(true);
224 if (part.TaskInventory.ContainsKey(ItemID))
223 { 225 {
224 if (part.TaskInventory.ContainsKey(ItemID)) 226 ScriptTask = part.TaskInventory[ItemID];
225 {
226 ScriptTask = part.TaskInventory[ItemID];
227 }
228 } 227 }
228 part.TaskInventory.LockItemsForRead(false);
229 } 229 }
230 230
231 ApiManager am = new ApiManager(); 231 ApiManager am = new ApiManager();
@@ -417,14 +417,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
417 { 417 {
418 int permsMask; 418 int permsMask;
419 UUID permsGranter; 419 UUID permsGranter;
420 lock (part.TaskInventory) 420 part.TaskInventory.LockItemsForRead(true);
421 if (!part.TaskInventory.ContainsKey(ItemID))
421 { 422 {
422 if (!part.TaskInventory.ContainsKey(ItemID)) 423 part.TaskInventory.LockItemsForRead(false);
423 return; 424 return;
424
425 permsGranter = part.TaskInventory[ItemID].PermsGranter;
426 permsMask = part.TaskInventory[ItemID].PermsMask;
427 } 425 }
426 permsGranter = part.TaskInventory[ItemID].PermsGranter;
427 permsMask = part.TaskInventory[ItemID].PermsMask;
428 part.TaskInventory.LockItemsForRead(false);
428 429
429 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 430 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
430 { 431 {
@@ -552,6 +553,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
552 return true; 553 return true;
553 } 554 }
554 555
556 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
555 public void SetState(string state) 557 public void SetState(string state)
556 { 558 {
557 if (state == State) 559 if (state == State)
@@ -563,7 +565,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
563 new DetectParams[0])); 565 new DetectParams[0]));
564 PostEvent(new EventParams("state_entry", new Object[0], 566 PostEvent(new EventParams("state_entry", new Object[0],
565 new DetectParams[0])); 567 new DetectParams[0]));
566 568
567 throw new EventAbortException(); 569 throw new EventAbortException();
568 } 570 }
569 571
@@ -653,45 +655,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
653 /// <returns></returns> 655 /// <returns></returns>
654 public object EventProcessor() 656 public object EventProcessor()
655 { 657 {
658 EventParams data = null;
656 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 659 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
657 if (!Running) 660 if (!Running)
658 return 0; 661 return 0;
659 662
660 lock (m_Script)
661 {
662// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 663// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
663 664
664 if (Suspended) 665 if (Suspended)
665 return 0; 666 return 0;
666
667 EventParams data = null;
668 667
669 lock (EventQueue) 668 lock (EventQueue)
669 {
670 data = (EventParams) EventQueue.Dequeue();
671 if (data == null) // Shouldn't happen
670 { 672 {
671 data = (EventParams)EventQueue.Dequeue(); 673 if (EventQueue.Count > 0 && Running && !ShuttingDown)
672 if (data == null) // Shouldn't happen
673 { 674 {
674 if (EventQueue.Count > 0 && Running && !ShuttingDown) 675 m_CurrentWorkItem = Engine.QueueEventHandler(this);
675 {
676 m_CurrentWorkItem = Engine.QueueEventHandler(this);
677 }
678 else
679 {
680 m_CurrentWorkItem = null;
681 }
682 return 0;
683 } 676 }
684 677 else
685 if (data.EventName == "timer")
686 m_TimerQueued = false;
687 if (data.EventName == "control")
688 { 678 {
689 if (m_ControlEventsInQueue > 0) 679 m_CurrentWorkItem = null;
690 m_ControlEventsInQueue--;
691 } 680 }
692 if (data.EventName == "collision") 681 return 0;
693 m_CollisionInQueue = false;
694 } 682 }
683
684 if (data.EventName == "timer")
685 m_TimerQueued = false;
686 if (data.EventName == "control")
687 {
688 if (m_ControlEventsInQueue > 0)
689 m_ControlEventsInQueue--;
690 }
691 if (data.EventName == "collision")
692 m_CollisionInQueue = false;
693 }
694
695 lock(m_Script)
696 {
695 697
696// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 698// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
697 699
@@ -846,6 +848,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
846 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 848 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
847 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 849 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
848 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 850 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
851 part.CollisionSound = UUID.Zero;
849 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 852 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
850 EventQueue.Clear(); 853 EventQueue.Clear();
851 m_Script.ResetVars(); 854 m_Script.ResetVars();
@@ -860,6 +863,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
860 new Object[0], new DetectParams[0])); 863 new Object[0], new DetectParams[0]));
861 } 864 }
862 865
866 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
863 public void ApiResetScript() 867 public void ApiResetScript()
864 { 868 {
865 // bool running = Running; 869 // bool running = Running;
@@ -871,6 +875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
871 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 875 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
872 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 876 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
873 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 877 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
878 part.CollisionSound = UUID.Zero;
874 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 879 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
875 880
876 EventQueue.Clear(); 881 EventQueue.Clear();
@@ -891,10 +896,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
891 896
892 public Dictionary<string, object> GetVars() 897 public Dictionary<string, object> GetVars()
893 { 898 {
894 if (m_Script != null) 899 return m_Script.GetVars();
895 return m_Script.GetVars();
896 else
897 return new Dictionary<string, object>();
898 } 900 }
899 901
900 public void SetVars(Dictionary<string, object> vars) 902 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index fcb98a5..c9c4753 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -102,19 +102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
102 102
103 public override string ToString() 103 public override string ToString()
104 { 104 {
105 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 105 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
106 return s; 106 return s;
107 } 107 }
108 108
109 public static explicit operator LSLString(Vector3 vec) 109 public static explicit operator LSLString(Vector3 vec)
110 { 110 {
111 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 111 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
112 return new LSLString(s); 112 return new LSLString(s);
113 } 113 }
114 114
115 public static explicit operator string(Vector3 vec) 115 public static explicit operator string(Vector3 vec)
116 { 116 {
117 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 117 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
118 return s; 118 return s;
119 } 119 }
120 120
@@ -389,19 +389,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
389 389
390 public override string ToString() 390 public override string ToString()
391 { 391 {
392 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 392 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
393 return st; 393 return st;
394 } 394 }
395 395
396 public static explicit operator string(Quaternion r) 396 public static explicit operator string(Quaternion r)
397 { 397 {
398 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 398 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
399 return s; 399 return s;
400 } 400 }
401 401
402 public static explicit operator LSLString(Quaternion r) 402 public static explicit operator LSLString(Quaternion r)
403 { 403 {
404 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 404 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
405 return new LSLString(s); 405 return new LSLString(s);
406 } 406 }
407 407
@@ -521,6 +521,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
521 size += 64; 521 size += 64;
522 else if (o is int) 522 else if (o is int)
523 size += 4; 523 size += 4;
524 else if (o is uint)
525 size += 4;
524 else if (o is string) 526 else if (o is string)
525 size += ((string)o).Length; 527 size += ((string)o).Length;
526 else if (o is float) 528 else if (o is float)
@@ -686,24 +688,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
686 688
687 public static bool operator ==(list a, list b) 689 public static bool operator ==(list a, list b)
688 { 690 {
689 int la = -1; 691 int la = a.Length;
690 int lb = -1; 692 int lb = b.Length;
691 try { la = a.Length; }
692 catch (NullReferenceException) { }
693 try { lb = b.Length; }
694 catch (NullReferenceException) { }
695 693
696 return la == lb; 694 return la == lb;
697 } 695 }
698 696
699 public static bool operator !=(list a, list b) 697 public static bool operator !=(list a, list b)
700 { 698 {
701 int la = -1; 699 int la = a.Length;
702 int lb = -1; 700 int lb = b.Length;
703 try { la = a.Length; }
704 catch (NullReferenceException) { }
705 try {lb = b.Length;}
706 catch (NullReferenceException) { }
707 701
708 return la != lb; 702 return la != lb;
709 } 703 }
@@ -937,7 +931,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
937 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 931 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
938 } 932 }
939 933
940 if (ascending == 0) 934 if (ascending != 1)
941 { 935 {
942 ret = 0 - ret; 936 ret = 0 - ret;
943 } 937 }
@@ -970,6 +964,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
970 stride = 1; 964 stride = 1;
971 } 965 }
972 966
967 if ((Data.Length % stride) != 0)
968 return new list(ret);
969
973 // we can optimize here in the case where stride == 1 and the list 970 // we can optimize here in the case where stride == 1 and the list
974 // consists of homogeneous types 971 // consists of homogeneous types
975 972
@@ -989,7 +986,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
989 if (homogeneous) 986 if (homogeneous)
990 { 987 {
991 Array.Sort(ret, new HomogeneousComparer()); 988 Array.Sort(ret, new HomogeneousComparer());
992 if (ascending == 0) 989 if (ascending != 1)
993 { 990 {
994 Array.Reverse(ret); 991 Array.Reverse(ret);
995 } 992 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 0460f22..9f05666 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Globalization; 32using System.Globalization;
32using System.IO; 33using System.IO;
33using System.Reflection; 34using System.Reflection;
@@ -128,6 +129,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
128 private Dictionary<UUID, IScriptInstance> m_Scripts = 129 private Dictionary<UUID, IScriptInstance> m_Scripts =
129 new Dictionary<UUID, IScriptInstance>(); 130 new Dictionary<UUID, IScriptInstance>();
130 131
132 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
133
131 // Maps the asset ID to the assembly 134 // Maps the asset ID to the assembly
132 135
133 private Dictionary<UUID, string> m_Assemblies = 136 private Dictionary<UUID, string> m_Assemblies =
@@ -150,6 +153,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
150 IWorkItemResult m_CurrentCompile = null; 153 IWorkItemResult m_CurrentCompile = null;
151 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 154 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
152 155
156 private void lockScriptsForRead(bool locked)
157 {
158 if (locked)
159 {
160 if (m_scriptsLock.RecursiveReadCount > 0)
161 {
162 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
163 m_scriptsLock.ExitReadLock();
164 }
165 if (m_scriptsLock.RecursiveWriteCount > 0)
166 {
167 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
168 m_scriptsLock.ExitWriteLock();
169 }
170
171 while (!m_scriptsLock.TryEnterReadLock(60000))
172 {
173 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
174 if (m_scriptsLock.IsWriteLockHeld)
175 {
176 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
177 }
178 }
179 }
180 else
181 {
182 if (m_scriptsLock.RecursiveReadCount > 0)
183 {
184 m_scriptsLock.ExitReadLock();
185 }
186 }
187 }
188 private void lockScriptsForWrite(bool locked)
189 {
190 if (locked)
191 {
192 if (m_scriptsLock.RecursiveReadCount > 0)
193 {
194 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
195 m_scriptsLock.ExitReadLock();
196 }
197 if (m_scriptsLock.RecursiveWriteCount > 0)
198 {
199 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
200 m_scriptsLock.ExitWriteLock();
201 }
202
203 while (!m_scriptsLock.TryEnterWriteLock(60000))
204 {
205 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
206 if (m_scriptsLock.IsWriteLockHeld)
207 {
208 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
209 }
210 }
211 }
212 else
213 {
214 if (m_scriptsLock.RecursiveWriteCount > 0)
215 {
216 m_scriptsLock.ExitWriteLock();
217 }
218 }
219 }
220
153 public string ScriptEngineName 221 public string ScriptEngineName
154 { 222 {
155 get { return "XEngine"; } 223 get { return "XEngine"; }
@@ -576,64 +644,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine
576 { 644 {
577 if (!m_Enabled) 645 if (!m_Enabled)
578 return; 646 return;
647 lockScriptsForRead(true);
579 648
580 lock (m_Scripts) 649 List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values);
581 {
582 m_log.InfoFormat(
583 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName);
584 650
585 foreach (IScriptInstance instance in m_Scripts.Values) 651// foreach (IScriptInstance instance in m_Scripts.Values)
652 foreach (IScriptInstance instance in instancesToDel)
653 {
654 // Force a final state save
655 //
656 if (m_Assemblies.ContainsKey(instance.AssetID))
586 { 657 {
587 // Force a final state save 658 string assembly = m_Assemblies[instance.AssetID];
588 //
589 if (m_Assemblies.ContainsKey(instance.AssetID))
590 {
591 string assembly = m_Assemblies[instance.AssetID];
592 659
593 try 660 try
594 { 661 {
595 instance.SaveState(assembly); 662 instance.SaveState(assembly);
596 }
597 catch (Exception e)
598 {
599 m_log.Error(
600 string.Format(
601 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
602 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
603 , e);
604 }
605 } 663 }
664 catch (Exception e)
665 {
666 m_log.Error(
667 string.Format(
668 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
669 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
670 , e);
671 }
672 }
606 673
607 // Clear the event queue and abort the instance thread 674 // Clear the event queue and abort the instance thread
608 // 675 //
609 instance.ClearQueue(); 676 instance.ClearQueue();
610 instance.Stop(0); 677 instance.Stop(0);
611 678
612 // Release events, timer, etc 679 // Release events, timer, etc
613 // 680 //
614 instance.DestroyScriptInstance(); 681 instance.DestroyScriptInstance();
615 682
616 // Unload scripts and app domains. 683 // Unload scripts and app domains
617 // Must be done explicitly because they have infinite 684 // Must be done explicitly because they have infinite
618 // lifetime. 685 // lifetime
619 // However, don't bother to do this if the simulator is shutting 686 //
620 // down since it takes a long time with many scripts. 687// if (!m_SimulatorShuttingDown)
621 if (!m_SimulatorShuttingDown) 688 {
689 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
690 if (m_DomainScripts[instance.AppDomain].Count == 0)
622 { 691 {
623 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 692 m_DomainScripts.Remove(instance.AppDomain);
624 if (m_DomainScripts[instance.AppDomain].Count == 0) 693 UnloadAppDomain(instance.AppDomain);
625 {
626 m_DomainScripts.Remove(instance.AppDomain);
627 UnloadAppDomain(instance.AppDomain);
628 }
629 } 694 }
630 } 695 }
631 696
632 m_Scripts.Clear(); 697// m_Scripts.Clear();
633 m_PrimObjects.Clear(); 698// m_PrimObjects.Clear();
634 m_Assemblies.Clear(); 699// m_Assemblies.Clear();
635 m_DomainScripts.Clear(); 700// m_DomainScripts.Clear();
636 } 701 }
702 lockScriptsForRead(false);
703 lockScriptsForWrite(true);
704 m_Scripts.Clear();
705 lockScriptsForWrite(false);
706 m_PrimObjects.Clear();
707 m_Assemblies.Clear();
708 m_DomainScripts.Clear();
709
637 lock (m_ScriptEngines) 710 lock (m_ScriptEngines)
638 { 711 {
639 m_ScriptEngines.Remove(this); 712 m_ScriptEngines.Remove(this);
@@ -702,22 +775,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
702 775
703 List<IScriptInstance> instances = new List<IScriptInstance>(); 776 List<IScriptInstance> instances = new List<IScriptInstance>();
704 777
705 lock (m_Scripts) 778 lockScriptsForRead(true);
706 { 779 foreach (IScriptInstance instance in m_Scripts.Values)
707 foreach (IScriptInstance instance in m_Scripts.Values)
708 instances.Add(instance); 780 instances.Add(instance);
709 } 781 lockScriptsForRead(false);
710 782
711 foreach (IScriptInstance i in instances) 783 foreach (IScriptInstance i in instances)
712 { 784 {
713 string assembly = String.Empty; 785 string assembly = String.Empty;
714 786
715 lock (m_Scripts) 787
716 {
717 if (!m_Assemblies.ContainsKey(i.AssetID)) 788 if (!m_Assemblies.ContainsKey(i.AssetID))
718 continue; 789 continue;
719 assembly = m_Assemblies[i.AssetID]; 790 assembly = m_Assemblies[i.AssetID];
720 } 791
721 792
722 try 793 try
723 { 794 {
@@ -1119,96 +1190,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1119 } 1190 }
1120 1191
1121 ScriptInstance instance = null; 1192 ScriptInstance instance = null;
1122 lock (m_Scripts) 1193 // Create the object record
1194 lockScriptsForRead(true);
1195 if ((!m_Scripts.ContainsKey(itemID)) ||
1196 (m_Scripts[itemID].AssetID != assetID))
1123 { 1197 {
1124 // Create the object record 1198 lockScriptsForRead(false);
1125 if ((!m_Scripts.ContainsKey(itemID)) ||
1126 (m_Scripts[itemID].AssetID != assetID))
1127 {
1128 UUID appDomain = assetID;
1129 1199
1130 if (part.ParentGroup.IsAttachment) 1200 UUID appDomain = assetID;
1131 appDomain = part.ParentGroup.RootPart.UUID;
1132 1201
1133 if (!m_AppDomains.ContainsKey(appDomain)) 1202 if (part.ParentGroup.IsAttachment)
1134 { 1203 appDomain = part.ParentGroup.RootPart.UUID;
1135 try
1136 {
1137 AppDomainSetup appSetup = new AppDomainSetup();
1138 appSetup.PrivateBinPath = Path.Combine(
1139 m_ScriptEnginesPath,
1140 m_Scene.RegionInfo.RegionID.ToString());
1141 1204
1142 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1205 if (!m_AppDomains.ContainsKey(appDomain))
1143 Evidence evidence = new Evidence(baseEvidence); 1206 {
1207 try
1208 {
1209 AppDomainSetup appSetup = new AppDomainSetup();
1210 appSetup.PrivateBinPath = Path.Combine(
1211 m_ScriptEnginesPath,
1212 m_Scene.RegionInfo.RegionID.ToString());
1144 1213
1145 AppDomain sandbox; 1214 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1146 if (m_AppDomainLoading) 1215 Evidence evidence = new Evidence(baseEvidence);
1147 {
1148 sandbox = AppDomain.CreateDomain(
1149 m_Scene.RegionInfo.RegionID.ToString(),
1150 evidence, appSetup);
1151 sandbox.AssemblyResolve +=
1152 new ResolveEventHandler(
1153 AssemblyResolver.OnAssemblyResolve);
1154 }
1155 else
1156 {
1157 sandbox = AppDomain.CurrentDomain;
1158 }
1159
1160 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1161 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1162 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1163 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1164 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1165 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1166 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1167
1168 m_AppDomains[appDomain] = sandbox;
1169 1216
1170 m_DomainScripts[appDomain] = new List<UUID>(); 1217 AppDomain sandbox;
1218 if (m_AppDomainLoading)
1219 {
1220 sandbox = AppDomain.CreateDomain(
1221 m_Scene.RegionInfo.RegionID.ToString(),
1222 evidence, appSetup);
1223 m_AppDomains[appDomain].AssemblyResolve +=
1224 new ResolveEventHandler(
1225 AssemblyResolver.OnAssemblyResolve);
1171 } 1226 }
1172 catch (Exception e) 1227 else
1173 { 1228 {
1174 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1229 sandbox = AppDomain.CurrentDomain;
1175 m_ScriptErrorMessage += "Exception creating app domain:\n";
1176 m_ScriptFailCount++;
1177 lock (m_AddingAssemblies)
1178 {
1179 m_AddingAssemblies[assembly]--;
1180 }
1181 return false;
1182 } 1230 }
1183 }
1184 m_DomainScripts[appDomain].Add(itemID);
1185
1186 instance = new ScriptInstance(this, part,
1187 itemID, assetID, assembly,
1188 m_AppDomains[appDomain],
1189 part.ParentGroup.RootPart.Name,
1190 item.Name, startParam, postOnRez,
1191 stateSource, m_MaxScriptQueue);
1192
1193// if (DebugLevel >= 1)
1194// m_log.DebugFormat(
1195// "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1196// part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1197// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1198 1231
1199 if (presence != null) 1232 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1233 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1234 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1235 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1236 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1237 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1238 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1239
1240 m_AppDomains[appDomain] = sandbox;
1241
1242 m_DomainScripts[appDomain] = new List<UUID>();
1243 }
1244 catch (Exception e)
1200 { 1245 {
1201 ShowScriptSaveResponse(item.OwnerID, 1246 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1202 assetID, "Compile successful", true); 1247 m_ScriptErrorMessage += "Exception creating app domain:\n";
1248 m_ScriptFailCount++;
1249 lock (m_AddingAssemblies)
1250 {
1251 m_AddingAssemblies[assembly]--;
1252 }
1253 return false;
1203 } 1254 }
1255 }
1256 m_DomainScripts[appDomain].Add(itemID);
1257
1258 instance = new ScriptInstance(this, part,
1259 itemID, assetID, assembly,
1260 m_AppDomains[appDomain],
1261 part.ParentGroup.RootPart.Name,
1262 item.Name, startParam, postOnRez,
1263 stateSource, m_MaxScriptQueue);
1264
1265// m_log.DebugFormat(
1266// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1267// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1268// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1204 1269
1205 instance.AppDomain = appDomain; 1270 if (presence != null)
1206 instance.LineMap = linemap; 1271 {
1207 1272 ShowScriptSaveResponse(item.OwnerID,
1208 m_Scripts[itemID] = instance; 1273 assetID, "Compile successful", true);
1209 } 1274 }
1210 }
1211 1275
1276 instance.AppDomain = appDomain;
1277 instance.LineMap = linemap;
1278 lockScriptsForWrite(true);
1279 m_Scripts[itemID] = instance;
1280 lockScriptsForWrite(false);
1281 }
1282 else
1283 {
1284 lockScriptsForRead(false);
1285 }
1212 lock (m_PrimObjects) 1286 lock (m_PrimObjects)
1213 { 1287 {
1214 if (!m_PrimObjects.ContainsKey(localID)) 1288 if (!m_PrimObjects.ContainsKey(localID))
@@ -1226,7 +1300,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1226 m_AddingAssemblies[assembly]--; 1300 m_AddingAssemblies[assembly]--;
1227 } 1301 }
1228 1302
1229 if (instance != null) 1303 if (instance!=null)
1230 instance.Init(); 1304 instance.Init();
1231 1305
1232 bool runIt; 1306 bool runIt;
@@ -1249,18 +1323,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1249 m_CompileDict.Remove(itemID); 1323 m_CompileDict.Remove(itemID);
1250 } 1324 }
1251 1325
1252 IScriptInstance instance = null; 1326 lockScriptsForRead(true);
1253 1327 // Do we even have it?
1254 lock (m_Scripts) 1328 if (!m_Scripts.ContainsKey(itemID))
1255 { 1329 {
1256 // Do we even have it? 1330 // Do we even have it?
1257 if (!m_Scripts.ContainsKey(itemID)) 1331 if (!m_Scripts.ContainsKey(itemID))
1258 return; 1332 return;
1259 1333
1260 instance = m_Scripts[itemID]; 1334 lockScriptsForRead(false);
1335 lockScriptsForWrite(true);
1261 m_Scripts.Remove(itemID); 1336 m_Scripts.Remove(itemID);
1337 lockScriptsForWrite(false);
1338
1339 return;
1262 } 1340 }
1341
1263 1342
1343 IScriptInstance instance=m_Scripts[itemID];
1344 lockScriptsForRead(false);
1345 lockScriptsForWrite(true);
1346 m_Scripts.Remove(itemID);
1347 lockScriptsForWrite(false);
1264 instance.ClearQueue(); 1348 instance.ClearQueue();
1265 1349
1266 // Give the script some time to finish processing its last event. Simply aborting the script thread can 1350 // Give the script some time to finish processing its last event. Simply aborting the script thread can
@@ -1299,8 +1383,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1299 1383
1300 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1384 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1301 if (handlerObjectRemoved != null) 1385 if (handlerObjectRemoved != null)
1302 handlerObjectRemoved(instance.ObjectID); 1386 {
1387 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1388 handlerObjectRemoved(part.UUID);
1389 }
1303 1390
1391 CleanAssemblies();
1392
1304 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1393 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1305 if (handlerScriptRemoved != null) 1394 if (handlerScriptRemoved != null)
1306 handlerScriptRemoved(itemID); 1395 handlerScriptRemoved(itemID);
@@ -1561,12 +1650,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1561 private IScriptInstance GetInstance(UUID itemID) 1650 private IScriptInstance GetInstance(UUID itemID)
1562 { 1651 {
1563 IScriptInstance instance; 1652 IScriptInstance instance;
1564 lock (m_Scripts) 1653 lockScriptsForRead(true);
1654 if (!m_Scripts.ContainsKey(itemID))
1565 { 1655 {
1566 if (!m_Scripts.ContainsKey(itemID)) 1656 lockScriptsForRead(false);
1567 return null; 1657 return null;
1568 instance = m_Scripts[itemID];
1569 } 1658 }
1659 instance = m_Scripts[itemID];
1660 lockScriptsForRead(false);
1570 return instance; 1661 return instance;
1571 } 1662 }
1572 1663
@@ -1590,6 +1681,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1590 return false; 1681 return false;
1591 } 1682 }
1592 1683
1684 [DebuggerNonUserCode]
1593 public void ApiResetScript(UUID itemID) 1685 public void ApiResetScript(UUID itemID)
1594 { 1686 {
1595 IScriptInstance instance = GetInstance(itemID); 1687 IScriptInstance instance = GetInstance(itemID);
@@ -1651,6 +1743,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1651 return UUID.Zero; 1743 return UUID.Zero;
1652 } 1744 }
1653 1745
1746 [DebuggerNonUserCode]
1654 public void SetState(UUID itemID, string newState) 1747 public void SetState(UUID itemID, string newState)
1655 { 1748 {
1656 IScriptInstance instance = GetInstance(itemID); 1749 IScriptInstance instance = GetInstance(itemID);
@@ -1673,11 +1766,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1673 1766
1674 List<IScriptInstance> instances = new List<IScriptInstance>(); 1767 List<IScriptInstance> instances = new List<IScriptInstance>();
1675 1768
1676 lock (m_Scripts) 1769 lockScriptsForRead(true);
1677 { 1770 foreach (IScriptInstance instance in m_Scripts.Values)
1678 foreach (IScriptInstance instance in m_Scripts.Values)
1679 instances.Add(instance); 1771 instances.Add(instance);
1680 } 1772 lockScriptsForRead(false);
1681 1773
1682 foreach (IScriptInstance i in instances) 1774 foreach (IScriptInstance i in instances)
1683 { 1775 {