aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.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 1d2ef40..dda8257 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);
@@ -2096,25 +2327,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2096 2327
2097 protected void SetRot(SceneObjectPart part, Quaternion rot) 2328 protected void SetRot(SceneObjectPart part, Quaternion rot)
2098 { 2329 {
2099 part.UpdateRotation(rot); 2330 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2100 // Update rotation does not move the object in the physics scene if it's a linkset. 2331 return;
2101 2332
2102//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2333 bool isroot = (part == part.ParentGroup.RootPart);
2103// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2334 bool isphys;
2104 2335
2105 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2106 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2107 // It's perfectly okay when the object is not an active physical body though.
2108 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2109 // but only if the object is not physial and active. This is important for rotating doors.
2110 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2111 // scene
2112 PhysicsActor pa = part.PhysActor; 2336 PhysicsActor pa = part.PhysActor;
2113 2337
2114 if (pa != null && !pa.IsPhysical) 2338 // keep using physactor ideia of isphysical
2339 // it should be SOP ideia of that
2340 // not much of a issue with ubitODE
2341 if (pa != null && pa.IsPhysical)
2342 isphys = true;
2343 else
2344 isphys = false;
2345
2346 // SL doesn't let scripts rotate root of physical linksets
2347 if (isroot && isphys)
2348 return;
2349
2350 part.UpdateRotation(rot);
2351
2352 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2353 // so do a nasty update of parts positions if is a root part rotation
2354 if (isroot && pa != null) // with if above implies non physical root part
2115 { 2355 {
2116 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2356 part.ParentGroup.ResetChildPrimPhysicsPositions();
2117 } 2357 }
2358 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2359 {
2360 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2361 if (sittingavas.Count > 0)
2362 {
2363 foreach (ScenePresence av in sittingavas)
2364 {
2365 if (isroot || part.LocalId == av.ParentID)
2366 av.SendTerseUpdateToAllClients();
2367 }
2368 }
2369 }
2118 } 2370 }
2119 2371
2120 /// <summary> 2372 /// <summary>
@@ -2162,8 +2414,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2162 2414
2163 public LSL_Rotation llGetLocalRot() 2415 public LSL_Rotation llGetLocalRot()
2164 { 2416 {
2417 return GetPartLocalRot(m_host);
2418 }
2419
2420 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2421 {
2165 m_host.AddScriptLPS(1); 2422 m_host.AddScriptLPS(1);
2166 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2423 Quaternion rot = part.RotationOffset;
2424 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2167 } 2425 }
2168 2426
2169 public void llSetForce(LSL_Vector force, int local) 2427 public void llSetForce(LSL_Vector force, int local)
@@ -2243,16 +2501,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2243 m_host.ApplyImpulse(v, local != 0); 2501 m_host.ApplyImpulse(v, local != 0);
2244 } 2502 }
2245 2503
2504
2246 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2505 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2247 { 2506 {
2248 m_host.AddScriptLPS(1); 2507 m_host.AddScriptLPS(1);
2249 m_host.ApplyAngularImpulse(force, local != 0); 2508 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2250 } 2509 }
2251 2510
2252 public void llSetTorque(LSL_Vector torque, int local) 2511 public void llSetTorque(LSL_Vector torque, int local)
2253 { 2512 {
2254 m_host.AddScriptLPS(1); 2513 m_host.AddScriptLPS(1);
2255 m_host.SetAngularImpulse(torque, local != 0); 2514 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2256 } 2515 }
2257 2516
2258 public LSL_Vector llGetTorque() 2517 public LSL_Vector llGetTorque()
@@ -2269,20 +2528,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2269 llSetTorque(torque, local); 2528 llSetTorque(torque, local);
2270 } 2529 }
2271 2530
2531 public void llSetVelocity(LSL_Vector vel, int local)
2532 {
2533 m_host.AddScriptLPS(1);
2534 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2535 }
2536
2272 public LSL_Vector llGetVel() 2537 public LSL_Vector llGetVel()
2273 { 2538 {
2274 m_host.AddScriptLPS(1); 2539 m_host.AddScriptLPS(1);
2275 2540
2276 Vector3 vel; 2541 Vector3 vel = Vector3.Zero;
2277 2542
2278 if (m_host.ParentGroup.IsAttachment) 2543 if (m_host.ParentGroup.IsAttachment)
2279 { 2544 {
2280 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2545 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2281 vel = avatar.Velocity; 2546 if (avatar != null)
2547 vel = avatar.Velocity;
2282 } 2548 }
2283 else 2549 else
2284 { 2550 {
2285 vel = m_host.Velocity; 2551 vel = m_host.ParentGroup.RootPart.Velocity;
2286 } 2552 }
2287 2553
2288 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2554 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2294,10 +2560,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2294 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2560 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2295 } 2561 }
2296 2562
2563 public void llSetAngularVelocity(LSL_Vector avel, int local)
2564 {
2565 m_host.AddScriptLPS(1);
2566 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2567 }
2568
2297 public LSL_Vector llGetOmega() 2569 public LSL_Vector llGetOmega()
2298 { 2570 {
2299 m_host.AddScriptLPS(1); 2571 m_host.AddScriptLPS(1);
2300 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2572 Vector3 avel = m_host.AngularVelocity;
2573 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2301 } 2574 }
2302 2575
2303 public LSL_Float llGetTimeOfDay() 2576 public LSL_Float llGetTimeOfDay()
@@ -2823,16 +3096,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2823 new_group.RootPart.UUID.ToString()) }, 3096 new_group.RootPart.UUID.ToString()) },
2824 new DetectParams[0])); 3097 new DetectParams[0]));
2825 3098
2826 float groupmass = new_group.GetMass(); 3099 // do recoil
3100 SceneObjectGroup hostgrp = m_host.ParentGroup;
3101 if (hostgrp == null)
3102 return;
3103
3104 if (hostgrp.IsAttachment) // don't recoil avatars
3105 return;
2827 3106
2828 PhysicsActor pa = new_group.RootPart.PhysActor; 3107 PhysicsActor pa = new_group.RootPart.PhysActor;
2829 3108
2830 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3109 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2831 { 3110 {
2832 //Recoil. 3111 float groupmass = new_group.GetMass();
2833 llApplyImpulse(vel * groupmass, 0); 3112 vel *= -groupmass;
3113 llApplyImpulse(vel, 0);
2834 } 3114 }
2835 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3115 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3116 return;
3117
2836 }); 3118 });
2837 3119
2838 //ScriptSleep((int)((groupmass * velmag) / 10)); 3120 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2847,35 +3129,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2847 public void llLookAt(LSL_Vector target, double strength, double damping) 3129 public void llLookAt(LSL_Vector target, double strength, double damping)
2848 { 3130 {
2849 m_host.AddScriptLPS(1); 3131 m_host.AddScriptLPS(1);
2850 // Determine where we are looking from
2851 LSL_Vector from = llGetPos();
2852 3132
2853 // Work out the normalised vector from the source to the target 3133 // Get the normalized vector to the target
2854 LSL_Vector delta = llVecNorm(target - from); 3134 LSL_Vector d1 = llVecNorm(target - llGetPos());
2855 LSL_Vector angle = new LSL_Vector(0,0,0);
2856 3135
2857 // Calculate the yaw 3136 // Get the bearing (yaw)
2858 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3137 LSL_Vector a1 = new LSL_Vector(0,0,0);
2859 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3138 a1.z = llAtan2(d1.y, d1.x);
2860 3139
2861 // Calculate pitch 3140 // Get the elevation (pitch)
2862 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3141 LSL_Vector a2 = new LSL_Vector(0,0,0);
3142 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2863 3143
2864 // we need to convert from a vector describing 3144 LSL_Rotation r1 = llEuler2Rot(a1);
2865 // the angles of rotation in radians into rotation value 3145 LSL_Rotation r2 = llEuler2Rot(a2);
2866 LSL_Rotation rot = llEuler2Rot(angle); 3146 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2867
2868 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2869 // set the rotation of the object, copy that behavior
2870 PhysicsActor pa = m_host.PhysActor;
2871 3147
2872 if (strength == 0 || pa == null || !pa.IsPhysical) 3148 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2873 { 3149 {
2874 llSetRot(rot); 3150 // Do nothing if either value is 0 (this has been checked in SL)
3151 if (strength <= 0.0 || damping <= 0.0)
3152 return;
3153
3154 llSetRot(r3 * r2 * r1);
2875 } 3155 }
2876 else 3156 else
2877 { 3157 {
2878 m_host.StartLookAt(rot, (float)strength, (float)damping); 3158 if (strength == 0)
3159 {
3160 llSetRot(r3 * r2 * r1);
3161 return;
3162 }
3163
3164 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2879 } 3165 }
2880 } 3166 }
2881 3167
@@ -2921,17 +3207,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2921 } 3207 }
2922 else 3208 else
2923 { 3209 {
2924 if (m_host.IsRoot) 3210 // new SL always returns object mass
2925 { 3211// if (m_host.IsRoot)
3212// {
2926 return m_host.ParentGroup.GetMass(); 3213 return m_host.ParentGroup.GetMass();
2927 } 3214// }
2928 else 3215// else
2929 { 3216// {
2930 return m_host.GetMass(); 3217// return m_host.GetMass();
2931 } 3218// }
2932 } 3219 }
2933 } 3220 }
2934 3221
3222
3223 public LSL_Float llGetMassMKS()
3224 {
3225 return 100f * llGetMass();
3226 }
3227
2935 public void llCollisionFilter(string name, string id, int accept) 3228 public void llCollisionFilter(string name, string id, int accept)
2936 { 3229 {
2937 m_host.AddScriptLPS(1); 3230 m_host.AddScriptLPS(1);
@@ -2979,8 +3272,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2979 { 3272 {
2980 // Unregister controls from Presence 3273 // Unregister controls from Presence
2981 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3274 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2982 // Remove Take Control permission.
2983 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
2984 } 3275 }
2985 } 3276 }
2986 } 3277 }
@@ -3006,7 +3297,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3006 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3297 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3007 3298
3008 if (attachmentsModule != null) 3299 if (attachmentsModule != null)
3009 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3300 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3010 else 3301 else
3011 return false; 3302 return false;
3012 } 3303 }
@@ -3036,9 +3327,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3036 { 3327 {
3037 m_host.AddScriptLPS(1); 3328 m_host.AddScriptLPS(1);
3038 3329
3039// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3040// return;
3041
3042 if (m_item.PermsGranter != m_host.OwnerID) 3330 if (m_item.PermsGranter != m_host.OwnerID)
3043 return; 3331 return;
3044 3332
@@ -3081,6 +3369,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3081 3369
3082 public void llInstantMessage(string user, string message) 3370 public void llInstantMessage(string user, string message)
3083 { 3371 {
3372 UUID result;
3373 if (!UUID.TryParse(user, out result))
3374 {
3375 ShoutError("An invalid key was passed to llInstantMessage");
3376 ScriptSleep(2000);
3377 return;
3378 }
3379
3380
3084 m_host.AddScriptLPS(1); 3381 m_host.AddScriptLPS(1);
3085 3382
3086 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3383 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3095,14 +3392,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3095 UUID friendTransactionID = UUID.Random(); 3392 UUID friendTransactionID = UUID.Random();
3096 3393
3097 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3394 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3098 3395
3099 GridInstantMessage msg = new GridInstantMessage(); 3396 GridInstantMessage msg = new GridInstantMessage();
3100 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3397 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3101 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3398 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3102 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3399 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3103// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3400// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3104// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3401// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3105 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3402// DateTime dt = DateTime.UtcNow;
3403//
3404// // Ticks from UtcNow, but make it look like local. Evil, huh?
3405// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3406//
3407// try
3408// {
3409// // Convert that to the PST timezone
3410// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3411// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3412// }
3413// catch
3414// {
3415// // No logging here, as it could be VERY spammy
3416// }
3417//
3418// // And make it look local again to fool the unix time util
3419// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3420
3421 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3422
3106 //if (client != null) 3423 //if (client != null)
3107 //{ 3424 //{
3108 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3425 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3116,12 +3433,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3116 msg.message = message.Substring(0, 1024); 3433 msg.message = message.Substring(0, 1024);
3117 else 3434 else
3118 msg.message = message; 3435 msg.message = message;
3119 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3436 msg.dialog = (byte)19; // MessageFromObject
3120 msg.fromGroup = false;// fromGroup; 3437 msg.fromGroup = false;// fromGroup;
3121 msg.offline = (byte)0; //offline; 3438 msg.offline = (byte)0; //offline;
3122 msg.ParentEstateID = 0; //ParentEstateID; 3439 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3123 msg.Position = new Vector3(m_host.AbsolutePosition); 3440 msg.Position = new Vector3(m_host.AbsolutePosition);
3124 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3441 msg.RegionID = World.RegionInfo.RegionID.Guid;
3125 msg.binaryBucket 3442 msg.binaryBucket
3126 = Util.StringToBytes256( 3443 = Util.StringToBytes256(
3127 "{0}/{1}/{2}/{3}", 3444 "{0}/{1}/{2}/{3}",
@@ -3149,7 +3466,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3149 } 3466 }
3150 3467
3151 emailModule.SendEmail(m_host.UUID, address, subject, message); 3468 emailModule.SendEmail(m_host.UUID, address, subject, message);
3152 llSleep(EMAIL_PAUSE_TIME); 3469 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3153 } 3470 }
3154 3471
3155 public void llGetNextEmail(string address, string subject) 3472 public void llGetNextEmail(string address, string subject)
@@ -3395,7 +3712,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3395 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3712 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3396 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3713 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3397 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3714 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3715 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3398 ScriptBaseClass.PERMISSION_ATTACH; 3716 ScriptBaseClass.PERMISSION_ATTACH;
3717
3399 } 3718 }
3400 else 3719 else
3401 { 3720 {
@@ -3430,11 +3749,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3430 3749
3431 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3750 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3432 { 3751 {
3433 lock (m_host.TaskInventory) 3752 m_host.TaskInventory.LockItemsForWrite(true);
3434 { 3753 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3435 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3754 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3436 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3755 m_host.TaskInventory.LockItemsForWrite(false);
3437 }
3438 3756
3439 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3757 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3440 "run_time_permissions", new Object[] { 3758 "run_time_permissions", new Object[] {
@@ -3477,11 +3795,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3477 3795
3478 if (!m_waitingForScriptAnswer) 3796 if (!m_waitingForScriptAnswer)
3479 { 3797 {
3480 lock (m_host.TaskInventory) 3798 m_host.TaskInventory.LockItemsForWrite(true);
3481 { 3799 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3482 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3800 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3483 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3801 m_host.TaskInventory.LockItemsForWrite(false);
3484 }
3485 3802
3486 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3803 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3487 m_waitingForScriptAnswer=true; 3804 m_waitingForScriptAnswer=true;
@@ -3510,14 +3827,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3510 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3827 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3511 llReleaseControls(); 3828 llReleaseControls();
3512 3829
3513 lock (m_host.TaskInventory) 3830 m_host.TaskInventory.LockItemsForWrite(true);
3514 { 3831 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3515 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3832 m_host.TaskInventory.LockItemsForWrite(false);
3516 } 3833
3517 3834 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3518 m_ScriptEngine.PostScriptEvent( 3835 "run_time_permissions", new Object[] {
3519 m_item.ItemID, 3836 new LSL_Integer(answer) },
3520 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3837 new DetectParams[0]));
3521 } 3838 }
3522 3839
3523 public LSL_String llGetPermissionsKey() 3840 public LSL_String llGetPermissionsKey()
@@ -3556,14 +3873,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3556 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3873 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3557 { 3874 {
3558 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3875 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3559 3876 if (parts.Count > 0)
3560 foreach (SceneObjectPart part in parts) 3877 {
3561 part.SetFaceColorAlpha(face, color, null); 3878 try
3879 {
3880 foreach (SceneObjectPart part in parts)
3881 part.SetFaceColorAlpha(face, color, null);
3882 }
3883 finally
3884 {
3885 }
3886 }
3562 } 3887 }
3563 3888
3564 public void llCreateLink(string target, int parent) 3889 public void llCreateLink(string target, int parent)
3565 { 3890 {
3566 m_host.AddScriptLPS(1); 3891 m_host.AddScriptLPS(1);
3892
3567 UUID targetID; 3893 UUID targetID;
3568 3894
3569 if (!UUID.TryParse(target, out targetID)) 3895 if (!UUID.TryParse(target, out targetID))
@@ -3669,10 +3995,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3669 // Restructuring Multiple Prims. 3995 // Restructuring Multiple Prims.
3670 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3996 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3671 parts.Remove(parentPrim.RootPart); 3997 parts.Remove(parentPrim.RootPart);
3672 foreach (SceneObjectPart part in parts) 3998 if (parts.Count > 0)
3673 { 3999 {
3674 parentPrim.DelinkFromGroup(part.LocalId, true); 4000 try
4001 {
4002 foreach (SceneObjectPart part in parts)
4003 {
4004 parentPrim.DelinkFromGroup(part.LocalId, true);
4005 }
4006 }
4007 finally
4008 {
4009 }
3675 } 4010 }
4011
3676 parentPrim.HasGroupChanged = true; 4012 parentPrim.HasGroupChanged = true;
3677 parentPrim.ScheduleGroupForFullUpdate(); 4013 parentPrim.ScheduleGroupForFullUpdate();
3678 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4014 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3681,12 +4017,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3681 { 4017 {
3682 SceneObjectPart newRoot = parts[0]; 4018 SceneObjectPart newRoot = parts[0];
3683 parts.Remove(newRoot); 4019 parts.Remove(newRoot);
3684 foreach (SceneObjectPart part in parts) 4020
4021 try
3685 { 4022 {
3686 // Required for linking 4023 foreach (SceneObjectPart part in parts)
3687 part.ClearUpdateSchedule(); 4024 {
3688 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4025 part.ClearUpdateSchedule();
4026 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4027 }
3689 } 4028 }
4029 finally
4030 {
4031 }
4032
4033
3690 newRoot.ParentGroup.HasGroupChanged = true; 4034 newRoot.ParentGroup.HasGroupChanged = true;
3691 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4035 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3692 } 4036 }
@@ -3706,6 +4050,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3706 public void llBreakAllLinks() 4050 public void llBreakAllLinks()
3707 { 4051 {
3708 m_host.AddScriptLPS(1); 4052 m_host.AddScriptLPS(1);
4053
4054 TaskInventoryItem item = m_item;
4055
4056 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4057 && !m_automaticLinkPermission)
4058 {
4059 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4060 return;
4061 }
4062
3709 SceneObjectGroup parentPrim = m_host.ParentGroup; 4063 SceneObjectGroup parentPrim = m_host.ParentGroup;
3710 if (parentPrim.AttachmentPoint != 0) 4064 if (parentPrim.AttachmentPoint != 0)
3711 return; // Fail silently if attached 4065 return; // Fail silently if attached
@@ -3725,25 +4079,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3725 public LSL_String llGetLinkKey(int linknum) 4079 public LSL_String llGetLinkKey(int linknum)
3726 { 4080 {
3727 m_host.AddScriptLPS(1); 4081 m_host.AddScriptLPS(1);
3728 List<UUID> keytable = new List<UUID>();
3729 // parse for sitting avatare-uuids
3730 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3731 {
3732 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3733 keytable.Add(presence.UUID);
3734 });
3735
3736 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3737 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3738 {
3739 return keytable[totalprims - linknum].ToString();
3740 }
3741
3742 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3743 {
3744 return m_host.UUID.ToString();
3745 }
3746
3747 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4082 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3748 if (part != null) 4083 if (part != null)
3749 { 4084 {
@@ -3751,6 +4086,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3751 } 4086 }
3752 else 4087 else
3753 { 4088 {
4089 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4090 {
4091 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4092
4093 if (linknum < 0)
4094 return UUID.Zero.ToString();
4095
4096 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4097 if (avatars.Count > linknum)
4098 {
4099 return avatars[linknum].UUID.ToString();
4100 }
4101 }
3754 return UUID.Zero.ToString(); 4102 return UUID.Zero.ToString();
3755 } 4103 }
3756 } 4104 }
@@ -3850,17 +4198,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3850 m_host.AddScriptLPS(1); 4198 m_host.AddScriptLPS(1);
3851 int count = 0; 4199 int count = 0;
3852 4200
3853 lock (m_host.TaskInventory) 4201 m_host.TaskInventory.LockItemsForRead(true);
4202 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3854 { 4203 {
3855 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4204 if (inv.Value.Type == type || type == -1)
3856 { 4205 {
3857 if (inv.Value.Type == type || type == -1) 4206 count = count + 1;
3858 {
3859 count = count + 1;
3860 }
3861 } 4207 }
3862 } 4208 }
3863 4209
4210 m_host.TaskInventory.LockItemsForRead(false);
3864 return count; 4211 return count;
3865 } 4212 }
3866 4213
@@ -3869,16 +4216,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3869 m_host.AddScriptLPS(1); 4216 m_host.AddScriptLPS(1);
3870 ArrayList keys = new ArrayList(); 4217 ArrayList keys = new ArrayList();
3871 4218
3872 lock (m_host.TaskInventory) 4219 m_host.TaskInventory.LockItemsForRead(true);
4220 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3873 { 4221 {
3874 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4222 if (inv.Value.Type == type || type == -1)
3875 { 4223 {
3876 if (inv.Value.Type == type || type == -1) 4224 keys.Add(inv.Value.Name);
3877 {
3878 keys.Add(inv.Value.Name);
3879 }
3880 } 4225 }
3881 } 4226 }
4227 m_host.TaskInventory.LockItemsForRead(false);
3882 4228
3883 if (keys.Count == 0) 4229 if (keys.Count == 0)
3884 { 4230 {
@@ -3916,7 +4262,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3916 if (item == null) 4262 if (item == null)
3917 { 4263 {
3918 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4264 llSay(0, String.Format("Could not find object '{0}'", inventory));
3919 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4265 return;
4266// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3920 } 4267 }
3921 4268
3922 UUID objId = item.ItemID; 4269 UUID objId = item.ItemID;
@@ -3944,33 +4291,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3944 return; 4291 return;
3945 } 4292 }
3946 } 4293 }
4294
3947 // destination is an avatar 4295 // destination is an avatar
3948 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4296 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3949 4297
3950 if (agentItem == null) 4298 if (agentItem == null)
3951 return; 4299 return;
3952 4300
3953 if (m_TransferModule != null) 4301 byte[] bucket = new byte[1];
3954 { 4302 bucket[0] = (byte)item.Type;
3955 byte[] bucket = new byte[] { (byte)item.Type }; 4303 //byte[] objBytes = agentItem.ID.GetBytes();
4304 //Array.Copy(objBytes, 0, bucket, 1, 16);
3956 4305
3957 GridInstantMessage msg = new GridInstantMessage(World, 4306 GridInstantMessage msg = new GridInstantMessage(World,
3958 m_host.UUID, m_host.Name + ", an object owned by " + 4307 m_host.OwnerID, m_host.Name, destId,
3959 resolveName(m_host.OwnerID) + ",", destId, 4308 (byte)InstantMessageDialog.TaskInventoryOffered,
3960 (byte)InstantMessageDialog.TaskInventoryOffered, 4309 false, item.Name+". "+m_host.Name+" is located at "+
3961 false, item.Name + "\n" + m_host.Name + " is located at " + 4310 World.RegionInfo.RegionName+" "+
3962 World.RegionInfo.RegionName+" "+ 4311 m_host.AbsolutePosition.ToString(),
3963 m_host.AbsolutePosition.ToString(), 4312 agentItem.ID, true, m_host.AbsolutePosition,
3964 agentItem.ID, true, m_host.AbsolutePosition, 4313 bucket);
3965 bucket);
3966 4314
3967 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4315 ScenePresence sp;
3968 }
3969 4316
4317 if (World.TryGetScenePresence(destId, out sp))
4318 {
4319 sp.ControllingClient.SendInstantMessage(msg);
4320 }
4321 else
4322 {
4323 if (m_TransferModule != null)
4324 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4325 }
4326
4327 //This delay should only occur when giving inventory to avatars.
3970 ScriptSleep(3000); 4328 ScriptSleep(3000);
3971 } 4329 }
3972 } 4330 }
3973 4331
4332 [DebuggerNonUserCode]
3974 public void llRemoveInventory(string name) 4333 public void llRemoveInventory(string name)
3975 { 4334 {
3976 m_host.AddScriptLPS(1); 4335 m_host.AddScriptLPS(1);
@@ -4014,109 +4373,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4014 { 4373 {
4015 m_host.AddScriptLPS(1); 4374 m_host.AddScriptLPS(1);
4016 4375
4017 UUID uuid = (UUID)id; 4376 UUID uuid;
4018 PresenceInfo pinfo = null; 4377 if (UUID.TryParse(id, out uuid))
4019 UserAccount account;
4020
4021 UserInfoCacheEntry ce;
4022 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4023 { 4378 {
4024 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4379 PresenceInfo pinfo = null;
4025 if (account == null) 4380 UserAccount account;
4381
4382 UserInfoCacheEntry ce;
4383 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4026 { 4384 {
4027 m_userInfoCache[uuid] = null; // Cache negative 4385 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4028 return UUID.Zero.ToString(); 4386 if (account == null)
4029 } 4387 {
4388 m_userInfoCache[uuid] = null; // Cache negative
4389 return UUID.Zero.ToString();
4390 }
4030 4391
4031 4392
4032 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4393 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4033 if (pinfos != null && pinfos.Length > 0) 4394 if (pinfos != null && pinfos.Length > 0)
4034 {
4035 foreach (PresenceInfo p in pinfos)
4036 { 4395 {
4037 if (p.RegionID != UUID.Zero) 4396 foreach (PresenceInfo p in pinfos)
4038 { 4397 {
4039 pinfo = p; 4398 if (p.RegionID != UUID.Zero)
4399 {
4400 pinfo = p;
4401 }
4040 } 4402 }
4041 } 4403 }
4042 }
4043 4404
4044 ce = new UserInfoCacheEntry(); 4405 ce = new UserInfoCacheEntry();
4045 ce.time = Util.EnvironmentTickCount(); 4406 ce.time = Util.EnvironmentTickCount();
4046 ce.account = account; 4407 ce.account = account;
4047 ce.pinfo = pinfo; 4408 ce.pinfo = pinfo;
4048 } 4409 m_userInfoCache[uuid] = ce;
4049 else 4410 }
4050 { 4411 else
4051 if (ce == null) 4412 {
4052 return UUID.Zero.ToString(); 4413 if (ce == null)
4414 return UUID.Zero.ToString();
4053 4415
4054 account = ce.account; 4416 account = ce.account;
4055 pinfo = ce.pinfo; 4417 pinfo = ce.pinfo;
4056 } 4418 }
4057 4419
4058 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4420 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4059 {
4060 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4061 if (pinfos != null && pinfos.Length > 0)
4062 { 4421 {
4063 foreach (PresenceInfo p in pinfos) 4422 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4423 if (pinfos != null && pinfos.Length > 0)
4064 { 4424 {
4065 if (p.RegionID != UUID.Zero) 4425 foreach (PresenceInfo p in pinfos)
4066 { 4426 {
4067 pinfo = p; 4427 if (p.RegionID != UUID.Zero)
4428 {
4429 pinfo = p;
4430 }
4068 } 4431 }
4069 } 4432 }
4070 } 4433 else
4071 else 4434 pinfo = null;
4072 pinfo = null;
4073 4435
4074 ce.time = Util.EnvironmentTickCount(); 4436 ce.time = Util.EnvironmentTickCount();
4075 ce.pinfo = pinfo; 4437 ce.pinfo = pinfo;
4076 } 4438 }
4077 4439
4078 string reply = String.Empty; 4440 string reply = String.Empty;
4079 4441
4080 switch (data) 4442 switch (data)
4081 { 4443 {
4082 case 1: // DATA_ONLINE (0|1) 4444 case 1: // DATA_ONLINE (0|1)
4083 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4445 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4084 reply = "1"; 4446 reply = "1";
4085 else 4447 else
4086 reply = "0"; 4448 reply = "0";
4087 break; 4449 break;
4088 case 2: // DATA_NAME (First Last) 4450 case 2: // DATA_NAME (First Last)
4089 reply = account.FirstName + " " + account.LastName; 4451 reply = account.FirstName + " " + account.LastName;
4090 break; 4452 break;
4091 case 3: // DATA_BORN (YYYY-MM-DD) 4453 case 3: // DATA_BORN (YYYY-MM-DD)
4092 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4454 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4093 born = born.AddSeconds(account.Created); 4455 born = born.AddSeconds(account.Created);
4094 reply = born.ToString("yyyy-MM-dd"); 4456 reply = born.ToString("yyyy-MM-dd");
4095 break; 4457 break;
4096 case 4: // DATA_RATING (0,0,0,0,0,0) 4458 case 4: // DATA_RATING (0,0,0,0,0,0)
4097 reply = "0,0,0,0,0,0"; 4459 reply = "0,0,0,0,0,0";
4098 break; 4460 break;
4099 case 7: // DATA_USERLEVEL (integer) 4461 case 8: // DATA_PAYINFO (0|1|2|3)
4100 reply = account.UserLevel.ToString(); 4462 reply = "0";
4101 break; 4463 break;
4102 case 8: // DATA_PAYINFO (0|1|2|3) 4464 default:
4103 reply = "0"; 4465 return UUID.Zero.ToString(); // Raise no event
4104 break; 4466 }
4105 default:
4106 return UUID.Zero.ToString(); // Raise no event
4107 }
4108 4467
4109 UUID rq = UUID.Random(); 4468 UUID rq = UUID.Random();
4110 4469
4111 UUID tid = AsyncCommands. 4470 UUID tid = AsyncCommands.
4112 DataserverPlugin.RegisterRequest(m_host.LocalId, 4471 DataserverPlugin.RegisterRequest(m_host.LocalId,
4113 m_item.ItemID, rq.ToString()); 4472 m_item.ItemID, rq.ToString());
4114 4473
4115 AsyncCommands. 4474 AsyncCommands.
4116 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4475 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4117 4476
4118 ScriptSleep(100); 4477 ScriptSleep(100);
4119 return tid.ToString(); 4478 return tid.ToString();
4479 }
4480 else
4481 {
4482 ShoutError("Invalid UUID passed to llRequestAgentData.");
4483 }
4484 return "";
4120 } 4485 }
4121 4486
4122 public LSL_String llRequestInventoryData(string name) 4487 public LSL_String llRequestInventoryData(string name)
@@ -4173,13 +4538,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4173 if (UUID.TryParse(agent, out agentId)) 4538 if (UUID.TryParse(agent, out agentId))
4174 { 4539 {
4175 ScenePresence presence = World.GetScenePresence(agentId); 4540 ScenePresence presence = World.GetScenePresence(agentId);
4176 if (presence != null) 4541 if (presence != null && presence.PresenceType != PresenceType.Npc)
4177 { 4542 {
4543 // agent must not be a god
4544 if (presence.UserLevel >= 200) return;
4545
4178 // agent must be over the owners land 4546 // agent must be over the owners land
4179 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4547 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4180 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4548 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4181 { 4549 {
4182 World.TeleportClientHome(agentId, presence.ControllingClient); 4550 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4551 {
4552 // They can't be teleported home for some reason
4553 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4554 if (regionInfo != null)
4555 {
4556 World.RequestTeleportLocation(
4557 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4558 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4559 }
4560 }
4183 } 4561 }
4184 } 4562 }
4185 } 4563 }
@@ -4286,7 +4664,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4286 UUID av = new UUID(); 4664 UUID av = new UUID();
4287 if (!UUID.TryParse(agent,out av)) 4665 if (!UUID.TryParse(agent,out av))
4288 { 4666 {
4289 LSLError("First parameter to llDialog needs to be a key"); 4667 //LSLError("First parameter to llDialog needs to be a key");
4290 return; 4668 return;
4291 } 4669 }
4292 4670
@@ -4318,7 +4696,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4318 public void llCollisionSound(string impact_sound, double impact_volume) 4696 public void llCollisionSound(string impact_sound, double impact_volume)
4319 { 4697 {
4320 m_host.AddScriptLPS(1); 4698 m_host.AddScriptLPS(1);
4321 4699
4700 if(impact_sound == "")
4701 {
4702 m_host.CollisionSoundVolume = (float)impact_volume;
4703 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4704 m_host.CollisionSoundType = 0;
4705 return;
4706 }
4322 // TODO: Parameter check logic required. 4707 // TODO: Parameter check logic required.
4323 UUID soundId = UUID.Zero; 4708 UUID soundId = UUID.Zero;
4324 if (!UUID.TryParse(impact_sound, out soundId)) 4709 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4331,6 +4716,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4331 4716
4332 m_host.CollisionSound = soundId; 4717 m_host.CollisionSound = soundId;
4333 m_host.CollisionSoundVolume = (float)impact_volume; 4718 m_host.CollisionSoundVolume = (float)impact_volume;
4719 m_host.CollisionSoundType = 1;
4334 } 4720 }
4335 4721
4336 public LSL_String llGetAnimation(string id) 4722 public LSL_String llGetAnimation(string id)
@@ -4344,14 +4730,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4344 4730
4345 if (m_host.RegionHandle == presence.RegionHandle) 4731 if (m_host.RegionHandle == presence.RegionHandle)
4346 { 4732 {
4347 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4348
4349 if (presence != null) 4733 if (presence != null)
4350 { 4734 {
4351 AnimationSet currentAnims = presence.Animator.Animations; 4735 if (presence.SitGround)
4352 string currentAnimationState = String.Empty; 4736 return "Sitting on Ground";
4353 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4737 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4354 return currentAnimationState; 4738 return "Sitting";
4739
4740 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4741 string lslMovementAnimation;
4742
4743 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4744 return lslMovementAnimation;
4355 } 4745 }
4356 } 4746 }
4357 4747
@@ -4498,7 +4888,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4498 { 4888 {
4499 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4889 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4500 float distance_term = distance * distance * distance; // Script Energy 4890 float distance_term = distance * distance * distance; // Script Energy
4501 float pusher_mass = m_host.GetMass(); 4891 // use total object mass and not part
4892 float pusher_mass = m_host.ParentGroup.GetMass();
4502 4893
4503 float PUSH_ATTENUATION_DISTANCE = 17f; 4894 float PUSH_ATTENUATION_DISTANCE = 17f;
4504 float PUSH_ATTENUATION_SCALE = 5f; 4895 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4748,6 +5139,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4748 { 5139 {
4749 return item.AssetID.ToString(); 5140 return item.AssetID.ToString();
4750 } 5141 }
5142 m_host.TaskInventory.LockItemsForRead(false);
4751 5143
4752 return UUID.Zero.ToString(); 5144 return UUID.Zero.ToString();
4753 } 5145 }
@@ -4881,7 +5273,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4881 public LSL_Vector llGetCenterOfMass() 5273 public LSL_Vector llGetCenterOfMass()
4882 { 5274 {
4883 m_host.AddScriptLPS(1); 5275 m_host.AddScriptLPS(1);
4884 Vector3 center = m_host.GetGeometricCenter(); 5276 Vector3 center = m_host.GetCenterOfMass();
4885 return new LSL_Vector(center.X,center.Y,center.Z); 5277 return new LSL_Vector(center.X,center.Y,center.Z);
4886 } 5278 }
4887 5279
@@ -4900,14 +5292,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4900 { 5292 {
4901 m_host.AddScriptLPS(1); 5293 m_host.AddScriptLPS(1);
4902 5294
4903 if (src == null) 5295 return src.Length;
4904 {
4905 return 0;
4906 }
4907 else
4908 {
4909 return src.Length;
4910 }
4911 } 5296 }
4912 5297
4913 public LSL_Integer llList2Integer(LSL_List src, int index) 5298 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4978,7 +5363,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4978 else if (src.Data[index] is LSL_Float) 5363 else if (src.Data[index] is LSL_Float)
4979 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5364 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4980 else if (src.Data[index] is LSL_String) 5365 else if (src.Data[index] is LSL_String)
4981 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5366 {
5367 string str = ((LSL_String) src.Data[index]).m_string;
5368 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5369 if (m != Match.Empty)
5370 {
5371 str = m.Value;
5372 double d = 0.0;
5373 if (!Double.TryParse(str, out d))
5374 return 0.0;
5375
5376 return d;
5377 }
5378 return 0.0;
5379 }
4982 return Convert.ToDouble(src.Data[index]); 5380 return Convert.ToDouble(src.Data[index]);
4983 } 5381 }
4984 catch (FormatException) 5382 catch (FormatException)
@@ -5020,7 +5418,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5020 // for completion and should LSL_Key ever be implemented 5418 // for completion and should LSL_Key ever be implemented
5021 // as it's own struct 5419 // as it's own struct
5022 else if (!(src.Data[index] is LSL_String || 5420 else if (!(src.Data[index] is LSL_String ||
5023 src.Data[index] is LSL_Key)) 5421 src.Data[index] is LSL_Key ||
5422 src.Data[index] is String))
5024 { 5423 {
5025 return ""; 5424 return "";
5026 } 5425 }
@@ -5278,7 +5677,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5278 } 5677 }
5279 } 5678 }
5280 } 5679 }
5281 else { 5680 else
5681 {
5282 object[] array = new object[src.Length]; 5682 object[] array = new object[src.Length];
5283 Array.Copy(src.Data, 0, array, 0, src.Length); 5683 Array.Copy(src.Data, 0, array, 0, src.Length);
5284 result = new LSL_List(array); 5684 result = new LSL_List(array);
@@ -5385,7 +5785,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5385 public LSL_Integer llGetRegionAgentCount() 5785 public LSL_Integer llGetRegionAgentCount()
5386 { 5786 {
5387 m_host.AddScriptLPS(1); 5787 m_host.AddScriptLPS(1);
5388 return new LSL_Integer(World.GetRootAgentCount()); 5788
5789 int count = 0;
5790 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5791 count++;
5792 });
5793
5794 return new LSL_Integer(count);
5389 } 5795 }
5390 5796
5391 public LSL_Vector llGetRegionCorner() 5797 public LSL_Vector llGetRegionCorner()
@@ -5618,6 +6024,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5618 flags |= ScriptBaseClass.AGENT_AWAY; 6024 flags |= ScriptBaseClass.AGENT_AWAY;
5619 } 6025 }
5620 6026
6027 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6028 UUID[] anims = agent.Animator.GetAnimationArray();
6029 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6030 {
6031 flags |= ScriptBaseClass.AGENT_BUSY;
6032 }
6033
5621 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6034 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5622 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6035 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5623 { 6036 {
@@ -5665,6 +6078,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5665 flags |= ScriptBaseClass.AGENT_SITTING; 6078 flags |= ScriptBaseClass.AGENT_SITTING;
5666 } 6079 }
5667 6080
6081 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6082 {
6083 flags |= ScriptBaseClass.AGENT_MALE;
6084 }
6085
5668 return flags; 6086 return flags;
5669 } 6087 }
5670 6088
@@ -5812,9 +6230,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5812 6230
5813 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6231 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5814 6232
5815 foreach (SceneObjectPart part in parts) 6233 try
6234 {
6235 foreach (SceneObjectPart part in parts)
6236 {
6237 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6238 }
6239 }
6240 finally
5816 { 6241 {
5817 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5818 } 6242 }
5819 } 6243 }
5820 6244
@@ -5866,13 +6290,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5866 6290
5867 if (m_host.OwnerID == land.LandData.OwnerID) 6291 if (m_host.OwnerID == land.LandData.OwnerID)
5868 { 6292 {
5869 World.TeleportClientHome(agentID, presence.ControllingClient); 6293 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6294 presence.TeleportWithMomentum(pos, null);
6295 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5870 } 6296 }
5871 } 6297 }
5872 } 6298 }
5873 ScriptSleep(5000); 6299 ScriptSleep(5000);
5874 } 6300 }
5875 6301
6302 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6303 {
6304 return ParseString2List(str, separators, in_spacers, false);
6305 }
6306
5876 public LSL_Integer llOverMyLand(string id) 6307 public LSL_Integer llOverMyLand(string id)
5877 { 6308 {
5878 m_host.AddScriptLPS(1); 6309 m_host.AddScriptLPS(1);
@@ -5931,20 +6362,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5931 return agentSize; 6362 return agentSize;
5932 } 6363 }
5933 6364
5934 public LSL_Integer llSameGroup(string agent) 6365 public LSL_Integer llSameGroup(string id)
5935 { 6366 {
5936 m_host.AddScriptLPS(1); 6367 m_host.AddScriptLPS(1);
5937 UUID agentId = new UUID(); 6368 UUID uuid = new UUID();
5938 if (!UUID.TryParse(agent, out agentId)) 6369 if (!UUID.TryParse(id, out uuid))
5939 return new LSL_Integer(0); 6370 return new LSL_Integer(0);
5940 ScenePresence presence = World.GetScenePresence(agentId); 6371
5941 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6372 // Check if it's a group key
5942 return new LSL_Integer(0); 6373 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5943 IClientAPI client = presence.ControllingClient;
5944 if (m_host.GroupID == client.ActiveGroupId)
5945 return new LSL_Integer(1); 6374 return new LSL_Integer(1);
5946 else 6375
6376 // We got passed a UUID.Zero
6377 if (uuid == UUID.Zero)
5947 return new LSL_Integer(0); 6378 return new LSL_Integer(0);
6379
6380 // Handle the case where id names an avatar
6381 ScenePresence presence = World.GetScenePresence(uuid);
6382 if (presence != null)
6383 {
6384 if (presence.IsChildAgent)
6385 return new LSL_Integer(0);
6386
6387 IClientAPI client = presence.ControllingClient;
6388 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6389 return new LSL_Integer(1);
6390
6391 return new LSL_Integer(0);
6392 }
6393
6394 // Handle object case
6395 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6396 if (part != null)
6397 {
6398 // This will handle both deed and non-deed and also the no
6399 // group case
6400 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6401 return new LSL_Integer(1);
6402
6403 return new LSL_Integer(0);
6404 }
6405
6406 return new LSL_Integer(0);
5948 } 6407 }
5949 6408
5950 public void llUnSit(string id) 6409 public void llUnSit(string id)
@@ -6069,7 +6528,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6069 return m_host.ParentGroup.AttachmentPoint; 6528 return m_host.ParentGroup.AttachmentPoint;
6070 } 6529 }
6071 6530
6072 public LSL_Integer llGetFreeMemory() 6531 public virtual LSL_Integer llGetFreeMemory()
6073 { 6532 {
6074 m_host.AddScriptLPS(1); 6533 m_host.AddScriptLPS(1);
6075 // Make scripts designed for LSO happy 6534 // Make scripts designed for LSO happy
@@ -6186,7 +6645,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6186 SetParticleSystem(m_host, rules); 6645 SetParticleSystem(m_host, rules);
6187 } 6646 }
6188 6647
6189 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6648 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6649 {
6190 6650
6191 6651
6192 if (rules.Length == 0) 6652 if (rules.Length == 0)
@@ -6500,6 +6960,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6500 6960
6501 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6961 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6502 { 6962 {
6963 // LSL quaternions can normalize to 0, normal Quaternions can't.
6964 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6965 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6966
6503 part.SitTargetPosition = offset; 6967 part.SitTargetPosition = offset;
6504 part.SitTargetOrientation = rot; 6968 part.SitTargetOrientation = rot;
6505 part.ParentGroup.HasGroupChanged = true; 6969 part.ParentGroup.HasGroupChanged = true;
@@ -6655,13 +7119,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6655 UUID av = new UUID(); 7119 UUID av = new UUID();
6656 if (!UUID.TryParse(avatar,out av)) 7120 if (!UUID.TryParse(avatar,out av))
6657 { 7121 {
6658 LSLError("First parameter to llDialog needs to be a key"); 7122 //LSLError("First parameter to llDialog needs to be a key");
6659 return; 7123 return;
6660 } 7124 }
6661 if (buttons.Length < 1) 7125 if (buttons.Length < 1)
6662 { 7126 {
6663 LSLError("No less than 1 button can be shown"); 7127 buttons.Add("OK");
6664 return;
6665 } 7128 }
6666 if (buttons.Length > 12) 7129 if (buttons.Length > 12)
6667 { 7130 {
@@ -6678,7 +7141,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6678 } 7141 }
6679 if (buttons.Data[i].ToString().Length > 24) 7142 if (buttons.Data[i].ToString().Length > 24)
6680 { 7143 {
6681 LSLError("button label cannot be longer than 24 characters"); 7144 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6682 return; 7145 return;
6683 } 7146 }
6684 buts[i] = buttons.Data[i].ToString(); 7147 buts[i] = buttons.Data[i].ToString();
@@ -6745,9 +7208,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6745 return; 7208 return;
6746 } 7209 }
6747 7210
6748 // the rest of the permission checks are done in RezScript, so check the pin there as well 7211 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6749 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7212 if (dest != null)
7213 {
7214 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7215 {
7216 // the rest of the permission checks are done in RezScript, so check the pin there as well
7217 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6750 7218
7219 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7220 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7221 }
7222 }
6751 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7223 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6752 ScriptSleep(3000); 7224 ScriptSleep(3000);
6753 } 7225 }
@@ -6810,19 +7282,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6810 public LSL_String llMD5String(string src, int nonce) 7282 public LSL_String llMD5String(string src, int nonce)
6811 { 7283 {
6812 m_host.AddScriptLPS(1); 7284 m_host.AddScriptLPS(1);
6813 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7285 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6814 } 7286 }
6815 7287
6816 public LSL_String llSHA1String(string src) 7288 public LSL_String llSHA1String(string src)
6817 { 7289 {
6818 m_host.AddScriptLPS(1); 7290 m_host.AddScriptLPS(1);
6819 return Util.SHA1Hash(src).ToLower(); 7291 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6820 } 7292 }
6821 7293
6822 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7294 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6823 { 7295 {
6824 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7296 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6825 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7297 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7298 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7299 return shapeBlock;
6826 7300
6827 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7301 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6828 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7302 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6927,6 +7401,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6927 // Prim type box, cylinder and prism. 7401 // Prim type box, cylinder and prism.
6928 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) 7402 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)
6929 { 7403 {
7404 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7405 return;
7406
6930 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7407 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6931 ObjectShapePacket.ObjectDataBlock shapeBlock; 7408 ObjectShapePacket.ObjectDataBlock shapeBlock;
6932 7409
@@ -6980,6 +7457,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6980 // Prim type sphere. 7457 // Prim type sphere.
6981 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7458 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6982 { 7459 {
7460 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7461 return;
7462
6983 ObjectShapePacket.ObjectDataBlock shapeBlock; 7463 ObjectShapePacket.ObjectDataBlock shapeBlock;
6984 7464
6985 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7465 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7021,6 +7501,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7021 // Prim type torus, tube and ring. 7501 // Prim type torus, tube and ring.
7022 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) 7502 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)
7023 { 7503 {
7504 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7505 return;
7506
7024 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7507 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7025 ObjectShapePacket.ObjectDataBlock shapeBlock; 7508 ObjectShapePacket.ObjectDataBlock shapeBlock;
7026 7509
@@ -7156,6 +7639,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7156 // Prim type sculpt. 7639 // Prim type sculpt.
7157 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7640 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7158 { 7641 {
7642 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7643 return;
7644
7159 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7645 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7160 UUID sculptId; 7646 UUID sculptId;
7161 7647
@@ -7180,7 +7666,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7180 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7666 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7181 { 7667 {
7182 // default 7668 // default
7183 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7669 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7184 } 7670 }
7185 7671
7186 part.Shape.SetSculptProperties((byte)type, sculptId); 7672 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7197,48 +7683,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7197 ScriptSleep(200); 7683 ScriptSleep(200);
7198 } 7684 }
7199 7685
7200 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7686 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7201 { 7687 {
7202 m_host.AddScriptLPS(1); 7688 m_host.AddScriptLPS(1);
7203 7689
7204 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7690 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7205 7691
7206 ScriptSleep(200); 7692 ScriptSleep(200);
7207 } 7693 }
7208 7694
7209 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7695 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7210 { 7696 {
7211 m_host.AddScriptLPS(1); 7697 List<object> parts = new List<object>();
7698 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7699 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7700 foreach (SceneObjectPart p in prims)
7701 parts.Add(p);
7702 foreach (ScenePresence p in avatars)
7703 parts.Add(p);
7212 7704
7213 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7705 LSL_List remaining = null;
7706 uint rulesParsed = 0;
7707
7708 if (parts.Count > 0)
7709 {
7710 foreach (object part in parts)
7711 {
7712 if (part is SceneObjectPart)
7713 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7714 else
7715 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7716 }
7717
7718 while ((object)remaining != null && remaining.Length > 2)
7719 {
7720 linknumber = remaining.GetLSLIntegerItem(0);
7721 rules = remaining.GetSublist(1, -1);
7722 parts.Clear();
7723 prims = GetLinkParts(linknumber);
7724 avatars = GetLinkAvatars(linknumber);
7725 foreach (SceneObjectPart p in prims)
7726 parts.Add(p);
7727 foreach (ScenePresence p in avatars)
7728 parts.Add(p);
7729
7730 remaining = null;
7731 foreach (object part in parts)
7732 {
7733 if (part is SceneObjectPart)
7734 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7735 else
7736 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7737 }
7738 }
7739 }
7214 } 7740 }
7215 7741
7216 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7742 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7743 float material_density, float material_friction,
7744 float material_restitution, float material_gravity_modifier)
7217 { 7745 {
7218 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7746 ExtraPhysicsData physdata = new ExtraPhysicsData();
7747 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7748 physdata.Density = part.Density;
7749 physdata.Friction = part.Friction;
7750 physdata.Bounce = part.Bounciness;
7751 physdata.GravitationModifier = part.GravityModifier;
7219 7752
7220 LSL_List remaining = null; 7753 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7221 uint rulesParsed = 0; 7754 physdata.Density = material_density;
7755 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7756 physdata.Friction = material_friction;
7757 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7758 physdata.Bounce = material_restitution;
7759 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7760 physdata.GravitationModifier = material_gravity_modifier;
7222 7761
7223 foreach (SceneObjectPart part in parts) 7762 part.UpdateExtraPhysics(physdata);
7224 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7763 }
7225 7764
7226 while (remaining != null && remaining.Length > 2) 7765 public void llSetPhysicsMaterial(int material_bits,
7227 { 7766 float material_gravity_modifier, float material_restitution,
7228 linknumber = remaining.GetLSLIntegerItem(0); 7767 float material_friction, float material_density)
7229 rules = remaining.GetSublist(1, -1); 7768 {
7230 parts = GetLinkParts(linknumber); 7769 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7770 }
7231 7771
7232 foreach (SceneObjectPart part in parts) 7772 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7233 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7773 {
7774 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7775 llSetLinkPrimitiveParamsFast(linknumber, rules);
7776 ScriptSleep(200);
7777 }
7778
7779 // vector up using libomv (c&p from sop )
7780 // vector up rotated by r
7781 private Vector3 Zrot(Quaternion r)
7782 {
7783 double x, y, z, m;
7784
7785 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7786 if (Math.Abs(1.0 - m) > 0.000001)
7787 {
7788 m = 1.0 / Math.Sqrt(m);
7789 r.X *= (float)m;
7790 r.Y *= (float)m;
7791 r.Z *= (float)m;
7792 r.W *= (float)m;
7234 } 7793 }
7794
7795 x = 2 * (r.X * r.Z + r.Y * r.W);
7796 y = 2 * (-r.X * r.W + r.Y * r.Z);
7797 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7798
7799 return new Vector3((float)x, (float)y, (float)z);
7235 } 7800 }
7236 7801
7237 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7802 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7238 { 7803 {
7804 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7805 return null;
7806
7239 int idx = 0; 7807 int idx = 0;
7240 int idxStart = 0; 7808 int idxStart = 0;
7241 7809
7810 SceneObjectGroup parentgrp = part.ParentGroup;
7811
7242 bool positionChanged = false; 7812 bool positionChanged = false;
7243 LSL_Vector currentPosition = GetPartLocalPos(part); 7813 LSL_Vector currentPosition = GetPartLocalPos(part);
7244 7814
@@ -7263,8 +7833,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7263 return null; 7833 return null;
7264 7834
7265 v=rules.GetVector3Item(idx++); 7835 v=rules.GetVector3Item(idx++);
7266 positionChanged = true;
7267 currentPosition = GetSetPosTarget(part, v, currentPosition); 7836 currentPosition = GetSetPosTarget(part, v, currentPosition);
7837 positionChanged = true;
7268 7838
7269 break; 7839 break;
7270 case (int)ScriptBaseClass.PRIM_SIZE: 7840 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7530,7 +8100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7530 return null; 8100 return null;
7531 8101
7532 string ph = rules.Data[idx++].ToString(); 8102 string ph = rules.Data[idx++].ToString();
7533 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8103 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7534 8104
7535 break; 8105 break;
7536 8106
@@ -7548,12 +8118,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7548 part.ScriptSetPhysicsStatus(physics); 8118 part.ScriptSetPhysicsStatus(physics);
7549 break; 8119 break;
7550 8120
8121 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8122 if (remain < 1)
8123 return null;
8124
8125 int shape_type = rules.GetLSLIntegerItem(idx++);
8126
8127 ExtraPhysicsData physdata = new ExtraPhysicsData();
8128 physdata.Density = part.Density;
8129 physdata.Bounce = part.Bounciness;
8130 physdata.GravitationModifier = part.GravityModifier;
8131 physdata.PhysShapeType = (PhysShapeType)shape_type;
8132
8133 part.UpdateExtraPhysics(physdata);
8134
8135 break;
8136
8137 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8138 if (remain < 5)
8139 return null;
8140
8141 int material_bits = rules.GetLSLIntegerItem(idx++);
8142 float material_density = (float)rules.GetLSLFloatItem(idx++);
8143 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8144 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8145 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8146
8147 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8148
8149 break;
8150
7551 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8151 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7552 if (remain < 1) 8152 if (remain < 1)
7553 return null; 8153 return null;
7554 string temp = rules.Data[idx++].ToString(); 8154 string temp = rules.Data[idx++].ToString();
7555 8155
7556 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8156 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7557 8157
7558 break; 8158 break;
7559 8159
@@ -7622,7 +8222,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7622 if (part.ParentGroup.RootPart == part) 8222 if (part.ParentGroup.RootPart == part)
7623 { 8223 {
7624 SceneObjectGroup parent = part.ParentGroup; 8224 SceneObjectGroup parent = part.ParentGroup;
7625 parent.UpdateGroupPosition(currentPosition); 8225 Util.FireAndForget(delegate(object x) {
8226 parent.UpdateGroupPosition(currentPosition);
8227 });
7626 } 8228 }
7627 else 8229 else
7628 { 8230 {
@@ -7667,10 +8269,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7667 8269
7668 public LSL_String llXorBase64Strings(string str1, string str2) 8270 public LSL_String llXorBase64Strings(string str1, string str2)
7669 { 8271 {
7670 m_host.AddScriptLPS(1); 8272 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7671 Deprecated("llXorBase64Strings"); 8273
7672 ScriptSleep(300); 8274 ScriptSleep(300);
7673 return String.Empty; 8275 m_host.AddScriptLPS(1);
8276
8277 if (str1 == String.Empty)
8278 return String.Empty;
8279 if (str2 == String.Empty)
8280 return str1;
8281
8282 int len = str2.Length;
8283 if ((len % 4) != 0) // LL is EVIL!!!!
8284 {
8285 while (str2.EndsWith("="))
8286 str2 = str2.Substring(0, str2.Length - 1);
8287
8288 len = str2.Length;
8289 int mod = len % 4;
8290
8291 if (mod == 1)
8292 str2 = str2.Substring(0, str2.Length - 1);
8293 else if (mod == 2)
8294 str2 += "==";
8295 else if (mod == 3)
8296 str2 += "=";
8297 }
8298
8299 byte[] data1;
8300 byte[] data2;
8301 try
8302 {
8303 data1 = Convert.FromBase64String(str1);
8304 data2 = Convert.FromBase64String(str2);
8305 }
8306 catch (Exception)
8307 {
8308 return new LSL_String(String.Empty);
8309 }
8310
8311 // For cases where the decoded length of s2 is greater
8312 // than the decoded length of s1, simply perform a normal
8313 // decode and XOR
8314 //
8315 if (data2.Length >= data1.Length)
8316 {
8317 for (int pos = 0 ; pos < data1.Length ; pos++ )
8318 data1[pos] ^= data2[pos];
8319
8320 return Convert.ToBase64String(data1);
8321 }
8322
8323 // Remove padding
8324 while (str1.EndsWith("="))
8325 str1 = str1.Substring(0, str1.Length - 1);
8326 while (str2.EndsWith("="))
8327 str2 = str2.Substring(0, str2.Length - 1);
8328
8329 byte[] d1 = new byte[str1.Length];
8330 byte[] d2 = new byte[str2.Length];
8331
8332 for (int i = 0 ; i < str1.Length ; i++)
8333 {
8334 int idx = b64.IndexOf(str1.Substring(i, 1));
8335 if (idx == -1)
8336 idx = 0;
8337 d1[i] = (byte)idx;
8338 }
8339
8340 for (int i = 0 ; i < str2.Length ; i++)
8341 {
8342 int idx = b64.IndexOf(str2.Substring(i, 1));
8343 if (idx == -1)
8344 idx = 0;
8345 d2[i] = (byte)idx;
8346 }
8347
8348 string output = String.Empty;
8349
8350 for (int pos = 0 ; pos < d1.Length ; pos++)
8351 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8352
8353 while (output.Length % 3 > 0)
8354 output += "=";
8355
8356 return output;
7674 } 8357 }
7675 8358
7676 public void llRemoteDataSetRegion() 8359 public void llRemoteDataSetRegion()
@@ -7794,13 +8477,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7794 public LSL_Integer llGetNumberOfPrims() 8477 public LSL_Integer llGetNumberOfPrims()
7795 { 8478 {
7796 m_host.AddScriptLPS(1); 8479 m_host.AddScriptLPS(1);
7797 int avatarCount = 0; 8480 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7798 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8481
7799 {
7800 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7801 avatarCount++;
7802 });
7803
7804 return m_host.ParentGroup.PrimCount + avatarCount; 8482 return m_host.ParentGroup.PrimCount + avatarCount;
7805 } 8483 }
7806 8484
@@ -7816,55 +8494,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7816 m_host.AddScriptLPS(1); 8494 m_host.AddScriptLPS(1);
7817 UUID objID = UUID.Zero; 8495 UUID objID = UUID.Zero;
7818 LSL_List result = new LSL_List(); 8496 LSL_List result = new LSL_List();
8497
8498 // If the ID is not valid, return null result
7819 if (!UUID.TryParse(obj, out objID)) 8499 if (!UUID.TryParse(obj, out objID))
7820 { 8500 {
7821 result.Add(new LSL_Vector()); 8501 result.Add(new LSL_Vector());
7822 result.Add(new LSL_Vector()); 8502 result.Add(new LSL_Vector());
7823 return result; 8503 return result;
7824 } 8504 }
8505
8506 // Check if this is an attached prim. If so, replace
8507 // the UUID with the avatar UUID and report it's bounding box
8508 SceneObjectPart part = World.GetSceneObjectPart(objID);
8509 if (part != null && part.ParentGroup.IsAttachment)
8510 objID = part.ParentGroup.AttachedAvatar;
8511
8512 // Find out if this is an avatar ID. If so, return it's box
7825 ScenePresence presence = World.GetScenePresence(objID); 8513 ScenePresence presence = World.GetScenePresence(objID);
7826 if (presence != null) 8514 if (presence != null)
7827 { 8515 {
7828 if (presence.ParentID == 0) // not sat on an object 8516 // As per LSL Wiki, there is no difference between sitting
8517 // and standing avatar since server 1.36
8518 LSL_Vector lower;
8519 LSL_Vector upper;
8520 if (presence.Animator.Animations.DefaultAnimation.AnimID
8521 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7829 { 8522 {
7830 LSL_Vector lower; 8523 // This is for ground sitting avatars
7831 LSL_Vector upper; 8524 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7832 if (presence.Animator.Animations.DefaultAnimation.AnimID 8525 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7833 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8526 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7834 {
7835 // This is for ground sitting avatars
7836 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7837 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7838 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7839 }
7840 else
7841 {
7842 // This is for standing/flying avatars
7843 float height = presence.Appearance.AvatarHeight / 2.0f;
7844 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7845 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7846 }
7847 result.Add(lower);
7848 result.Add(upper);
7849 return result;
7850 } 8527 }
7851 else 8528 else
7852 { 8529 {
7853 // sitting on an object so we need the bounding box of that 8530 // This is for standing/flying avatars
7854 // which should include the avatar so set the UUID to the 8531 float height = presence.Appearance.AvatarHeight / 2.0f;
7855 // UUID of the object the avatar is sat on and allow it to fall through 8532 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7856 // to processing an object 8533 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7857 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7858 objID = p.UUID;
7859 } 8534 }
8535
8536 // Adjust to the documented error offsets (see LSL Wiki)
8537 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8538 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8539
8540 if (lower.x > upper.x)
8541 lower.x = upper.x;
8542 if (lower.y > upper.y)
8543 lower.y = upper.y;
8544 if (lower.z > upper.z)
8545 lower.z = upper.z;
8546
8547 result.Add(lower);
8548 result.Add(upper);
8549 return result;
7860 } 8550 }
7861 SceneObjectPart part = World.GetSceneObjectPart(objID); 8551
8552 part = World.GetSceneObjectPart(objID);
7862 // Currently only works for single prims without a sitting avatar 8553 // Currently only works for single prims without a sitting avatar
7863 if (part != null) 8554 if (part != null)
7864 { 8555 {
7865 Vector3 halfSize = part.Scale / 2.0f; 8556 float minX;
7866 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8557 float maxX;
7867 LSL_Vector upper = new LSL_Vector(halfSize); 8558 float minY;
8559 float maxY;
8560 float minZ;
8561 float maxZ;
8562
8563 // This BBox is in sim coordinates, with the offset being
8564 // a contained point.
8565 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8566 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8567
8568 minX -= offsets[0].X;
8569 maxX -= offsets[0].X;
8570 minY -= offsets[0].Y;
8571 maxY -= offsets[0].Y;
8572 minZ -= offsets[0].Z;
8573 maxZ -= offsets[0].Z;
8574
8575 LSL_Vector lower;
8576 LSL_Vector upper;
8577
8578 // Adjust to the documented error offsets (see LSL Wiki)
8579 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8580 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8581
8582 if (lower.x > upper.x)
8583 lower.x = upper.x;
8584 if (lower.y > upper.y)
8585 lower.y = upper.y;
8586 if (lower.z > upper.z)
8587 lower.z = upper.z;
8588
7868 result.Add(lower); 8589 result.Add(lower);
7869 result.Add(upper); 8590 result.Add(upper);
7870 return result; 8591 return result;
@@ -7878,7 +8599,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7878 8599
7879 public LSL_Vector llGetGeometricCenter() 8600 public LSL_Vector llGetGeometricCenter()
7880 { 8601 {
7881 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8602 Vector3 tmp = m_host.GetGeometricCenter();
8603 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7882 } 8604 }
7883 8605
7884 public LSL_List llGetPrimitiveParams(LSL_List rules) 8606 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7906,24 +8628,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7906 { 8628 {
7907 m_host.AddScriptLPS(1); 8629 m_host.AddScriptLPS(1);
7908 8630
7909 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8631 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8632 // keep other options as before
7910 8633
8634 List<SceneObjectPart> parts;
8635 List<ScenePresence> avatars;
8636
7911 LSL_List res = new LSL_List(); 8637 LSL_List res = new LSL_List();
7912 LSL_List remaining = null; 8638 LSL_List remaining = null;
7913 8639
7914 foreach (SceneObjectPart part in parts) 8640 while (rules.Length > 0)
7915 {
7916 remaining = GetPrimParams(part, rules, ref res);
7917 }
7918
7919 while (remaining != null && remaining.Length > 2)
7920 { 8641 {
7921 linknumber = remaining.GetLSLIntegerItem(0);
7922 rules = remaining.GetSublist(1, -1);
7923 parts = GetLinkParts(linknumber); 8642 parts = GetLinkParts(linknumber);
8643 avatars = GetLinkAvatars(linknumber);
7924 8644
8645 remaining = null;
7925 foreach (SceneObjectPart part in parts) 8646 foreach (SceneObjectPart part in parts)
8647 {
7926 remaining = GetPrimParams(part, rules, ref res); 8648 remaining = GetPrimParams(part, rules, ref res);
8649 }
8650 foreach (ScenePresence avatar in avatars)
8651 {
8652 remaining = GetPrimParams(avatar, rules, ref res);
8653 }
8654
8655 if (remaining != null && remaining.Length > 0)
8656 {
8657 linknumber = remaining.GetLSLIntegerItem(0);
8658 rules = remaining.GetSublist(1, -1);
8659 }
7927 } 8660 }
7928 8661
7929 return res; 8662 return res;
@@ -7968,13 +8701,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7968 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8701 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7969 part.AbsolutePosition.Y, 8702 part.AbsolutePosition.Y,
7970 part.AbsolutePosition.Z); 8703 part.AbsolutePosition.Z);
7971 // For some reason, the part.AbsolutePosition.* values do not change if the
7972 // linkset is rotated; they always reflect the child prim's world position
7973 // as though the linkset is unrotated. This is incompatible behavior with SL's
7974 // implementation, so will break scripts imported from there (not to mention it
7975 // makes it more difficult to determine a child prim's actual inworld position).
7976 if (part.ParentID != 0)
7977 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7978 res.Add(v); 8704 res.Add(v);
7979 break; 8705 break;
7980 8706
@@ -8146,30 +8872,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8146 if (remain < 1) 8872 if (remain < 1)
8147 return null; 8873 return null;
8148 8874
8149 face=(int)rules.GetLSLIntegerItem(idx++); 8875 face = (int)rules.GetLSLIntegerItem(idx++);
8150 8876
8151 tex = part.Shape.Textures; 8877 tex = part.Shape.Textures;
8878 int shiny;
8152 if (face == ScriptBaseClass.ALL_SIDES) 8879 if (face == ScriptBaseClass.ALL_SIDES)
8153 { 8880 {
8154 for (face = 0; face < GetNumberOfSides(part); face++) 8881 for (face = 0; face < GetNumberOfSides(part); face++)
8155 { 8882 {
8156 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8883 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8157 // Convert Shininess to PRIM_SHINY_* 8884 if (shinyness == Shininess.High)
8158 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8885 {
8159 // PRIM_BUMP_* 8886 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8160 res.Add(new LSL_Integer((int)texface.Bump)); 8887 }
8888 else if (shinyness == Shininess.Medium)
8889 {
8890 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8891 }
8892 else if (shinyness == Shininess.Low)
8893 {
8894 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8895 }
8896 else
8897 {
8898 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8899 }
8900 res.Add(new LSL_Integer(shiny));
8901 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8161 } 8902 }
8162 } 8903 }
8163 else 8904 else
8164 { 8905 {
8165 if (face >= 0 && face < GetNumberOfSides(part)) 8906 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8907 if (shinyness == Shininess.High)
8166 { 8908 {
8167 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8909 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8168 // Convert Shininess to PRIM_SHINY_*
8169 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8170 // PRIM_BUMP_*
8171 res.Add(new LSL_Integer((int)texface.Bump));
8172 } 8910 }
8911 else if (shinyness == Shininess.Medium)
8912 {
8913 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8914 }
8915 else if (shinyness == Shininess.Low)
8916 {
8917 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8918 }
8919 else
8920 {
8921 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8922 }
8923 res.Add(new LSL_Integer(shiny));
8924 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8173 } 8925 }
8174 break; 8926 break;
8175 8927
@@ -8177,24 +8929,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8177 if (remain < 1) 8929 if (remain < 1)
8178 return null; 8930 return null;
8179 8931
8180 face=(int)rules.GetLSLIntegerItem(idx++); 8932 face = (int)rules.GetLSLIntegerItem(idx++);
8181 8933
8182 tex = part.Shape.Textures; 8934 tex = part.Shape.Textures;
8935 int fullbright;
8183 if (face == ScriptBaseClass.ALL_SIDES) 8936 if (face == ScriptBaseClass.ALL_SIDES)
8184 { 8937 {
8185 for (face = 0; face < GetNumberOfSides(part); face++) 8938 for (face = 0; face < GetNumberOfSides(part); face++)
8186 { 8939 {
8187 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8940 if (tex.GetFace((uint)face).Fullbright == true)
8188 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8941 {
8942 fullbright = ScriptBaseClass.TRUE;
8943 }
8944 else
8945 {
8946 fullbright = ScriptBaseClass.FALSE;
8947 }
8948 res.Add(new LSL_Integer(fullbright));
8189 } 8949 }
8190 } 8950 }
8191 else 8951 else
8192 { 8952 {
8193 if (face >= 0 && face < GetNumberOfSides(part)) 8953 if (tex.GetFace((uint)face).Fullbright == true)
8194 { 8954 {
8195 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8955 fullbright = ScriptBaseClass.TRUE;
8196 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8956 }
8957 else
8958 {
8959 fullbright = ScriptBaseClass.FALSE;
8197 } 8960 }
8961 res.Add(new LSL_Integer(fullbright));
8198 } 8962 }
8199 break; 8963 break;
8200 8964
@@ -8216,27 +8980,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8216 break; 8980 break;
8217 8981
8218 case (int)ScriptBaseClass.PRIM_TEXGEN: 8982 case (int)ScriptBaseClass.PRIM_TEXGEN:
8983 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8219 if (remain < 1) 8984 if (remain < 1)
8220 return null; 8985 return null;
8221 8986
8222 face=(int)rules.GetLSLIntegerItem(idx++); 8987 face = (int)rules.GetLSLIntegerItem(idx++);
8223 8988
8224 tex = part.Shape.Textures; 8989 tex = part.Shape.Textures;
8225 if (face == ScriptBaseClass.ALL_SIDES) 8990 if (face == ScriptBaseClass.ALL_SIDES)
8226 { 8991 {
8227 for (face = 0; face < GetNumberOfSides(part); face++) 8992 for (face = 0; face < GetNumberOfSides(part); face++)
8228 { 8993 {
8229 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8994 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8230 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8995 {
8231 res.Add(new LSL_Integer((uint)texgen >> 1)); 8996 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8997 }
8998 else
8999 {
9000 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9001 }
8232 } 9002 }
8233 } 9003 }
8234 else 9004 else
8235 { 9005 {
8236 if (face >= 0 && face < GetNumberOfSides(part)) 9006 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9007 {
9008 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9009 }
9010 else
8237 { 9011 {
8238 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9012 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8239 res.Add(new LSL_Integer((uint)texgen >> 1));
8240 } 9013 }
8241 } 9014 }
8242 break; 9015 break;
@@ -8260,24 +9033,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8260 if (remain < 1) 9033 if (remain < 1)
8261 return null; 9034 return null;
8262 9035
8263 face=(int)rules.GetLSLIntegerItem(idx++); 9036 face = (int)rules.GetLSLIntegerItem(idx++);
8264 9037
8265 tex = part.Shape.Textures; 9038 tex = part.Shape.Textures;
9039 float primglow;
8266 if (face == ScriptBaseClass.ALL_SIDES) 9040 if (face == ScriptBaseClass.ALL_SIDES)
8267 { 9041 {
8268 for (face = 0; face < GetNumberOfSides(part); face++) 9042 for (face = 0; face < GetNumberOfSides(part); face++)
8269 { 9043 {
8270 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9044 primglow = tex.GetFace((uint)face).Glow;
8271 res.Add(new LSL_Float(texface.Glow)); 9045 res.Add(new LSL_Float(primglow));
8272 } 9046 }
8273 } 9047 }
8274 else 9048 else
8275 { 9049 {
8276 if (face >= 0 && face < GetNumberOfSides(part)) 9050 primglow = tex.GetFace((uint)face).Glow;
8277 { 9051 res.Add(new LSL_Float(primglow));
8278 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8279 res.Add(new LSL_Float(texface.Glow));
8280 }
8281 } 9052 }
8282 break; 9053 break;
8283 9054
@@ -8289,15 +9060,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8289 textColor.B)); 9060 textColor.B));
8290 res.Add(new LSL_Float(textColor.A)); 9061 res.Add(new LSL_Float(textColor.A));
8291 break; 9062 break;
9063
8292 case (int)ScriptBaseClass.PRIM_NAME: 9064 case (int)ScriptBaseClass.PRIM_NAME:
8293 res.Add(new LSL_String(part.Name)); 9065 res.Add(new LSL_String(part.Name));
8294 break; 9066 break;
9067
8295 case (int)ScriptBaseClass.PRIM_DESC: 9068 case (int)ScriptBaseClass.PRIM_DESC:
8296 res.Add(new LSL_String(part.Description)); 9069 res.Add(new LSL_String(part.Description));
8297 break; 9070 break;
9071
8298 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9072 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8299 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9073 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8300 break; 9074 break;
9075
8301 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9076 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8302 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9077 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8303 break; 9078 break;
@@ -8908,8 +9683,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8908 // The function returns an ordered list 9683 // The function returns an ordered list
8909 // representing the tokens found in the supplied 9684 // representing the tokens found in the supplied
8910 // sources string. If two successive tokenizers 9685 // sources string. If two successive tokenizers
8911 // are encountered, then a NULL entry is added 9686 // are encountered, then a null-string entry is
8912 // to the list. 9687 // added to the list.
8913 // 9688 //
8914 // It is a precondition that the source and 9689 // It is a precondition that the source and
8915 // toekizer lisst are non-null. If they are null, 9690 // toekizer lisst are non-null. If they are null,
@@ -8917,7 +9692,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8917 // while their lengths are being determined. 9692 // while their lengths are being determined.
8918 // 9693 //
8919 // A small amount of working memoryis required 9694 // A small amount of working memoryis required
8920 // of approximately 8*#tokenizers. 9695 // of approximately 8*#tokenizers + 8*srcstrlen.
8921 // 9696 //
8922 // There are many ways in which this function 9697 // There are many ways in which this function
8923 // can be implemented, this implementation is 9698 // can be implemented, this implementation is
@@ -8933,155 +9708,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8933 // and eliminates redundant tokenizers as soon 9708 // and eliminates redundant tokenizers as soon
8934 // as is possible. 9709 // as is possible.
8935 // 9710 //
8936 // The implementation tries to avoid any copying 9711 // The implementation tries to minimize temporary
8937 // of arrays or other objects. 9712 // garbage generation.
8938 // </remarks> 9713 // </remarks>
8939 9714
8940 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9715 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8941 { 9716 {
8942 int beginning = 0; 9717 return ParseString2List(src, separators, spacers, true);
8943 int srclen = src.Length; 9718 }
8944 int seplen = separators.Length;
8945 object[] separray = separators.Data;
8946 int spclen = spacers.Length;
8947 object[] spcarray = spacers.Data;
8948 int mlen = seplen+spclen;
8949
8950 int[] offset = new int[mlen+1];
8951 bool[] active = new bool[mlen];
8952
8953 int best;
8954 int j;
8955
8956 // Initial capacity reduces resize cost
8957 9719
8958 LSL_List tokens = new LSL_List(); 9720 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9721 {
9722 int srclen = src.Length;
9723 int seplen = separators.Length;
9724 object[] separray = separators.Data;
9725 int spclen = spacers.Length;
9726 object[] spcarray = spacers.Data;
9727 int dellen = 0;
9728 string[] delarray = new string[seplen+spclen];
8959 9729
8960 // All entries are initially valid 9730 int outlen = 0;
9731 string[] outarray = new string[srclen*2+1];
8961 9732
8962 for (int i = 0; i < mlen; i++) 9733 int i, j;
8963 active[i] = true; 9734 string d;
8964 9735
8965 offset[mlen] = srclen; 9736 m_host.AddScriptLPS(1);
8966 9737
8967 while (beginning < srclen) 9738 /*
9739 * Convert separator and spacer lists to C# strings.
9740 * Also filter out null strings so we don't hang.
9741 */
9742 for (i = 0; i < seplen; i ++)
8968 { 9743 {
9744 d = separray[i].ToString();
9745 if (d.Length > 0)
9746 {
9747 delarray[dellen++] = d;
9748 }
9749 }
9750 seplen = dellen;
8969 9751
8970 best = mlen; // as bad as it gets 9752 for (i = 0; i < spclen; i ++)
9753 {
9754 d = spcarray[i].ToString();
9755 if (d.Length > 0)
9756 {
9757 delarray[dellen++] = d;
9758 }
9759 }
8971 9760
8972 // Scan for separators 9761 /*
9762 * Scan through source string from beginning to end.
9763 */
9764 for (i = 0;;)
9765 {
8973 9766
8974 for (j = 0; j < seplen; j++) 9767 /*
9768 * Find earliest delimeter in src starting at i (if any).
9769 */
9770 int earliestDel = -1;
9771 int earliestSrc = srclen;
9772 string earliestStr = null;
9773 for (j = 0; j < dellen; j ++)
8975 { 9774 {
8976 if (separray[j].ToString() == String.Empty) 9775 d = delarray[j];
8977 active[j] = false; 9776 if (d != null)
8978
8979 if (active[j])
8980 { 9777 {
8981 // scan all of the markers 9778 int index = src.IndexOf(d, i);
8982 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9779 if (index < 0)
8983 { 9780 {
8984 // not present at all 9781 delarray[j] = null; // delim nowhere in src, don't check it anymore
8985 active[j] = false;
8986 } 9782 }
8987 else 9783 else if (index < earliestSrc)
8988 { 9784 {
8989 // present and correct 9785 earliestSrc = index; // where delimeter starts in source string
8990 if (offset[j] < offset[best]) 9786 earliestDel = j; // where delimeter is in delarray[]
8991 { 9787 earliestStr = d; // the delimeter string from delarray[]
8992 // closest so far 9788 if (index == i) break; // can't do any better than found at beg of string
8993 best = j;
8994 if (offset[best] == beginning)
8995 break;
8996 }
8997 } 9789 }
8998 } 9790 }
8999 } 9791 }
9000 9792
9001 // Scan for spacers 9793 /*
9002 9794 * Output source string starting at i through start of earliest delimeter.
9003 if (offset[best] != beginning) 9795 */
9796 if (keepNulls || (earliestSrc > i))
9004 { 9797 {
9005 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9798 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9006 {
9007 if (spcarray[j-seplen].ToString() == String.Empty)
9008 active[j] = false;
9009
9010 if (active[j])
9011 {
9012 // scan all of the markers
9013 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9014 {
9015 // not present at all
9016 active[j] = false;
9017 }
9018 else
9019 {
9020 // present and correct
9021 if (offset[j] < offset[best])
9022 {
9023 // closest so far
9024 best = j;
9025 }
9026 }
9027 }
9028 }
9029 } 9799 }
9030 9800
9031 // This is the normal exit from the scanning loop 9801 /*
9802 * If no delimeter found at or after i, we're done scanning.
9803 */
9804 if (earliestDel < 0) break;
9032 9805
9033 if (best == mlen) 9806 /*
9807 * If delimeter was a spacer, output the spacer.
9808 */
9809 if (earliestDel >= seplen)
9034 { 9810 {
9035 // no markers were found on this pass 9811 outarray[outlen++] = earliestStr;
9036 // so we're pretty much done
9037 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9038 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9039 break;
9040 } 9812 }
9041 9813
9042 // Otherwise we just add the newly delimited token 9814 /*
9043 // and recalculate where the search should continue. 9815 * Look at rest of src string following delimeter.
9044 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9816 */
9045 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9817 i = earliestSrc + earliestStr.Length;
9046
9047 if (best < seplen)
9048 {
9049 beginning = offset[best] + (separray[best].ToString()).Length;
9050 }
9051 else
9052 {
9053 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9054 string str = spcarray[best - seplen].ToString();
9055 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9056 tokens.Add(new LSL_String(str));
9057 }
9058 } 9818 }
9059 9819
9060 // This an awkward an not very intuitive boundary case. If the 9820 /*
9061 // last substring is a tokenizer, then there is an implied trailing 9821 * Make up an exact-sized output array suitable for an LSL_List object.
9062 // null list entry. Hopefully the single comparison will not be too 9822 */
9063 // arduous. Alternatively the 'break' could be replced with a return 9823 object[] outlist = new object[outlen];
9064 // but that's shabby programming. 9824 for (i = 0; i < outlen; i ++)
9065
9066 if ((beginning == srclen) && (keepNulls))
9067 { 9825 {
9068 if (srclen != 0) 9826 outlist[i] = new LSL_String(outarray[i]);
9069 tokens.Add(new LSL_String(""));
9070 } 9827 }
9071 9828 return new LSL_List(outlist);
9072 return tokens;
9073 }
9074
9075 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9076 {
9077 m_host.AddScriptLPS(1);
9078 return this.ParseString(src, separators, spacers, false);
9079 }
9080
9081 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9082 {
9083 m_host.AddScriptLPS(1);
9084 return this.ParseString(src, separators, spacers, true);
9085 } 9829 }
9086 9830
9087 public LSL_Integer llGetObjectPermMask(int mask) 9831 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9176,6 +9920,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9176 case 4: 9920 case 4:
9177 return (int)item.NextPermissions; 9921 return (int)item.NextPermissions;
9178 } 9922 }
9923 m_host.TaskInventory.LockItemsForRead(false);
9179 9924
9180 return -1; 9925 return -1;
9181 } 9926 }
@@ -9366,9 +10111,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9366 { 10111 {
9367 try 10112 try
9368 { 10113 {
10114 /*
9369 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10115 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9370 if (obj != null) 10116 if (obj != null)
9371 return (double)obj.GetMass(); 10117 return (double)obj.GetMass();
10118 */
10119 // return total object mass
10120 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10121 if (obj != null)
10122 return obj.GetMass();
10123
9372 // the object is null so the key is for an avatar 10124 // the object is null so the key is for an avatar
9373 ScenePresence avatar = World.GetScenePresence(key); 10125 ScenePresence avatar = World.GetScenePresence(key);
9374 if (avatar != null) 10126 if (avatar != null)
@@ -9388,7 +10140,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9388 } 10140 }
9389 10141
9390 /// <summary> 10142 /// <summary>
9391 /// illListReplaceList removes the sub-list defined by the inclusive indices 10143 /// llListReplaceList removes the sub-list defined by the inclusive indices
9392 /// start and end and inserts the src list in its place. The inclusive 10144 /// start and end and inserts the src list in its place. The inclusive
9393 /// nature of the indices means that at least one element must be deleted 10145 /// nature of the indices means that at least one element must be deleted
9394 /// if the indices are within the bounds of the existing list. I.e. 2,2 10146 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9445,16 +10197,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9445 // based upon end. Note that if end exceeds the upper 10197 // based upon end. Note that if end exceeds the upper
9446 // bound in this case, the entire destination list 10198 // bound in this case, the entire destination list
9447 // is removed. 10199 // is removed.
9448 else 10200 else if (start == 0)
9449 { 10201 {
9450 if (end + 1 < dest.Length) 10202 if (end + 1 < dest.Length)
9451 {
9452 return src + dest.GetSublist(end + 1, -1); 10203 return src + dest.GetSublist(end + 1, -1);
9453 }
9454 else 10204 else
9455 {
9456 return src; 10205 return src;
9457 } 10206 }
10207 else // Start < 0
10208 {
10209 if (end + 1 < dest.Length)
10210 return dest.GetSublist(end + 1, -1);
10211 else
10212 return new LSL_List();
9458 } 10213 }
9459 } 10214 }
9460 // Finally, if start > end, we strip away a prefix and 10215 // Finally, if start > end, we strip away a prefix and
@@ -9505,17 +10260,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9505 int width = 0; 10260 int width = 0;
9506 int height = 0; 10261 int height = 0;
9507 10262
9508 ParcelMediaCommandEnum? commandToSend = null; 10263 uint commandToSend = 0;
9509 float time = 0.0f; // default is from start 10264 float time = 0.0f; // default is from start
9510 10265
9511 ScenePresence presence = null; 10266 ScenePresence presence = null;
9512 10267
9513 for (int i = 0; i < commandList.Data.Length; i++) 10268 for (int i = 0; i < commandList.Data.Length; i++)
9514 { 10269 {
9515 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10270 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9516 switch (command) 10271 switch (command)
9517 { 10272 {
9518 case ParcelMediaCommandEnum.Agent: 10273 case (uint)ParcelMediaCommandEnum.Agent:
9519 // we send only to one agent 10274 // we send only to one agent
9520 if ((i + 1) < commandList.Length) 10275 if ((i + 1) < commandList.Length)
9521 { 10276 {
@@ -9532,25 +10287,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9532 } 10287 }
9533 break; 10288 break;
9534 10289
9535 case ParcelMediaCommandEnum.Loop: 10290 case (uint)ParcelMediaCommandEnum.Loop:
9536 loop = 1; 10291 loop = 1;
9537 commandToSend = command; 10292 commandToSend = command;
9538 update = true; //need to send the media update packet to set looping 10293 update = true; //need to send the media update packet to set looping
9539 break; 10294 break;
9540 10295
9541 case ParcelMediaCommandEnum.Play: 10296 case (uint)ParcelMediaCommandEnum.Play:
9542 loop = 0; 10297 loop = 0;
9543 commandToSend = command; 10298 commandToSend = command;
9544 update = true; //need to send the media update packet to make sure it doesn't loop 10299 update = true; //need to send the media update packet to make sure it doesn't loop
9545 break; 10300 break;
9546 10301
9547 case ParcelMediaCommandEnum.Pause: 10302 case (uint)ParcelMediaCommandEnum.Pause:
9548 case ParcelMediaCommandEnum.Stop: 10303 case (uint)ParcelMediaCommandEnum.Stop:
9549 case ParcelMediaCommandEnum.Unload: 10304 case (uint)ParcelMediaCommandEnum.Unload:
9550 commandToSend = command; 10305 commandToSend = command;
9551 break; 10306 break;
9552 10307
9553 case ParcelMediaCommandEnum.Url: 10308 case (uint)ParcelMediaCommandEnum.Url:
9554 if ((i + 1) < commandList.Length) 10309 if ((i + 1) < commandList.Length)
9555 { 10310 {
9556 if (commandList.Data[i + 1] is LSL_String) 10311 if (commandList.Data[i + 1] is LSL_String)
@@ -9563,7 +10318,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9563 } 10318 }
9564 break; 10319 break;
9565 10320
9566 case ParcelMediaCommandEnum.Texture: 10321 case (uint)ParcelMediaCommandEnum.Texture:
9567 if ((i + 1) < commandList.Length) 10322 if ((i + 1) < commandList.Length)
9568 { 10323 {
9569 if (commandList.Data[i + 1] is LSL_String) 10324 if (commandList.Data[i + 1] is LSL_String)
@@ -9576,7 +10331,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9576 } 10331 }
9577 break; 10332 break;
9578 10333
9579 case ParcelMediaCommandEnum.Time: 10334 case (uint)ParcelMediaCommandEnum.Time:
9580 if ((i + 1) < commandList.Length) 10335 if ((i + 1) < commandList.Length)
9581 { 10336 {
9582 if (commandList.Data[i + 1] is LSL_Float) 10337 if (commandList.Data[i + 1] is LSL_Float)
@@ -9588,7 +10343,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9588 } 10343 }
9589 break; 10344 break;
9590 10345
9591 case ParcelMediaCommandEnum.AutoAlign: 10346 case (uint)ParcelMediaCommandEnum.AutoAlign:
9592 if ((i + 1) < commandList.Length) 10347 if ((i + 1) < commandList.Length)
9593 { 10348 {
9594 if (commandList.Data[i + 1] is LSL_Integer) 10349 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9602,7 +10357,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9602 } 10357 }
9603 break; 10358 break;
9604 10359
9605 case ParcelMediaCommandEnum.Type: 10360 case (uint)ParcelMediaCommandEnum.Type:
9606 if ((i + 1) < commandList.Length) 10361 if ((i + 1) < commandList.Length)
9607 { 10362 {
9608 if (commandList.Data[i + 1] is LSL_String) 10363 if (commandList.Data[i + 1] is LSL_String)
@@ -9615,7 +10370,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9615 } 10370 }
9616 break; 10371 break;
9617 10372
9618 case ParcelMediaCommandEnum.Desc: 10373 case (uint)ParcelMediaCommandEnum.Desc:
9619 if ((i + 1) < commandList.Length) 10374 if ((i + 1) < commandList.Length)
9620 { 10375 {
9621 if (commandList.Data[i + 1] is LSL_String) 10376 if (commandList.Data[i + 1] is LSL_String)
@@ -9628,7 +10383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9628 } 10383 }
9629 break; 10384 break;
9630 10385
9631 case ParcelMediaCommandEnum.Size: 10386 case (uint)ParcelMediaCommandEnum.Size:
9632 if ((i + 2) < commandList.Length) 10387 if ((i + 2) < commandList.Length)
9633 { 10388 {
9634 if (commandList.Data[i + 1] is LSL_Integer) 10389 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9698,7 +10453,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9698 } 10453 }
9699 } 10454 }
9700 10455
9701 if (commandToSend != null) 10456 if (commandToSend != 0)
9702 { 10457 {
9703 // the commandList contained a start/stop/... command, too 10458 // the commandList contained a start/stop/... command, too
9704 if (presence == null) 10459 if (presence == null)
@@ -9735,7 +10490,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9735 10490
9736 if (aList.Data[i] != null) 10491 if (aList.Data[i] != null)
9737 { 10492 {
9738 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10493 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9739 { 10494 {
9740 case ParcelMediaCommandEnum.Url: 10495 case ParcelMediaCommandEnum.Url:
9741 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10496 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9792,15 +10547,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9792 10547
9793 if (quick_pay_buttons.Data.Length < 4) 10548 if (quick_pay_buttons.Data.Length < 4)
9794 { 10549 {
9795 LSLError("List must have at least 4 elements"); 10550 int x;
9796 return; 10551 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10552 {
10553 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10554 }
9797 } 10555 }
9798 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10556 int[] nPrice = new int[5];
9799 10557 nPrice[0] = price;
9800 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10558 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9801 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10559 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9802 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10560 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9803 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10561 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10562 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9804 m_host.ParentGroup.HasGroupChanged = true; 10563 m_host.ParentGroup.HasGroupChanged = true;
9805 } 10564 }
9806 10565
@@ -9817,7 +10576,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9817 return new LSL_Vector(); 10576 return new LSL_Vector();
9818 } 10577 }
9819 10578
9820 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10579// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10580 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9821 if (presence != null) 10581 if (presence != null)
9822 { 10582 {
9823 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10583 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9839,7 +10599,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9839 return new LSL_Rotation(); 10599 return new LSL_Rotation();
9840 } 10600 }
9841 10601
9842 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10602// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10603 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9843 if (presence != null) 10604 if (presence != null)
9844 { 10605 {
9845 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10606 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9899,14 +10660,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9899 { 10660 {
9900 m_host.AddScriptLPS(1); 10661 m_host.AddScriptLPS(1);
9901 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10662 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9902 if (detectedParams == null) return; // only works on the first detected avatar 10663 if (detectedParams == null)
9903 10664 {
10665 if (m_host.ParentGroup.IsAttachment == true)
10666 {
10667 detectedParams = new DetectParams();
10668 detectedParams.Key = m_host.OwnerID;
10669 }
10670 else
10671 {
10672 return;
10673 }
10674 }
10675
9904 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10676 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9905 if (avatar != null) 10677 if (avatar != null)
9906 { 10678 {
9907 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10679 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9908 simname, pos, lookAt); 10680 simname, pos, lookAt);
9909 } 10681 }
10682
9910 ScriptSleep(1000); 10683 ScriptSleep(1000);
9911 } 10684 }
9912 10685
@@ -10030,12 +10803,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10030 10803
10031 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10804 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10032 object[] data = rules.Data; 10805 object[] data = rules.Data;
10033 for (int i = 0; i < data.Length; ++i) { 10806 for (int i = 0; i < data.Length; ++i)
10807 {
10034 int type = Convert.ToInt32(data[i++].ToString()); 10808 int type = Convert.ToInt32(data[i++].ToString());
10035 if (i >= data.Length) break; // odd number of entries => ignore the last 10809 if (i >= data.Length) break; // odd number of entries => ignore the last
10036 10810
10037 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10811 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10038 switch (type) { 10812 switch (type)
10813 {
10039 case ScriptBaseClass.CAMERA_FOCUS: 10814 case ScriptBaseClass.CAMERA_FOCUS:
10040 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10815 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10041 case ScriptBaseClass.CAMERA_POSITION: 10816 case ScriptBaseClass.CAMERA_POSITION:
@@ -10140,19 +10915,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10140 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10915 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10141 { 10916 {
10142 m_host.AddScriptLPS(1); 10917 m_host.AddScriptLPS(1);
10143 string ret = String.Empty; 10918
10144 string src1 = llBase64ToString(str1); 10919 if (str1 == String.Empty)
10145 string src2 = llBase64ToString(str2); 10920 return String.Empty;
10146 int c = 0; 10921 if (str2 == String.Empty)
10147 for (int i = 0; i < src1.Length; i++) 10922 return str1;
10923
10924 int len = str2.Length;
10925 if ((len % 4) != 0) // LL is EVIL!!!!
10148 { 10926 {
10149 ret += (char) (src1[i] ^ src2[c]); 10927 while (str2.EndsWith("="))
10928 str2 = str2.Substring(0, str2.Length - 1);
10929
10930 len = str2.Length;
10931 int mod = len % 4;
10150 10932
10151 c++; 10933 if (mod == 1)
10152 if (c >= src2.Length) 10934 str2 = str2.Substring(0, str2.Length - 1);
10153 c = 0; 10935 else if (mod == 2)
10936 str2 += "==";
10937 else if (mod == 3)
10938 str2 += "=";
10154 } 10939 }
10155 return llStringToBase64(ret); 10940
10941 byte[] data1;
10942 byte[] data2;
10943 try
10944 {
10945 data1 = Convert.FromBase64String(str1);
10946 data2 = Convert.FromBase64String(str2);
10947 }
10948 catch (Exception)
10949 {
10950 return new LSL_String(String.Empty);
10951 }
10952
10953 byte[] d2 = new Byte[data1.Length];
10954 int pos = 0;
10955
10956 if (data1.Length <= data2.Length)
10957 {
10958 Array.Copy(data2, 0, d2, 0, data1.Length);
10959 }
10960 else
10961 {
10962 while (pos < data1.Length)
10963 {
10964 len = data1.Length - pos;
10965 if (len > data2.Length)
10966 len = data2.Length;
10967
10968 Array.Copy(data2, 0, d2, pos, len);
10969 pos += len;
10970 }
10971 }
10972
10973 for (pos = 0 ; pos < data1.Length ; pos++ )
10974 data1[pos] ^= d2[pos];
10975
10976 return Convert.ToBase64String(data1);
10156 } 10977 }
10157 10978
10158 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10979 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10205,16 +11026,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10205 if (userAgent != null) 11026 if (userAgent != null)
10206 httpHeaders["User-Agent"] = userAgent; 11027 httpHeaders["User-Agent"] = userAgent;
10207 11028
11029 // See if the URL contains any header hacks
11030 string[] urlParts = url.Split(new char[] {'\n'});
11031 if (urlParts.Length > 1)
11032 {
11033 // Iterate the passed headers and parse them
11034 for (int i = 1 ; i < urlParts.Length ; i++ )
11035 {
11036 // The rest of those would be added to the body in SL.
11037 // Let's not do that.
11038 if (urlParts[i] == String.Empty)
11039 break;
11040
11041 // See if this could be a valid header
11042 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11043 if (headerParts.Length != 2)
11044 continue;
11045
11046 string headerName = headerParts[0].Trim();
11047 string headerValue = headerParts[1].Trim();
11048
11049 // Filter out headers that could be used to abuse
11050 // another system or cloak the request
11051 if (headerName.ToLower() == "x-secondlife-shard" ||
11052 headerName.ToLower() == "x-secondlife-object-name" ||
11053 headerName.ToLower() == "x-secondlife-object-key" ||
11054 headerName.ToLower() == "x-secondlife-region" ||
11055 headerName.ToLower() == "x-secondlife-local-position" ||
11056 headerName.ToLower() == "x-secondlife-local-velocity" ||
11057 headerName.ToLower() == "x-secondlife-local-rotation" ||
11058 headerName.ToLower() == "x-secondlife-owner-name" ||
11059 headerName.ToLower() == "x-secondlife-owner-key" ||
11060 headerName.ToLower() == "connection" ||
11061 headerName.ToLower() == "content-length" ||
11062 headerName.ToLower() == "from" ||
11063 headerName.ToLower() == "host" ||
11064 headerName.ToLower() == "proxy-authorization" ||
11065 headerName.ToLower() == "referer" ||
11066 headerName.ToLower() == "trailer" ||
11067 headerName.ToLower() == "transfer-encoding" ||
11068 headerName.ToLower() == "via" ||
11069 headerName.ToLower() == "authorization")
11070 continue;
11071
11072 httpHeaders[headerName] = headerValue;
11073 }
11074
11075 // Finally, strip any protocol specifier from the URL
11076 url = urlParts[0].Trim();
11077 int idx = url.IndexOf(" HTTP/");
11078 if (idx != -1)
11079 url = url.Substring(0, idx);
11080 }
11081
10208 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11082 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10209 Regex r = new Regex(authregex); 11083 Regex r = new Regex(authregex);
10210 int[] gnums = r.GetGroupNumbers(); 11084 int[] gnums = r.GetGroupNumbers();
10211 Match m = r.Match(url); 11085 Match m = r.Match(url);
10212 if (m.Success) { 11086 if (m.Success)
10213 for (int i = 1; i < gnums.Length; i++) { 11087 {
11088 for (int i = 1; i < gnums.Length; i++)
11089 {
10214 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11090 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10215 //CaptureCollection cc = g.Captures; 11091 //CaptureCollection cc = g.Captures;
10216 } 11092 }
10217 if (m.Groups.Count == 5) { 11093 if (m.Groups.Count == 5)
11094 {
10218 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11095 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10219 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11096 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10220 } 11097 }
@@ -10417,6 +11294,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10417 11294
10418 LSL_List ret = new LSL_List(); 11295 LSL_List ret = new LSL_List();
10419 UUID key = new UUID(); 11296 UUID key = new UUID();
11297
11298
10420 if (UUID.TryParse(id, out key)) 11299 if (UUID.TryParse(id, out key))
10421 { 11300 {
10422 ScenePresence av = World.GetScenePresence(key); 11301 ScenePresence av = World.GetScenePresence(key);
@@ -10434,13 +11313,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10434 ret.Add(new LSL_String("")); 11313 ret.Add(new LSL_String(""));
10435 break; 11314 break;
10436 case ScriptBaseClass.OBJECT_POS: 11315 case ScriptBaseClass.OBJECT_POS:
10437 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11316 Vector3 avpos;
11317
11318 if (av.ParentID != 0 && av.ParentPart != null)
11319 {
11320 avpos = av.OffsetPosition;
11321
11322 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11323 avpos -= sitOffset;
11324
11325 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11326 }
11327 else
11328 avpos = av.AbsolutePosition;
11329
11330 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10438 break; 11331 break;
10439 case ScriptBaseClass.OBJECT_ROT: 11332 case ScriptBaseClass.OBJECT_ROT:
10440 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11333 Quaternion avrot = av.Rotation;
11334 if (av.ParentID != 0 && av.ParentPart != null)
11335 {
11336 avrot = av.ParentPart.GetWorldRotation() * avrot;
11337 }
11338 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10441 break; 11339 break;
10442 case ScriptBaseClass.OBJECT_VELOCITY: 11340 case ScriptBaseClass.OBJECT_VELOCITY:
10443 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11341 Vector3 avvel = av.Velocity;
11342 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10444 break; 11343 break;
10445 case ScriptBaseClass.OBJECT_OWNER: 11344 case ScriptBaseClass.OBJECT_OWNER:
10446 ret.Add(new LSL_String(id)); 11345 ret.Add(new LSL_String(id));
@@ -10496,11 +11395,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10496 case ScriptBaseClass.OBJECT_NAME: 11395 case ScriptBaseClass.OBJECT_NAME:
10497 ret.Add(new LSL_String(obj.Name)); 11396 ret.Add(new LSL_String(obj.Name));
10498 break; 11397 break;
10499 case ScriptBaseClass.OBJECT_DESC: 11398 case ScriptBaseClass.OBJECT_DESC:
10500 ret.Add(new LSL_String(obj.Description)); 11399 ret.Add(new LSL_String(obj.Description));
10501 break; 11400 break;
10502 case ScriptBaseClass.OBJECT_POS: 11401 case ScriptBaseClass.OBJECT_POS:
10503 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11402 Vector3 opos = obj.AbsolutePosition;
11403 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10504 break; 11404 break;
10505 case ScriptBaseClass.OBJECT_ROT: 11405 case ScriptBaseClass.OBJECT_ROT:
10506 { 11406 {
@@ -10550,9 +11450,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10550 // The value returned in SL for normal prims is prim count 11450 // The value returned in SL for normal prims is prim count
10551 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11451 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10552 break; 11452 break;
10553 // The following 3 costs I have intentionaly coded to return zero. They are part of 11453
10554 // "Land Impact" calculations. These calculations are probably not applicable 11454 // costs below may need to be diferent for root parts, need to check
10555 // to OpenSim and are not yet complete in SL
10556 case ScriptBaseClass.OBJECT_SERVER_COST: 11455 case ScriptBaseClass.OBJECT_SERVER_COST:
10557 // The linden calculation is here 11456 // The linden calculation is here
10558 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11457 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10560,16 +11459,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10560 ret.Add(new LSL_Float(0)); 11459 ret.Add(new LSL_Float(0));
10561 break; 11460 break;
10562 case ScriptBaseClass.OBJECT_STREAMING_COST: 11461 case ScriptBaseClass.OBJECT_STREAMING_COST:
10563 // The linden calculation is here 11462 // The value returned in SL for normal prims is prim count * 0.06
10564 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11463 ret.Add(new LSL_Float(obj.StreamingCost));
10565 // The value returned in SL for normal prims looks like the prim count * 0.06
10566 ret.Add(new LSL_Float(0));
10567 break; 11464 break;
10568 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11465 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10569 // The linden calculation is here 11466 // The value returned in SL for normal prims is prim count
10570 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11467 ret.Add(new LSL_Float(obj.PhysicsCost));
10571 // The value returned in SL for normal prims looks like the prim count
10572 ret.Add(new LSL_Float(0));
10573 break; 11468 break;
10574 default: 11469 default:
10575 // Invalid or unhandled constant. 11470 // Invalid or unhandled constant.
@@ -10780,15 +11675,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10780 return result; 11675 return result;
10781 } 11676 }
10782 11677
10783 public void print(string str) 11678 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10784 { 11679 {
10785 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11680 List<SceneObjectPart> parts = GetLinkParts(link);
10786 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11681 if (parts.Count < 1)
10787 if (ossl != null) 11682 return 0;
10788 { 11683
10789 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11684 return GetNumberOfSides(parts[0]);
10790 m_log.Info("LSL print():" + str);
10791 }
10792 } 11685 }
10793 11686
10794 private string Name2Username(string name) 11687 private string Name2Username(string name)
@@ -10833,7 +11726,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10833 11726
10834 return rq.ToString(); 11727 return rq.ToString();
10835 } 11728 }
10836 11729/*
11730 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11731 {
11732 m_SayShoutCount = 0;
11733 }
11734*/
10837 private struct Tri 11735 private struct Tri
10838 { 11736 {
10839 public Vector3 p1; 11737 public Vector3 p1;
@@ -10973,9 +11871,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10973 11871
10974 ContactResult result = new ContactResult (); 11872 ContactResult result = new ContactResult ();
10975 result.ConsumerID = group.LocalId; 11873 result.ConsumerID = group.LocalId;
10976 result.Depth = intersection.distance; 11874// result.Depth = intersection.distance;
10977 result.Normal = intersection.normal; 11875 result.Normal = intersection.normal;
10978 result.Pos = intersection.ipoint; 11876 result.Pos = intersection.ipoint;
11877 result.Depth = Vector3.Mag(rayStart - result.Pos);
10979 11878
10980 contacts.Add(result); 11879 contacts.Add(result);
10981 }); 11880 });
@@ -11108,6 +12007,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11108 12007
11109 return contacts[0]; 12008 return contacts[0];
11110 } 12009 }
12010/*
12011 // not done:
12012 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12013 {
12014 ContactResult[] contacts = null;
12015 World.ForEachSOG(delegate(SceneObjectGroup group)
12016 {
12017 if (m_host.ParentGroup == group)
12018 return;
12019
12020 if (group.IsAttachment)
12021 return;
12022
12023 if(group.RootPart.PhysActor != null)
12024 return;
12025
12026 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12027 });
12028 return contacts;
12029 }
12030*/
11111 12031
11112 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12032 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11113 { 12033 {
@@ -11149,32 +12069,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11149 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12069 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11150 12070
11151 12071
11152 if (checkTerrain) 12072 if (World.SuportsRayCastFiltered())
11153 { 12073 {
11154 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12074 if (dist == 0)
11155 if (groundContact != null) 12075 return list;
11156 results.Add((ContactResult)groundContact);
11157 }
11158 12076
11159 if (checkAgents) 12077 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11160 { 12078 if (checkTerrain)
11161 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12079 rayfilter |= RayFilterFlags.land;
11162 foreach (ContactResult r in agentHits) 12080// if (checkAgents)
11163 results.Add(r); 12081// rayfilter |= RayFilterFlags.agent;
11164 } 12082 if (checkPhysical)
12083 rayfilter |= RayFilterFlags.physical;
12084 if (checkNonPhysical)
12085 rayfilter |= RayFilterFlags.nonphysical;
12086 if (detectPhantom)
12087 rayfilter |= RayFilterFlags.LSLPhanton;
12088
12089 Vector3 direction = dir * ( 1/dist);
12090
12091 if(rayfilter == 0)
12092 {
12093 list.Add(new LSL_Integer(0));
12094 return list;
12095 }
12096
12097 // get some more contacts to sort ???
12098 int physcount = 4 * count;
12099 if (physcount > 20)
12100 physcount = 20;
12101
12102 object physresults;
12103 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12104
12105 if (physresults == null)
12106 {
12107 list.Add(new LSL_Integer(-3)); // timeout error
12108 return list;
12109 }
11165 12110
11166 if (checkPhysical || checkNonPhysical || detectPhantom) 12111 results = (List<ContactResult>)physresults;
12112
12113 // for now physics doesn't detect sitted avatars so do it outside physics
12114 if (checkAgents)
12115 {
12116 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12117 foreach (ContactResult r in agentHits)
12118 results.Add(r);
12119 }
12120
12121 // TODO: Replace this with a better solution. ObjectIntersection can only
12122 // detect nonphysical phantoms. They are detected by virtue of being
12123 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12124 // physicsl phantoms as done by the physics scene
12125 // We don't want anything else but phantoms here.
12126 if (detectPhantom)
12127 {
12128 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12129 foreach (ContactResult r in objectHits)
12130 results.Add(r);
12131 }
12132 }
12133 else
11167 { 12134 {
11168 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12135 if (checkTerrain)
11169 foreach (ContactResult r in objectHits) 12136 {
11170 results.Add(r); 12137 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12138 if (groundContact != null)
12139 results.Add((ContactResult)groundContact);
12140 }
12141
12142 if (checkAgents)
12143 {
12144 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12145 foreach (ContactResult r in agentHits)
12146 results.Add(r);
12147 }
12148
12149 if (checkPhysical || checkNonPhysical || detectPhantom)
12150 {
12151 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12152 foreach (ContactResult r in objectHits)
12153 results.Add(r);
12154 }
11171 } 12155 }
11172 12156
11173 results.Sort(delegate(ContactResult a, ContactResult b) 12157 results.Sort(delegate(ContactResult a, ContactResult b)
11174 { 12158 {
11175 return a.Depth.CompareTo(b.Depth); 12159 return a.Depth.CompareTo(b.Depth);
11176 }); 12160 });
11177 12161
11178 int values = 0; 12162 int values = 0;
11179 SceneObjectGroup thisgrp = m_host.ParentGroup; 12163 SceneObjectGroup thisgrp = m_host.ParentGroup;
11180 12164
@@ -11267,7 +12251,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11267 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12251 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11268 if (!isAccount) return 0; 12252 if (!isAccount) return 0;
11269 if (estate.HasAccess(id)) return 1; 12253 if (estate.HasAccess(id)) return 1;
11270 if (estate.IsBanned(id)) 12254 if (estate.IsBanned(id, World.GetUserFlags(id)))
11271 estate.RemoveBan(id); 12255 estate.RemoveBan(id);
11272 estate.AddEstateUser(id); 12256 estate.AddEstateUser(id);
11273 break; 12257 break;
@@ -11286,14 +12270,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11286 break; 12270 break;
11287 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12271 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11288 if (!isAccount) return 0; 12272 if (!isAccount) return 0;
11289 if (estate.IsBanned(id)) return 1; 12273 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11290 EstateBan ban = new EstateBan(); 12274 EstateBan ban = new EstateBan();
11291 ban.EstateID = estate.EstateID; 12275 ban.EstateID = estate.EstateID;
11292 ban.BannedUserID = id; 12276 ban.BannedUserID = id;
11293 estate.AddBan(ban); 12277 estate.AddBan(ban);
11294 break; 12278 break;
11295 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12279 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11296 if (!isAccount || !estate.IsBanned(id)) return 0; 12280 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11297 estate.RemoveBan(id); 12281 estate.RemoveBan(id);
11298 break; 12282 break;
11299 default: return 0; 12283 default: return 0;
@@ -11322,7 +12306,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11322 return 16384; 12306 return 16384;
11323 } 12307 }
11324 12308
11325 public LSL_Integer llGetUsedMemory() 12309 public virtual LSL_Integer llGetUsedMemory()
11326 { 12310 {
11327 m_host.AddScriptLPS(1); 12311 m_host.AddScriptLPS(1);
11328 // The value returned for LSO scripts in SL 12312 // The value returned for LSO scripts in SL
@@ -11350,22 +12334,731 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11350 public void llSetSoundQueueing(int queue) 12334 public void llSetSoundQueueing(int queue)
11351 { 12335 {
11352 m_host.AddScriptLPS(1); 12336 m_host.AddScriptLPS(1);
11353 NotImplemented("llSetSoundQueueing");
11354 } 12337 }
11355 12338
11356 public void llCollisionSprite(string impact_sprite) 12339 public void llCollisionSprite(string impact_sprite)
11357 { 12340 {
11358 m_host.AddScriptLPS(1); 12341 m_host.AddScriptLPS(1);
11359 NotImplemented("llCollisionSprite"); 12342 // Viewer 2.0 broke this and it's likely LL has no intention
12343 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11360 } 12344 }
11361 12345
11362 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12346 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11363 { 12347 {
11364 m_host.AddScriptLPS(1); 12348 m_host.AddScriptLPS(1);
11365 NotImplemented("llGodLikeRezObject"); 12349
12350 if (!World.Permissions.IsGod(m_host.OwnerID))
12351 NotImplemented("llGodLikeRezObject");
12352
12353 AssetBase rezAsset = World.AssetService.Get(inventory);
12354 if (rezAsset == null)
12355 {
12356 llSay(0, "Asset not found");
12357 return;
12358 }
12359
12360 SceneObjectGroup group = null;
12361
12362 try
12363 {
12364 string xmlData = Utils.BytesToString(rezAsset.Data);
12365 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12366 }
12367 catch
12368 {
12369 llSay(0, "Asset not found");
12370 return;
12371 }
12372
12373 if (group == null)
12374 {
12375 llSay(0, "Asset not found");
12376 return;
12377 }
12378
12379 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12380 group.RootPart.AttachOffset = group.AbsolutePosition;
12381
12382 group.ResetIDs();
12383
12384 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12385 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12386 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12387 group.ScheduleGroupForFullUpdate();
12388
12389 // objects rezzed with this method are die_at_edge by default.
12390 group.RootPart.SetDieAtEdge(true);
12391
12392 group.ResumeScripts();
12393
12394 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12395 "object_rez", new Object[] {
12396 new LSL_String(
12397 group.RootPart.UUID.ToString()) },
12398 new DetectParams[0]));
12399 }
12400
12401 public LSL_String llTransferLindenDollars(string destination, int amount)
12402 {
12403 UUID txn = UUID.Random();
12404
12405 Util.FireAndForget(delegate(object x)
12406 {
12407 int replycode = 0;
12408 string replydata = destination + "," + amount.ToString();
12409
12410 try
12411 {
12412 TaskInventoryItem item = m_item;
12413 if (item == null)
12414 {
12415 replydata = "SERVICE_ERROR";
12416 return;
12417 }
12418
12419 m_host.AddScriptLPS(1);
12420
12421 if (item.PermsGranter == UUID.Zero)
12422 {
12423 replydata = "MISSING_PERMISSION_DEBIT";
12424 return;
12425 }
12426
12427 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12428 {
12429 replydata = "MISSING_PERMISSION_DEBIT";
12430 return;
12431 }
12432
12433 UUID toID = new UUID();
12434
12435 if (!UUID.TryParse(destination, out toID))
12436 {
12437 replydata = "INVALID_AGENT";
12438 return;
12439 }
12440
12441 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12442
12443 if (money == null)
12444 {
12445 replydata = "TRANSFERS_DISABLED";
12446 return;
12447 }
12448
12449 bool result = money.ObjectGiveMoney(
12450 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12451
12452 if (result)
12453 {
12454 replycode = 1;
12455 return;
12456 }
12457
12458 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12459 }
12460 finally
12461 {
12462 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12463 "transaction_result", new Object[] {
12464 new LSL_String(txn.ToString()),
12465 new LSL_Integer(replycode),
12466 new LSL_String(replydata) },
12467 new DetectParams[0]));
12468 }
12469 });
12470
12471 return txn.ToString();
11366 } 12472 }
11367 12473
11368 #endregion 12474 #endregion
12475
12476 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12477 {
12478 SceneObjectGroup group = m_host.ParentGroup;
12479
12480 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12481 return;
12482 if (group.IsAttachment)
12483 return;
12484
12485 if (frames.Data.Length > 0) // We are getting a new motion
12486 {
12487 if (group.RootPart.KeyframeMotion != null)
12488 group.RootPart.KeyframeMotion.Delete();
12489 group.RootPart.KeyframeMotion = null;
12490
12491 int idx = 0;
12492
12493 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12494 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12495
12496 while (idx < options.Data.Length)
12497 {
12498 int option = (int)options.GetLSLIntegerItem(idx++);
12499 int remain = options.Data.Length - idx;
12500
12501 switch (option)
12502 {
12503 case ScriptBaseClass.KFM_MODE:
12504 if (remain < 1)
12505 break;
12506 int modeval = (int)options.GetLSLIntegerItem(idx++);
12507 switch(modeval)
12508 {
12509 case ScriptBaseClass.KFM_FORWARD:
12510 mode = KeyframeMotion.PlayMode.Forward;
12511 break;
12512 case ScriptBaseClass.KFM_REVERSE:
12513 mode = KeyframeMotion.PlayMode.Reverse;
12514 break;
12515 case ScriptBaseClass.KFM_LOOP:
12516 mode = KeyframeMotion.PlayMode.Loop;
12517 break;
12518 case ScriptBaseClass.KFM_PING_PONG:
12519 mode = KeyframeMotion.PlayMode.PingPong;
12520 break;
12521 }
12522 break;
12523 case ScriptBaseClass.KFM_DATA:
12524 if (remain < 1)
12525 break;
12526 int dataval = (int)options.GetLSLIntegerItem(idx++);
12527 data = (KeyframeMotion.DataFormat)dataval;
12528 break;
12529 }
12530 }
12531
12532 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12533
12534 idx = 0;
12535
12536 int elemLength = 2;
12537 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12538 elemLength = 3;
12539
12540 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12541 while (idx < frames.Data.Length)
12542 {
12543 int remain = frames.Data.Length - idx;
12544
12545 if (remain < elemLength)
12546 break;
12547
12548 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12549 frame.Position = null;
12550 frame.Rotation = null;
12551
12552 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12553 {
12554 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12555 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12556 }
12557 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12558 {
12559 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12560 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12561 }
12562
12563 float tempf = (float)frames.GetLSLFloatItem(idx++);
12564 frame.TimeMS = (int)(tempf * 1000.0f);
12565
12566 keyframes.Add(frame);
12567 }
12568
12569 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12570 group.RootPart.KeyframeMotion.Start();
12571 }
12572 else
12573 {
12574 if (group.RootPart.KeyframeMotion == null)
12575 return;
12576
12577 if (options.Data.Length == 0)
12578 {
12579 group.RootPart.KeyframeMotion.Stop();
12580 return;
12581 }
12582
12583 int code = (int)options.GetLSLIntegerItem(0);
12584
12585 int idx = 0;
12586
12587 while (idx < options.Data.Length)
12588 {
12589 int option = (int)options.GetLSLIntegerItem(idx++);
12590 int remain = options.Data.Length - idx;
12591
12592 switch (option)
12593 {
12594 case ScriptBaseClass.KFM_COMMAND:
12595 int cmd = (int)options.GetLSLIntegerItem(idx++);
12596 switch (cmd)
12597 {
12598 case ScriptBaseClass.KFM_CMD_PLAY:
12599 group.RootPart.KeyframeMotion.Start();
12600 break;
12601 case ScriptBaseClass.KFM_CMD_STOP:
12602 group.RootPart.KeyframeMotion.Stop();
12603 break;
12604 case ScriptBaseClass.KFM_CMD_PAUSE:
12605 group.RootPart.KeyframeMotion.Pause();
12606 break;
12607 }
12608 break;
12609 }
12610 }
12611 }
12612 }
12613
12614 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12615 {
12616 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12617
12618 int idx = 0;
12619 int idxStart = 0;
12620
12621 bool positionChanged = false;
12622 Vector3 finalPos = Vector3.Zero;
12623
12624 try
12625 {
12626 while (idx < rules.Length)
12627 {
12628 ++rulesParsed;
12629 int code = rules.GetLSLIntegerItem(idx++);
12630
12631 int remain = rules.Length - idx;
12632 idxStart = idx;
12633
12634 switch (code)
12635 {
12636 case (int)ScriptBaseClass.PRIM_POSITION:
12637 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12638 {
12639 if (remain < 1)
12640 return null;
12641
12642 LSL_Vector v;
12643 v = rules.GetVector3Item(idx++);
12644
12645 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12646 if (part == null)
12647 break;
12648
12649 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12650 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12651 if (part.LinkNum > 1)
12652 {
12653 localRot = GetPartLocalRot(part);
12654 localPos = GetPartLocalPos(part);
12655 }
12656
12657 v -= localPos;
12658 v /= localRot;
12659
12660 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12661
12662 v = v + 2 * sitOffset;
12663
12664 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12665 av.SendAvatarDataToAllAgents();
12666
12667 }
12668 break;
12669
12670 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12671 case (int)ScriptBaseClass.PRIM_ROTATION:
12672 {
12673 if (remain < 1)
12674 return null;
12675
12676 LSL_Rotation r;
12677 r = rules.GetQuaternionItem(idx++);
12678
12679 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12680 if (part == null)
12681 break;
12682
12683 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12684 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12685
12686 if (part.LinkNum > 1)
12687 localRot = GetPartLocalRot(part);
12688
12689 r = r * llGetRootRotation() / localRot;
12690 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12691 av.SendAvatarDataToAllAgents();
12692 }
12693 break;
12694
12695 // parse rest doing nothing but number of parameters error check
12696 case (int)ScriptBaseClass.PRIM_SIZE:
12697 case (int)ScriptBaseClass.PRIM_MATERIAL:
12698 case (int)ScriptBaseClass.PRIM_PHANTOM:
12699 case (int)ScriptBaseClass.PRIM_PHYSICS:
12700 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12701 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12702 case (int)ScriptBaseClass.PRIM_NAME:
12703 case (int)ScriptBaseClass.PRIM_DESC:
12704 if (remain < 1)
12705 return null;
12706 idx++;
12707 break;
12708
12709 case (int)ScriptBaseClass.PRIM_GLOW:
12710 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12711 case (int)ScriptBaseClass.PRIM_TEXGEN:
12712 if (remain < 2)
12713 return null;
12714 idx += 2;
12715 break;
12716
12717 case (int)ScriptBaseClass.PRIM_TYPE:
12718 if (remain < 3)
12719 return null;
12720 code = (int)rules.GetLSLIntegerItem(idx++);
12721 remain = rules.Length - idx;
12722 switch (code)
12723 {
12724 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12725 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12726 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12727 if (remain < 6)
12728 return null;
12729 idx += 6;
12730 break;
12731
12732 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12733 if (remain < 5)
12734 return null;
12735 idx += 5;
12736 break;
12737
12738 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12739 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12740 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12741 if (remain < 11)
12742 return null;
12743 idx += 11;
12744 break;
12745
12746 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12747 if (remain < 2)
12748 return null;
12749 idx += 2;
12750 break;
12751 }
12752 break;
12753
12754 case (int)ScriptBaseClass.PRIM_COLOR:
12755 case (int)ScriptBaseClass.PRIM_TEXT:
12756 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12757 case (int)ScriptBaseClass.PRIM_OMEGA:
12758 if (remain < 3)
12759 return null;
12760 idx += 3;
12761 break;
12762
12763 case (int)ScriptBaseClass.PRIM_TEXTURE:
12764 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12765 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12766 if (remain < 5)
12767 return null;
12768 idx += 5;
12769 break;
12770
12771 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12772 if (remain < 7)
12773 return null;
12774
12775 idx += 7;
12776 break;
12777
12778 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12779 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12780 return null;
12781
12782 return rules.GetSublist(idx, -1);
12783 }
12784 }
12785 }
12786 catch (InvalidCastException e)
12787 {
12788 ShoutError(string.Format(
12789 "{0} error running rule #{1}: arg #{2} ",
12790 originFunc, rulesParsed, idx - idxStart) + e.Message);
12791 }
12792 finally
12793 {
12794 if (positionChanged)
12795 {
12796 av.OffsetPosition = finalPos;
12797// av.SendAvatarDataToAllAgents();
12798 av.SendTerseUpdateToAllClients();
12799 positionChanged = false;
12800 }
12801 }
12802 return null;
12803 }
12804
12805 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12806 {
12807 // avatars case
12808 // replies as SL wiki
12809
12810// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12811 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12812
12813 int idx = 0;
12814 while (idx < rules.Length)
12815 {
12816 int code = (int)rules.GetLSLIntegerItem(idx++);
12817 int remain = rules.Length - idx;
12818
12819 switch (code)
12820 {
12821 case (int)ScriptBaseClass.PRIM_MATERIAL:
12822 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12823 break;
12824
12825 case (int)ScriptBaseClass.PRIM_PHYSICS:
12826 res.Add(new LSL_Integer(0));
12827 break;
12828
12829 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12830 res.Add(new LSL_Integer(0));
12831 break;
12832
12833 case (int)ScriptBaseClass.PRIM_PHANTOM:
12834 res.Add(new LSL_Integer(0));
12835 break;
12836
12837 case (int)ScriptBaseClass.PRIM_POSITION:
12838
12839 Vector3 pos = avatar.OffsetPosition;
12840
12841 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12842 pos -= sitOffset;
12843
12844 if( sitPart != null)
12845 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12846
12847 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12848 break;
12849
12850 case (int)ScriptBaseClass.PRIM_SIZE:
12851 // as in llGetAgentSize above
12852 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12853 break;
12854
12855 case (int)ScriptBaseClass.PRIM_ROTATION:
12856 Quaternion rot = avatar.Rotation;
12857 if (sitPart != null)
12858 {
12859 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12860 }
12861
12862 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12863 break;
12864
12865 case (int)ScriptBaseClass.PRIM_TYPE:
12866 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12867 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12868 res.Add(new LSL_Vector(0f,1.0f,0f));
12869 res.Add(new LSL_Float(0.0f));
12870 res.Add(new LSL_Vector(0, 0, 0));
12871 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12872 res.Add(new LSL_Vector(0, 0, 0));
12873 break;
12874
12875 case (int)ScriptBaseClass.PRIM_TEXTURE:
12876 if (remain < 1)
12877 return null;
12878
12879 int face = (int)rules.GetLSLIntegerItem(idx++);
12880 if (face == ScriptBaseClass.ALL_SIDES)
12881 {
12882 for (face = 0; face < 21; face++)
12883 {
12884 res.Add(new LSL_String(""));
12885 res.Add(new LSL_Vector(0,0,0));
12886 res.Add(new LSL_Vector(0,0,0));
12887 res.Add(new LSL_Float(0.0));
12888 }
12889 }
12890 else
12891 {
12892 if (face >= 0 && face < 21)
12893 {
12894 res.Add(new LSL_String(""));
12895 res.Add(new LSL_Vector(0,0,0));
12896 res.Add(new LSL_Vector(0,0,0));
12897 res.Add(new LSL_Float(0.0));
12898 }
12899 }
12900 break;
12901
12902 case (int)ScriptBaseClass.PRIM_COLOR:
12903 if (remain < 1)
12904 return null;
12905
12906 face = (int)rules.GetLSLIntegerItem(idx++);
12907
12908 if (face == ScriptBaseClass.ALL_SIDES)
12909 {
12910 for (face = 0; face < 21; face++)
12911 {
12912 res.Add(new LSL_Vector(0,0,0));
12913 res.Add(new LSL_Float(0));
12914 }
12915 }
12916 else
12917 {
12918 res.Add(new LSL_Vector(0,0,0));
12919 res.Add(new LSL_Float(0));
12920 }
12921 break;
12922
12923 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12924 if (remain < 1)
12925 return null;
12926 face = (int)rules.GetLSLIntegerItem(idx++);
12927
12928 if (face == ScriptBaseClass.ALL_SIDES)
12929 {
12930 for (face = 0; face < 21; face++)
12931 {
12932 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12933 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12934 }
12935 }
12936 else
12937 {
12938 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12939 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12940 }
12941 break;
12942
12943 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12944 if (remain < 1)
12945 return null;
12946 face = (int)rules.GetLSLIntegerItem(idx++);
12947
12948 if (face == ScriptBaseClass.ALL_SIDES)
12949 {
12950 for (face = 0; face < 21; face++)
12951 {
12952 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12953 }
12954 }
12955 else
12956 {
12957 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12958 }
12959 break;
12960
12961 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12962 res.Add(new LSL_Integer(0));
12963 res.Add(new LSL_Integer(0));// softness
12964 res.Add(new LSL_Float(0.0f)); // gravity
12965 res.Add(new LSL_Float(0.0f)); // friction
12966 res.Add(new LSL_Float(0.0f)); // wind
12967 res.Add(new LSL_Float(0.0f)); // tension
12968 res.Add(new LSL_Vector(0f,0f,0f));
12969 break;
12970
12971 case (int)ScriptBaseClass.PRIM_TEXGEN:
12972 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
12973 if (remain < 1)
12974 return null;
12975 face = (int)rules.GetLSLIntegerItem(idx++);
12976
12977 if (face == ScriptBaseClass.ALL_SIDES)
12978 {
12979 for (face = 0; face < 21; face++)
12980 {
12981 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
12982 }
12983 }
12984 else
12985 {
12986 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
12987 }
12988 break;
12989
12990 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12991 res.Add(new LSL_Integer(0));
12992 res.Add(new LSL_Vector(0f,0f,0f));
12993 res.Add(new LSL_Float(0f)); // intensity
12994 res.Add(new LSL_Float(0f)); // radius
12995 res.Add(new LSL_Float(0f)); // falloff
12996 break;
12997
12998 case (int)ScriptBaseClass.PRIM_GLOW:
12999 if (remain < 1)
13000 return null;
13001 face = (int)rules.GetLSLIntegerItem(idx++);
13002
13003 if (face == ScriptBaseClass.ALL_SIDES)
13004 {
13005 for (face = 0; face < 21; face++)
13006 {
13007 res.Add(new LSL_Float(0f));
13008 }
13009 }
13010 else
13011 {
13012 res.Add(new LSL_Float(0f));
13013 }
13014 break;
13015
13016 case (int)ScriptBaseClass.PRIM_TEXT:
13017 res.Add(new LSL_String(""));
13018 res.Add(new LSL_Vector(0f,0f,0f));
13019 res.Add(new LSL_Float(1.0f));
13020 break;
13021
13022 case (int)ScriptBaseClass.PRIM_NAME:
13023 res.Add(new LSL_String(avatar.Name));
13024 break;
13025
13026 case (int)ScriptBaseClass.PRIM_DESC:
13027 res.Add(new LSL_String(""));
13028 break;
13029
13030 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13031 Quaternion lrot = avatar.Rotation;
13032
13033 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13034 {
13035 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13036 }
13037 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13038 break;
13039
13040 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13041 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13042 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13043 lpos -= lsitOffset;
13044
13045 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13046 {
13047 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13048 }
13049 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13050 break;
13051
13052 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13053 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13054 return null;
13055
13056 return rules.GetSublist(idx, -1);
13057 }
13058 }
13059
13060 return null;
13061 }
11369 } 13062 }
11370 13063
11371 public class NotecardCache 13064 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 e245684..7aacfd4 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);
@@ -1803,6 +1812,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1803 1812
1804 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1813 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1805 { 1814 {
1815 m_host.TaskInventory.LockItemsForRead(true);
1806 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1816 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1807 { 1817 {
1808 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1818 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1810,6 +1820,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1810 assetID = item.AssetID; 1820 assetID = item.AssetID;
1811 } 1821 }
1812 } 1822 }
1823 m_host.TaskInventory.LockItemsForRead(false);
1813 } 1824 }
1814 1825
1815 if (assetID == UUID.Zero) 1826 if (assetID == UUID.Zero)
@@ -2295,7 +2306,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2295 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2306 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2296 m_host.AddScriptLPS(1); 2307 m_host.AddScriptLPS(1);
2297 2308
2298 return NpcCreate(firstname, lastname, position, notecard, false, false); 2309 return NpcCreate(firstname, lastname, position, notecard, true, false);
2299 } 2310 }
2300 2311
2301 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2312 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2306,24 +2317,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2306 return NpcCreate( 2317 return NpcCreate(
2307 firstname, lastname, position, notecard, 2318 firstname, lastname, position, notecard,
2308 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2319 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2309 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2320 false);
2321// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2310 } 2322 }
2311 2323
2312 private LSL_Key NpcCreate( 2324 private LSL_Key NpcCreate(
2313 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2325 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2314 { 2326 {
2327 if (!owned)
2328 OSSLError("Unowned NPCs are unsupported");
2329
2330 string groupTitle = String.Empty;
2331
2332 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2333 return new LSL_Key(UUID.Zero.ToString());
2334
2335 if (firstname != String.Empty || lastname != String.Empty)
2336 {
2337 if (firstname != "Shown outfit:")
2338 groupTitle = "- NPC -";
2339 }
2340
2315 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2341 INPCModule module = World.RequestModuleInterface<INPCModule>();
2316 if (module != null) 2342 if (module != null)
2317 { 2343 {
2318 AvatarAppearance appearance = null; 2344 AvatarAppearance appearance = null;
2319 2345
2320 UUID id; 2346// UUID id;
2321 if (UUID.TryParse(notecard, out id)) 2347// if (UUID.TryParse(notecard, out id))
2322 { 2348// {
2323 ScenePresence clonePresence = World.GetScenePresence(id); 2349// ScenePresence clonePresence = World.GetScenePresence(id);
2324 if (clonePresence != null) 2350// if (clonePresence != null)
2325 appearance = clonePresence.Appearance; 2351// appearance = clonePresence.Appearance;
2326 } 2352// }
2327 2353
2328 if (appearance == null) 2354 if (appearance == null)
2329 { 2355 {
@@ -2351,6 +2377,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2351 World, 2377 World,
2352 appearance); 2378 appearance);
2353 2379
2380 ScenePresence sp;
2381 if (World.TryGetScenePresence(x, out sp))
2382 {
2383 sp.Grouptitle = groupTitle;
2384 sp.SendAvatarDataToAllAgents();
2385 }
2354 return new LSL_Key(x.ToString()); 2386 return new LSL_Key(x.ToString());
2355 } 2387 }
2356 2388
@@ -2650,16 +2682,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2650 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2682 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2651 m_host.AddScriptLPS(1); 2683 m_host.AddScriptLPS(1);
2652 2684
2653 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2685 ManualResetEvent ev = new ManualResetEvent(false);
2654 if (module != null)
2655 {
2656 UUID npcId = new UUID(npc.m_string);
2657 2686
2658 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2687 Util.FireAndForget(delegate(object x) {
2659 return; 2688 try
2689 {
2690 INPCModule module = World.RequestModuleInterface<INPCModule>();
2691 if (module != null)
2692 {
2693 UUID npcId = new UUID(npc.m_string);
2660 2694
2661 module.DeleteNPC(npcId, World); 2695 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2662 } 2696 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2697 {
2698 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2699 return;
2700 }
2701
2702 module.DeleteNPC(npcId, World);
2703 }
2704 }
2705 finally
2706 {
2707 ev.Set();
2708 }
2709 });
2710 ev.WaitOne();
2663 } 2711 }
2664 2712
2665 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2713 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3373,6 +3421,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3373 if (m_UrlModule != null) 3421 if (m_UrlModule != null)
3374 m_UrlModule.HttpContentType(new UUID(id),type); 3422 m_UrlModule.HttpContentType(new UUID(id),type);
3375 } 3423 }
3376 3424 }
3377 } 3425}
3378} \ 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 06729ab..07149b6 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 cad8518..05ba222 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;
@@ -285,6 +285,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
285 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 285 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
286 public const int CHANGED_MEDIA = 2048; 286 public const int CHANGED_MEDIA = 2048;
287 public const int CHANGED_ANIMATION = 16384; 287 public const int CHANGED_ANIMATION = 16384;
288 public const int CHANGED_POSITION = 32768;
288 public const int TYPE_INVALID = 0; 289 public const int TYPE_INVALID = 0;
289 public const int TYPE_INTEGER = 1; 290 public const int TYPE_INTEGER = 1;
290 public const int TYPE_FLOAT = 2; 291 public const int TYPE_FLOAT = 2;
@@ -590,6 +591,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
590 public const int PRIM_MEDIA_PERM_OWNER = 1; 591 public const int PRIM_MEDIA_PERM_OWNER = 1;
591 public const int PRIM_MEDIA_PERM_GROUP = 2; 592 public const int PRIM_MEDIA_PERM_GROUP = 2;
592 public const int PRIM_MEDIA_PERM_ANYONE = 4; 593 public const int PRIM_MEDIA_PERM_ANYONE = 4;
594
595 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
596 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
597 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
598 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
599
600 public const int PRIM_PHYSICS_MATERIAL = 31;
601 public const int DENSITY = 1;
602 public const int FRICTION = 2;
603 public const int RESTITUTION = 4;
604 public const int GRAVITY_MULTIPLIER = 8;
593 605
594 // extra constants for llSetPrimMediaParams 606 // extra constants for llSetPrimMediaParams
595 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 607 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -662,6 +674,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
662 674
663 public static readonly LSLInteger RCERR_UNKNOWN = -1; 675 public static readonly LSLInteger RCERR_UNKNOWN = -1;
664 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 676 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
665 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 677 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
678
679 public const int KFM_MODE = 1;
680 public const int KFM_LOOP = 1;
681 public const int KFM_REVERSE = 3;
682 public const int KFM_FORWARD = 0;
683 public const int KFM_PING_PONG = 2;
684 public const int KFM_DATA = 2;
685 public const int KFM_TRANSLATION = 2;
686 public const int KFM_ROTATION = 1;
687 public const int KFM_COMMAND = 0;
688 public const int KFM_CMD_PLAY = 0;
689 public const int KFM_CMD_STOP = 1;
690 public const int KFM_CMD_PAUSE = 2;
666 } 691 }
667} 692}
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 {