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.cs3174
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs102
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs29
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs56
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs45
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs86
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs378
19 files changed, 3224 insertions, 1025 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 2bfb9b3..5386a28 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 private List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 344 private 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);
@@ -2085,18 +2316,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2085 m_host.AddScriptLPS(1); 2316 m_host.AddScriptLPS(1);
2086 2317
2087 // try to let this work as in SL... 2318 // try to let this work as in SL...
2088 if (m_host.ParentID == 0) 2319 if (m_host.LinkNum < 2)
2089 { 2320 {
2090 // special case: If we are root, rotate complete SOG to new rotation 2321 // Special case: If we are root, rotate complete SOG to new
2322 // rotation.
2323 // We are root if the link number is 0 (single prim) or 1
2324 // (root prim). ParentID may be nonzero in attachments and
2325 // using it would cause attachments and HUDs to rotate
2326 // to the wrong positions.
2327
2091 SetRot(m_host, rot); 2328 SetRot(m_host, rot);
2092 } 2329 }
2093 else 2330 else
2094 { 2331 {
2095 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2332 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2096 SceneObjectPart rootPart = m_host.ParentGroup.RootPart; 2333 SceneObjectPart rootPart;
2097 if (rootPart != null) // better safe than sorry 2334 if (m_host.ParentGroup != null) // better safe than sorry
2098 { 2335 {
2099 SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot); 2336 rootPart = m_host.ParentGroup.RootPart;
2337 if (rootPart != null)
2338 SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot);
2100 } 2339 }
2101 } 2340 }
2102 2341
@@ -2112,25 +2351,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2112 2351
2113 protected void SetRot(SceneObjectPart part, Quaternion rot) 2352 protected void SetRot(SceneObjectPart part, Quaternion rot)
2114 { 2353 {
2115 part.UpdateRotation(rot); 2354 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2116 // Update rotation does not move the object in the physics scene if it's a linkset. 2355 return;
2117 2356
2118//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2357 bool isroot = (part == part.ParentGroup.RootPart);
2119// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2358 bool isphys;
2120 2359
2121 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2122 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2123 // It's perfectly okay when the object is not an active physical body though.
2124 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2125 // but only if the object is not physial and active. This is important for rotating doors.
2126 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2127 // scene
2128 PhysicsActor pa = part.PhysActor; 2360 PhysicsActor pa = part.PhysActor;
2129 2361
2130 if (pa != null && !pa.IsPhysical) 2362 // keep using physactor ideia of isphysical
2363 // it should be SOP ideia of that
2364 // not much of a issue with ubitODE
2365 if (pa != null && pa.IsPhysical)
2366 isphys = true;
2367 else
2368 isphys = false;
2369
2370 // SL doesn't let scripts rotate root of physical linksets
2371 if (isroot && isphys)
2372 return;
2373
2374 part.UpdateRotation(rot);
2375
2376 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2377 // so do a nasty update of parts positions if is a root part rotation
2378 if (isroot && pa != null) // with if above implies non physical root part
2131 { 2379 {
2132 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2380 part.ParentGroup.ResetChildPrimPhysicsPositions();
2133 } 2381 }
2382 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2383 {
2384 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2385 if (sittingavas.Count > 0)
2386 {
2387 foreach (ScenePresence av in sittingavas)
2388 {
2389 if (isroot || part.LocalId == av.ParentID)
2390 av.SendTerseUpdateToAllClients();
2391 }
2392 }
2393 }
2134 } 2394 }
2135 2395
2136 /// <summary> 2396 /// <summary>
@@ -2178,8 +2438,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2178 2438
2179 public LSL_Rotation llGetLocalRot() 2439 public LSL_Rotation llGetLocalRot()
2180 { 2440 {
2441 return GetPartLocalRot(m_host);
2442 }
2443
2444 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2445 {
2181 m_host.AddScriptLPS(1); 2446 m_host.AddScriptLPS(1);
2182 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2447 Quaternion rot = part.RotationOffset;
2448 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2183 } 2449 }
2184 2450
2185 public void llSetForce(LSL_Vector force, int local) 2451 public void llSetForce(LSL_Vector force, int local)
@@ -2259,16 +2525,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2259 m_host.ApplyImpulse(v, local != 0); 2525 m_host.ApplyImpulse(v, local != 0);
2260 } 2526 }
2261 2527
2528
2262 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2529 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2263 { 2530 {
2264 m_host.AddScriptLPS(1); 2531 m_host.AddScriptLPS(1);
2265 m_host.ApplyAngularImpulse(force, local != 0); 2532 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2266 } 2533 }
2267 2534
2268 public void llSetTorque(LSL_Vector torque, int local) 2535 public void llSetTorque(LSL_Vector torque, int local)
2269 { 2536 {
2270 m_host.AddScriptLPS(1); 2537 m_host.AddScriptLPS(1);
2271 m_host.SetAngularImpulse(torque, local != 0); 2538 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2272 } 2539 }
2273 2540
2274 public LSL_Vector llGetTorque() 2541 public LSL_Vector llGetTorque()
@@ -2285,20 +2552,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2285 llSetTorque(torque, local); 2552 llSetTorque(torque, local);
2286 } 2553 }
2287 2554
2555 public void llSetVelocity(LSL_Vector vel, int local)
2556 {
2557 m_host.AddScriptLPS(1);
2558 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2559 }
2560
2288 public LSL_Vector llGetVel() 2561 public LSL_Vector llGetVel()
2289 { 2562 {
2290 m_host.AddScriptLPS(1); 2563 m_host.AddScriptLPS(1);
2291 2564
2292 Vector3 vel; 2565 Vector3 vel = Vector3.Zero;
2293 2566
2294 if (m_host.ParentGroup.IsAttachment) 2567 if (m_host.ParentGroup.IsAttachment)
2295 { 2568 {
2296 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2569 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2297 vel = avatar.Velocity; 2570 if (avatar != null)
2571 vel = avatar.Velocity;
2298 } 2572 }
2299 else 2573 else
2300 { 2574 {
2301 vel = m_host.Velocity; 2575 vel = m_host.ParentGroup.RootPart.Velocity;
2302 } 2576 }
2303 2577
2304 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2578 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2310,10 +2584,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2310 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2584 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2311 } 2585 }
2312 2586
2587 public void llSetAngularVelocity(LSL_Vector avel, int local)
2588 {
2589 m_host.AddScriptLPS(1);
2590 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2591 }
2592
2313 public LSL_Vector llGetOmega() 2593 public LSL_Vector llGetOmega()
2314 { 2594 {
2315 m_host.AddScriptLPS(1); 2595 m_host.AddScriptLPS(1);
2316 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2596 Vector3 avel = m_host.AngularVelocity;
2597 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2317 } 2598 }
2318 2599
2319 public LSL_Float llGetTimeOfDay() 2600 public LSL_Float llGetTimeOfDay()
@@ -2839,16 +3120,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2839 new_group.RootPart.UUID.ToString()) }, 3120 new_group.RootPart.UUID.ToString()) },
2840 new DetectParams[0])); 3121 new DetectParams[0]));
2841 3122
2842 float groupmass = new_group.GetMass(); 3123 // do recoil
3124 SceneObjectGroup hostgrp = m_host.ParentGroup;
3125 if (hostgrp == null)
3126 return;
3127
3128 if (hostgrp.IsAttachment) // don't recoil avatars
3129 return;
2843 3130
2844 PhysicsActor pa = new_group.RootPart.PhysActor; 3131 PhysicsActor pa = new_group.RootPart.PhysActor;
2845 3132
2846 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3133 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2847 { 3134 {
2848 //Recoil. 3135 float groupmass = new_group.GetMass();
2849 llApplyImpulse(vel * groupmass, 0); 3136 vel *= -groupmass;
3137 llApplyImpulse(vel, 0);
2850 } 3138 }
2851 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3139 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3140 return;
3141
2852 }); 3142 });
2853 3143
2854 //ScriptSleep((int)((groupmass * velmag) / 10)); 3144 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2863,35 +3153,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2863 public void llLookAt(LSL_Vector target, double strength, double damping) 3153 public void llLookAt(LSL_Vector target, double strength, double damping)
2864 { 3154 {
2865 m_host.AddScriptLPS(1); 3155 m_host.AddScriptLPS(1);
2866 // Determine where we are looking from
2867 LSL_Vector from = llGetPos();
2868 3156
2869 // Work out the normalised vector from the source to the target 3157 // Get the normalized vector to the target
2870 LSL_Vector delta = llVecNorm(target - from); 3158 LSL_Vector d1 = llVecNorm(target - llGetPos());
2871 LSL_Vector angle = new LSL_Vector(0,0,0);
2872 3159
2873 // Calculate the yaw 3160 // Get the bearing (yaw)
2874 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3161 LSL_Vector a1 = new LSL_Vector(0,0,0);
2875 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3162 a1.z = llAtan2(d1.y, d1.x);
2876 3163
2877 // Calculate pitch 3164 // Get the elevation (pitch)
2878 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3165 LSL_Vector a2 = new LSL_Vector(0,0,0);
3166 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2879 3167
2880 // we need to convert from a vector describing 3168 LSL_Rotation r1 = llEuler2Rot(a1);
2881 // the angles of rotation in radians into rotation value 3169 LSL_Rotation r2 = llEuler2Rot(a2);
2882 LSL_Rotation rot = llEuler2Rot(angle); 3170 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2883
2884 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2885 // set the rotation of the object, copy that behavior
2886 PhysicsActor pa = m_host.PhysActor;
2887 3171
2888 if (strength == 0 || pa == null || !pa.IsPhysical) 3172 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2889 { 3173 {
2890 llSetRot(rot); 3174 // Do nothing if either value is 0 (this has been checked in SL)
3175 if (strength <= 0.0 || damping <= 0.0)
3176 return;
3177
3178 llSetRot(r3 * r2 * r1);
2891 } 3179 }
2892 else 3180 else
2893 { 3181 {
2894 m_host.StartLookAt(rot, (float)strength, (float)damping); 3182 if (strength == 0)
3183 {
3184 llSetRot(r3 * r2 * r1);
3185 return;
3186 }
3187
3188 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2895 } 3189 }
2896 } 3190 }
2897 3191
@@ -2937,17 +3231,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2937 } 3231 }
2938 else 3232 else
2939 { 3233 {
2940 if (m_host.IsRoot) 3234 // new SL always returns object mass
2941 { 3235// if (m_host.IsRoot)
3236// {
2942 return m_host.ParentGroup.GetMass(); 3237 return m_host.ParentGroup.GetMass();
2943 } 3238// }
2944 else 3239// else
2945 { 3240// {
2946 return m_host.GetMass(); 3241// return m_host.GetMass();
2947 } 3242// }
2948 } 3243 }
2949 } 3244 }
2950 3245
3246
3247 public LSL_Float llGetMassMKS()
3248 {
3249 return 100f * llGetMass();
3250 }
3251
2951 public void llCollisionFilter(string name, string id, int accept) 3252 public void llCollisionFilter(string name, string id, int accept)
2952 { 3253 {
2953 m_host.AddScriptLPS(1); 3254 m_host.AddScriptLPS(1);
@@ -2995,8 +3296,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2995 { 3296 {
2996 // Unregister controls from Presence 3297 // Unregister controls from Presence
2997 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3298 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2998 // Remove Take Control permission.
2999 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3000 } 3299 }
3001 } 3300 }
3002 } 3301 }
@@ -3022,7 +3321,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3022 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3321 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3023 3322
3024 if (attachmentsModule != null) 3323 if (attachmentsModule != null)
3025 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3324 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3026 else 3325 else
3027 return false; 3326 return false;
3028 } 3327 }
@@ -3052,9 +3351,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3052 { 3351 {
3053 m_host.AddScriptLPS(1); 3352 m_host.AddScriptLPS(1);
3054 3353
3055// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3056// return;
3057
3058 if (m_item.PermsGranter != m_host.OwnerID) 3354 if (m_item.PermsGranter != m_host.OwnerID)
3059 return; 3355 return;
3060 3356
@@ -3097,6 +3393,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3097 3393
3098 public void llInstantMessage(string user, string message) 3394 public void llInstantMessage(string user, string message)
3099 { 3395 {
3396 UUID result;
3397 if (!UUID.TryParse(user, out result))
3398 {
3399 ShoutError("An invalid key was passed to llInstantMessage");
3400 ScriptSleep(2000);
3401 return;
3402 }
3403
3404
3100 m_host.AddScriptLPS(1); 3405 m_host.AddScriptLPS(1);
3101 3406
3102 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3407 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3111,14 +3416,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3111 UUID friendTransactionID = UUID.Random(); 3416 UUID friendTransactionID = UUID.Random();
3112 3417
3113 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3418 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3114 3419
3115 GridInstantMessage msg = new GridInstantMessage(); 3420 GridInstantMessage msg = new GridInstantMessage();
3116 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3421 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3117 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3422 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3118 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3423 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3119// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3424// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3120// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3425// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3121 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3426// DateTime dt = DateTime.UtcNow;
3427//
3428// // Ticks from UtcNow, but make it look like local. Evil, huh?
3429// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3430//
3431// try
3432// {
3433// // Convert that to the PST timezone
3434// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3435// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3436// }
3437// catch
3438// {
3439// // No logging here, as it could be VERY spammy
3440// }
3441//
3442// // And make it look local again to fool the unix time util
3443// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3444
3445 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3446
3122 //if (client != null) 3447 //if (client != null)
3123 //{ 3448 //{
3124 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3449 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3132,12 +3457,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3132 msg.message = message.Substring(0, 1024); 3457 msg.message = message.Substring(0, 1024);
3133 else 3458 else
3134 msg.message = message; 3459 msg.message = message;
3135 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3460 msg.dialog = (byte)19; // MessageFromObject
3136 msg.fromGroup = false;// fromGroup; 3461 msg.fromGroup = false;// fromGroup;
3137 msg.offline = (byte)0; //offline; 3462 msg.offline = (byte)0; //offline;
3138 msg.ParentEstateID = 0; //ParentEstateID; 3463 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3139 msg.Position = new Vector3(m_host.AbsolutePosition); 3464 msg.Position = new Vector3(m_host.AbsolutePosition);
3140 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3465 msg.RegionID = World.RegionInfo.RegionID.Guid;
3141 msg.binaryBucket 3466 msg.binaryBucket
3142 = Util.StringToBytes256( 3467 = Util.StringToBytes256(
3143 "{0}/{1}/{2}/{3}", 3468 "{0}/{1}/{2}/{3}",
@@ -3165,7 +3490,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3165 } 3490 }
3166 3491
3167 emailModule.SendEmail(m_host.UUID, address, subject, message); 3492 emailModule.SendEmail(m_host.UUID, address, subject, message);
3168 llSleep(EMAIL_PAUSE_TIME); 3493 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3169 } 3494 }
3170 3495
3171 public void llGetNextEmail(string address, string subject) 3496 public void llGetNextEmail(string address, string subject)
@@ -3411,7 +3736,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3411 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3736 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3412 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3737 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3413 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3738 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3739 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3414 ScriptBaseClass.PERMISSION_ATTACH; 3740 ScriptBaseClass.PERMISSION_ATTACH;
3741
3415 } 3742 }
3416 else 3743 else
3417 { 3744 {
@@ -3446,11 +3773,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3446 3773
3447 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3774 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3448 { 3775 {
3449 lock (m_host.TaskInventory) 3776 m_host.TaskInventory.LockItemsForWrite(true);
3450 { 3777 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3451 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3778 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3452 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3779 m_host.TaskInventory.LockItemsForWrite(false);
3453 }
3454 3780
3455 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3781 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3456 "run_time_permissions", new Object[] { 3782 "run_time_permissions", new Object[] {
@@ -3493,11 +3819,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3493 3819
3494 if (!m_waitingForScriptAnswer) 3820 if (!m_waitingForScriptAnswer)
3495 { 3821 {
3496 lock (m_host.TaskInventory) 3822 m_host.TaskInventory.LockItemsForWrite(true);
3497 { 3823 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3498 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3824 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3499 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3825 m_host.TaskInventory.LockItemsForWrite(false);
3500 }
3501 3826
3502 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3827 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3503 m_waitingForScriptAnswer=true; 3828 m_waitingForScriptAnswer=true;
@@ -3526,14 +3851,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3526 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3851 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3527 llReleaseControls(); 3852 llReleaseControls();
3528 3853
3529 lock (m_host.TaskInventory) 3854 m_host.TaskInventory.LockItemsForWrite(true);
3530 { 3855 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3531 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3856 m_host.TaskInventory.LockItemsForWrite(false);
3532 } 3857
3533 3858 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3534 m_ScriptEngine.PostScriptEvent( 3859 "run_time_permissions", new Object[] {
3535 m_item.ItemID, 3860 new LSL_Integer(answer) },
3536 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3861 new DetectParams[0]));
3537 } 3862 }
3538 3863
3539 public LSL_String llGetPermissionsKey() 3864 public LSL_String llGetPermissionsKey()
@@ -3572,14 +3897,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3572 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3897 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3573 { 3898 {
3574 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3899 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3575 3900 if (parts.Count > 0)
3576 foreach (SceneObjectPart part in parts) 3901 {
3577 part.SetFaceColorAlpha(face, color, null); 3902 try
3903 {
3904 foreach (SceneObjectPart part in parts)
3905 part.SetFaceColorAlpha(face, color, null);
3906 }
3907 finally
3908 {
3909 }
3910 }
3578 } 3911 }
3579 3912
3580 public void llCreateLink(string target, int parent) 3913 public void llCreateLink(string target, int parent)
3581 { 3914 {
3582 m_host.AddScriptLPS(1); 3915 m_host.AddScriptLPS(1);
3916
3583 UUID targetID; 3917 UUID targetID;
3584 3918
3585 if (!UUID.TryParse(target, out targetID)) 3919 if (!UUID.TryParse(target, out targetID))
@@ -3685,10 +4019,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3685 // Restructuring Multiple Prims. 4019 // Restructuring Multiple Prims.
3686 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4020 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3687 parts.Remove(parentPrim.RootPart); 4021 parts.Remove(parentPrim.RootPart);
3688 foreach (SceneObjectPart part in parts) 4022 if (parts.Count > 0)
3689 { 4023 {
3690 parentPrim.DelinkFromGroup(part.LocalId, true); 4024 try
4025 {
4026 foreach (SceneObjectPart part in parts)
4027 {
4028 parentPrim.DelinkFromGroup(part.LocalId, true);
4029 }
4030 }
4031 finally
4032 {
4033 }
3691 } 4034 }
4035
3692 parentPrim.HasGroupChanged = true; 4036 parentPrim.HasGroupChanged = true;
3693 parentPrim.ScheduleGroupForFullUpdate(); 4037 parentPrim.ScheduleGroupForFullUpdate();
3694 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4038 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3697,12 +4041,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3697 { 4041 {
3698 SceneObjectPart newRoot = parts[0]; 4042 SceneObjectPart newRoot = parts[0];
3699 parts.Remove(newRoot); 4043 parts.Remove(newRoot);
3700 foreach (SceneObjectPart part in parts) 4044
4045 try
3701 { 4046 {
3702 // Required for linking 4047 foreach (SceneObjectPart part in parts)
3703 part.ClearUpdateSchedule(); 4048 {
3704 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4049 part.ClearUpdateSchedule();
4050 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4051 }
3705 } 4052 }
4053 finally
4054 {
4055 }
4056
4057
3706 newRoot.ParentGroup.HasGroupChanged = true; 4058 newRoot.ParentGroup.HasGroupChanged = true;
3707 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4059 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3708 } 4060 }
@@ -3722,6 +4074,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3722 public void llBreakAllLinks() 4074 public void llBreakAllLinks()
3723 { 4075 {
3724 m_host.AddScriptLPS(1); 4076 m_host.AddScriptLPS(1);
4077
4078 TaskInventoryItem item = m_item;
4079
4080 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4081 && !m_automaticLinkPermission)
4082 {
4083 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4084 return;
4085 }
4086
3725 SceneObjectGroup parentPrim = m_host.ParentGroup; 4087 SceneObjectGroup parentPrim = m_host.ParentGroup;
3726 if (parentPrim.AttachmentPoint != 0) 4088 if (parentPrim.AttachmentPoint != 0)
3727 return; // Fail silently if attached 4089 return; // Fail silently if attached
@@ -3741,25 +4103,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3741 public LSL_String llGetLinkKey(int linknum) 4103 public LSL_String llGetLinkKey(int linknum)
3742 { 4104 {
3743 m_host.AddScriptLPS(1); 4105 m_host.AddScriptLPS(1);
3744 List<UUID> keytable = new List<UUID>();
3745 // parse for sitting avatare-uuids
3746 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3747 {
3748 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3749 keytable.Add(presence.UUID);
3750 });
3751
3752 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3753 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3754 {
3755 return keytable[totalprims - linknum].ToString();
3756 }
3757
3758 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3759 {
3760 return m_host.UUID.ToString();
3761 }
3762
3763 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4106 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3764 if (part != null) 4107 if (part != null)
3765 { 4108 {
@@ -3767,6 +4110,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3767 } 4110 }
3768 else 4111 else
3769 { 4112 {
4113 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4114 {
4115 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4116
4117 if (linknum < 0)
4118 return UUID.Zero.ToString();
4119
4120 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4121 if (avatars.Count > linknum)
4122 {
4123 return avatars[linknum].UUID.ToString();
4124 }
4125 }
3770 return UUID.Zero.ToString(); 4126 return UUID.Zero.ToString();
3771 } 4127 }
3772 } 4128 }
@@ -3866,17 +4222,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3866 m_host.AddScriptLPS(1); 4222 m_host.AddScriptLPS(1);
3867 int count = 0; 4223 int count = 0;
3868 4224
3869 lock (m_host.TaskInventory) 4225 m_host.TaskInventory.LockItemsForRead(true);
4226 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3870 { 4227 {
3871 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4228 if (inv.Value.Type == type || type == -1)
3872 { 4229 {
3873 if (inv.Value.Type == type || type == -1) 4230 count = count + 1;
3874 {
3875 count = count + 1;
3876 }
3877 } 4231 }
3878 } 4232 }
3879 4233
4234 m_host.TaskInventory.LockItemsForRead(false);
3880 return count; 4235 return count;
3881 } 4236 }
3882 4237
@@ -3885,16 +4240,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3885 m_host.AddScriptLPS(1); 4240 m_host.AddScriptLPS(1);
3886 ArrayList keys = new ArrayList(); 4241 ArrayList keys = new ArrayList();
3887 4242
3888 lock (m_host.TaskInventory) 4243 m_host.TaskInventory.LockItemsForRead(true);
4244 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3889 { 4245 {
3890 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4246 if (inv.Value.Type == type || type == -1)
3891 { 4247 {
3892 if (inv.Value.Type == type || type == -1) 4248 keys.Add(inv.Value.Name);
3893 {
3894 keys.Add(inv.Value.Name);
3895 }
3896 } 4249 }
3897 } 4250 }
4251 m_host.TaskInventory.LockItemsForRead(false);
3898 4252
3899 if (keys.Count == 0) 4253 if (keys.Count == 0)
3900 { 4254 {
@@ -3932,7 +4286,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3932 if (item == null) 4286 if (item == null)
3933 { 4287 {
3934 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4288 llSay(0, String.Format("Could not find object '{0}'", inventory));
3935 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4289 return;
4290// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3936 } 4291 }
3937 4292
3938 UUID objId = item.ItemID; 4293 UUID objId = item.ItemID;
@@ -3960,33 +4315,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3960 return; 4315 return;
3961 } 4316 }
3962 } 4317 }
4318
3963 // destination is an avatar 4319 // destination is an avatar
3964 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4320 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3965 4321
3966 if (agentItem == null) 4322 if (agentItem == null)
3967 return; 4323 return;
3968 4324
3969 if (m_TransferModule != null) 4325 byte[] bucket = new byte[1];
3970 { 4326 bucket[0] = (byte)item.Type;
3971 byte[] bucket = new byte[] { (byte)item.Type }; 4327 //byte[] objBytes = agentItem.ID.GetBytes();
4328 //Array.Copy(objBytes, 0, bucket, 1, 16);
4329
4330 GridInstantMessage msg = new GridInstantMessage(World,
4331 m_host.OwnerID, m_host.Name, destId,
4332 (byte)InstantMessageDialog.TaskInventoryOffered,
4333 false, item.Name+". "+m_host.Name+" is located at "+
4334 World.RegionInfo.RegionName+" "+
4335 m_host.AbsolutePosition.ToString(),
4336 agentItem.ID, true, m_host.AbsolutePosition,
4337 bucket);
3972 4338
3973 GridInstantMessage msg = new GridInstantMessage(World, 4339 ScenePresence sp;
3974 m_host.UUID, m_host.Name + ", an object owned by " +
3975 resolveName(m_host.OwnerID) + ",", destId,
3976 (byte)InstantMessageDialog.TaskInventoryOffered,
3977 false, item.Name + "\n" + m_host.Name + " is located at " +
3978 World.RegionInfo.RegionName+" "+
3979 m_host.AbsolutePosition.ToString(),
3980 agentItem.ID, true, m_host.AbsolutePosition,
3981 bucket);
3982 4340
3983 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4341 if (World.TryGetScenePresence(destId, out sp))
4342 {
4343 sp.ControllingClient.SendInstantMessage(msg);
3984 } 4344 }
3985 4345 else
4346 {
4347 if (m_TransferModule != null)
4348 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4349 }
4350
4351 //This delay should only occur when giving inventory to avatars.
3986 ScriptSleep(3000); 4352 ScriptSleep(3000);
3987 } 4353 }
3988 } 4354 }
3989 4355
4356 [DebuggerNonUserCode]
3990 public void llRemoveInventory(string name) 4357 public void llRemoveInventory(string name)
3991 { 4358 {
3992 m_host.AddScriptLPS(1); 4359 m_host.AddScriptLPS(1);
@@ -4030,109 +4397,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4030 { 4397 {
4031 m_host.AddScriptLPS(1); 4398 m_host.AddScriptLPS(1);
4032 4399
4033 UUID uuid = (UUID)id; 4400 UUID uuid;
4034 PresenceInfo pinfo = null; 4401 if (UUID.TryParse(id, out uuid))
4035 UserAccount account;
4036
4037 UserInfoCacheEntry ce;
4038 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4039 { 4402 {
4040 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4403 PresenceInfo pinfo = null;
4041 if (account == null) 4404 UserAccount account;
4405
4406 UserInfoCacheEntry ce;
4407 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4042 { 4408 {
4043 m_userInfoCache[uuid] = null; // Cache negative 4409 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4044 return UUID.Zero.ToString(); 4410 if (account == null)
4045 } 4411 {
4412 m_userInfoCache[uuid] = null; // Cache negative
4413 return UUID.Zero.ToString();
4414 }
4046 4415
4047 4416
4048 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4417 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4049 if (pinfos != null && pinfos.Length > 0) 4418 if (pinfos != null && pinfos.Length > 0)
4050 {
4051 foreach (PresenceInfo p in pinfos)
4052 { 4419 {
4053 if (p.RegionID != UUID.Zero) 4420 foreach (PresenceInfo p in pinfos)
4054 { 4421 {
4055 pinfo = p; 4422 if (p.RegionID != UUID.Zero)
4423 {
4424 pinfo = p;
4425 }
4056 } 4426 }
4057 } 4427 }
4058 }
4059 4428
4060 ce = new UserInfoCacheEntry(); 4429 ce = new UserInfoCacheEntry();
4061 ce.time = Util.EnvironmentTickCount(); 4430 ce.time = Util.EnvironmentTickCount();
4062 ce.account = account; 4431 ce.account = account;
4063 ce.pinfo = pinfo; 4432 ce.pinfo = pinfo;
4064 } 4433 m_userInfoCache[uuid] = ce;
4065 else 4434 }
4066 { 4435 else
4067 if (ce == null) 4436 {
4068 return UUID.Zero.ToString(); 4437 if (ce == null)
4438 return UUID.Zero.ToString();
4069 4439
4070 account = ce.account; 4440 account = ce.account;
4071 pinfo = ce.pinfo; 4441 pinfo = ce.pinfo;
4072 } 4442 }
4073 4443
4074 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4444 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4075 {
4076 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4077 if (pinfos != null && pinfos.Length > 0)
4078 { 4445 {
4079 foreach (PresenceInfo p in pinfos) 4446 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4447 if (pinfos != null && pinfos.Length > 0)
4080 { 4448 {
4081 if (p.RegionID != UUID.Zero) 4449 foreach (PresenceInfo p in pinfos)
4082 { 4450 {
4083 pinfo = p; 4451 if (p.RegionID != UUID.Zero)
4452 {
4453 pinfo = p;
4454 }
4084 } 4455 }
4085 } 4456 }
4086 } 4457 else
4087 else 4458 pinfo = null;
4088 pinfo = null;
4089 4459
4090 ce.time = Util.EnvironmentTickCount(); 4460 ce.time = Util.EnvironmentTickCount();
4091 ce.pinfo = pinfo; 4461 ce.pinfo = pinfo;
4092 } 4462 }
4093 4463
4094 string reply = String.Empty; 4464 string reply = String.Empty;
4095 4465
4096 switch (data) 4466 switch (data)
4097 { 4467 {
4098 case 1: // DATA_ONLINE (0|1) 4468 case 1: // DATA_ONLINE (0|1)
4099 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4469 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4100 reply = "1"; 4470 reply = "1";
4101 else 4471 else
4102 reply = "0"; 4472 reply = "0";
4103 break; 4473 break;
4104 case 2: // DATA_NAME (First Last) 4474 case 2: // DATA_NAME (First Last)
4105 reply = account.FirstName + " " + account.LastName; 4475 reply = account.FirstName + " " + account.LastName;
4106 break; 4476 break;
4107 case 3: // DATA_BORN (YYYY-MM-DD) 4477 case 3: // DATA_BORN (YYYY-MM-DD)
4108 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4478 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4109 born = born.AddSeconds(account.Created); 4479 born = born.AddSeconds(account.Created);
4110 reply = born.ToString("yyyy-MM-dd"); 4480 reply = born.ToString("yyyy-MM-dd");
4111 break; 4481 break;
4112 case 4: // DATA_RATING (0,0,0,0,0,0) 4482 case 4: // DATA_RATING (0,0,0,0,0,0)
4113 reply = "0,0,0,0,0,0"; 4483 reply = "0,0,0,0,0,0";
4114 break; 4484 break;
4115 case 7: // DATA_USERLEVEL (integer) 4485 case 8: // DATA_PAYINFO (0|1|2|3)
4116 reply = account.UserLevel.ToString(); 4486 reply = "0";
4117 break; 4487 break;
4118 case 8: // DATA_PAYINFO (0|1|2|3) 4488 default:
4119 reply = "0"; 4489 return UUID.Zero.ToString(); // Raise no event
4120 break; 4490 }
4121 default:
4122 return UUID.Zero.ToString(); // Raise no event
4123 }
4124 4491
4125 UUID rq = UUID.Random(); 4492 UUID rq = UUID.Random();
4126 4493
4127 UUID tid = AsyncCommands. 4494 UUID tid = AsyncCommands.
4128 DataserverPlugin.RegisterRequest(m_host.LocalId, 4495 DataserverPlugin.RegisterRequest(m_host.LocalId,
4129 m_item.ItemID, rq.ToString()); 4496 m_item.ItemID, rq.ToString());
4130 4497
4131 AsyncCommands. 4498 AsyncCommands.
4132 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4499 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4133 4500
4134 ScriptSleep(100); 4501 ScriptSleep(100);
4135 return tid.ToString(); 4502 return tid.ToString();
4503 }
4504 else
4505 {
4506 ShoutError("Invalid UUID passed to llRequestAgentData.");
4507 }
4508 return "";
4136 } 4509 }
4137 4510
4138 public LSL_String llRequestInventoryData(string name) 4511 public LSL_String llRequestInventoryData(string name)
@@ -4189,13 +4562,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4189 if (UUID.TryParse(agent, out agentId)) 4562 if (UUID.TryParse(agent, out agentId))
4190 { 4563 {
4191 ScenePresence presence = World.GetScenePresence(agentId); 4564 ScenePresence presence = World.GetScenePresence(agentId);
4192 if (presence != null) 4565 if (presence != null && presence.PresenceType != PresenceType.Npc)
4193 { 4566 {
4567 // agent must not be a god
4568 if (presence.UserLevel >= 200) return;
4569
4194 // agent must be over the owners land 4570 // agent must be over the owners land
4195 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4571 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4196 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4572 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4197 { 4573 {
4198 World.TeleportClientHome(agentId, presence.ControllingClient); 4574 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4575 {
4576 // They can't be teleported home for some reason
4577 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4578 if (regionInfo != null)
4579 {
4580 World.RequestTeleportLocation(
4581 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4582 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4583 }
4584 }
4199 } 4585 }
4200 } 4586 }
4201 } 4587 }
@@ -4302,7 +4688,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4302 UUID av = new UUID(); 4688 UUID av = new UUID();
4303 if (!UUID.TryParse(agent,out av)) 4689 if (!UUID.TryParse(agent,out av))
4304 { 4690 {
4305 LSLError("First parameter to llDialog needs to be a key"); 4691 //LSLError("First parameter to llDialog needs to be a key");
4306 return; 4692 return;
4307 } 4693 }
4308 4694
@@ -4334,7 +4720,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4334 public void llCollisionSound(string impact_sound, double impact_volume) 4720 public void llCollisionSound(string impact_sound, double impact_volume)
4335 { 4721 {
4336 m_host.AddScriptLPS(1); 4722 m_host.AddScriptLPS(1);
4337 4723
4724 if(impact_sound == "")
4725 {
4726 m_host.CollisionSoundVolume = (float)impact_volume;
4727 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4728 m_host.CollisionSoundType = 0;
4729 return;
4730 }
4338 // TODO: Parameter check logic required. 4731 // TODO: Parameter check logic required.
4339 UUID soundId = UUID.Zero; 4732 UUID soundId = UUID.Zero;
4340 if (!UUID.TryParse(impact_sound, out soundId)) 4733 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4347,6 +4740,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4347 4740
4348 m_host.CollisionSound = soundId; 4741 m_host.CollisionSound = soundId;
4349 m_host.CollisionSoundVolume = (float)impact_volume; 4742 m_host.CollisionSoundVolume = (float)impact_volume;
4743 m_host.CollisionSoundType = 1;
4350 } 4744 }
4351 4745
4352 public LSL_String llGetAnimation(string id) 4746 public LSL_String llGetAnimation(string id)
@@ -4360,14 +4754,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4360 4754
4361 if (m_host.RegionHandle == presence.RegionHandle) 4755 if (m_host.RegionHandle == presence.RegionHandle)
4362 { 4756 {
4363 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4364
4365 if (presence != null) 4757 if (presence != null)
4366 { 4758 {
4367 AnimationSet currentAnims = presence.Animator.Animations; 4759 if (presence.SitGround)
4368 string currentAnimationState = String.Empty; 4760 return "Sitting on Ground";
4369 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4761 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4370 return currentAnimationState; 4762 return "Sitting";
4763
4764 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4765 string lslMovementAnimation;
4766
4767 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4768 return lslMovementAnimation;
4371 } 4769 }
4372 } 4770 }
4373 4771
@@ -4514,7 +4912,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4514 { 4912 {
4515 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4913 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4516 float distance_term = distance * distance * distance; // Script Energy 4914 float distance_term = distance * distance * distance; // Script Energy
4517 float pusher_mass = m_host.GetMass(); 4915 // use total object mass and not part
4916 float pusher_mass = m_host.ParentGroup.GetMass();
4518 4917
4519 float PUSH_ATTENUATION_DISTANCE = 17f; 4918 float PUSH_ATTENUATION_DISTANCE = 17f;
4520 float PUSH_ATTENUATION_SCALE = 5f; 4919 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4764,6 +5163,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4764 { 5163 {
4765 return item.AssetID.ToString(); 5164 return item.AssetID.ToString();
4766 } 5165 }
5166 m_host.TaskInventory.LockItemsForRead(false);
4767 5167
4768 return UUID.Zero.ToString(); 5168 return UUID.Zero.ToString();
4769 } 5169 }
@@ -4897,7 +5297,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4897 public LSL_Vector llGetCenterOfMass() 5297 public LSL_Vector llGetCenterOfMass()
4898 { 5298 {
4899 m_host.AddScriptLPS(1); 5299 m_host.AddScriptLPS(1);
4900 Vector3 center = m_host.GetGeometricCenter(); 5300 Vector3 center = m_host.GetCenterOfMass();
4901 return new LSL_Vector(center.X,center.Y,center.Z); 5301 return new LSL_Vector(center.X,center.Y,center.Z);
4902 } 5302 }
4903 5303
@@ -4916,14 +5316,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4916 { 5316 {
4917 m_host.AddScriptLPS(1); 5317 m_host.AddScriptLPS(1);
4918 5318
4919 if (src == null) 5319 return src.Length;
4920 {
4921 return 0;
4922 }
4923 else
4924 {
4925 return src.Length;
4926 }
4927 } 5320 }
4928 5321
4929 public LSL_Integer llList2Integer(LSL_List src, int index) 5322 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4994,7 +5387,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4994 else if (src.Data[index] is LSL_Float) 5387 else if (src.Data[index] is LSL_Float)
4995 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5388 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4996 else if (src.Data[index] is LSL_String) 5389 else if (src.Data[index] is LSL_String)
4997 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5390 {
5391 string str = ((LSL_String) src.Data[index]).m_string;
5392 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5393 if (m != Match.Empty)
5394 {
5395 str = m.Value;
5396 double d = 0.0;
5397 if (!Double.TryParse(str, out d))
5398 return 0.0;
5399
5400 return d;
5401 }
5402 return 0.0;
5403 }
4998 return Convert.ToDouble(src.Data[index]); 5404 return Convert.ToDouble(src.Data[index]);
4999 } 5405 }
5000 catch (FormatException) 5406 catch (FormatException)
@@ -5294,7 +5700,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5294 } 5700 }
5295 } 5701 }
5296 } 5702 }
5297 else { 5703 else
5704 {
5298 object[] array = new object[src.Length]; 5705 object[] array = new object[src.Length];
5299 Array.Copy(src.Data, 0, array, 0, src.Length); 5706 Array.Copy(src.Data, 0, array, 0, src.Length);
5300 result = new LSL_List(array); 5707 result = new LSL_List(array);
@@ -5401,7 +5808,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5401 public LSL_Integer llGetRegionAgentCount() 5808 public LSL_Integer llGetRegionAgentCount()
5402 { 5809 {
5403 m_host.AddScriptLPS(1); 5810 m_host.AddScriptLPS(1);
5404 return new LSL_Integer(World.GetRootAgentCount()); 5811
5812 int count = 0;
5813 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5814 count++;
5815 });
5816
5817 return new LSL_Integer(count);
5405 } 5818 }
5406 5819
5407 public LSL_Vector llGetRegionCorner() 5820 public LSL_Vector llGetRegionCorner()
@@ -5634,6 +6047,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5634 flags |= ScriptBaseClass.AGENT_AWAY; 6047 flags |= ScriptBaseClass.AGENT_AWAY;
5635 } 6048 }
5636 6049
6050 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6051 UUID[] anims = agent.Animator.GetAnimationArray();
6052 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6053 {
6054 flags |= ScriptBaseClass.AGENT_BUSY;
6055 }
6056
5637 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6057 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5638 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6058 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5639 { 6059 {
@@ -5681,6 +6101,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5681 flags |= ScriptBaseClass.AGENT_SITTING; 6101 flags |= ScriptBaseClass.AGENT_SITTING;
5682 } 6102 }
5683 6103
6104 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6105 {
6106 flags |= ScriptBaseClass.AGENT_MALE;
6107 }
6108
5684 return flags; 6109 return flags;
5685 } 6110 }
5686 6111
@@ -5827,10 +6252,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5827 m_host.AddScriptLPS(1); 6252 m_host.AddScriptLPS(1);
5828 6253
5829 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6254 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5830 6255 if (parts.Count > 0)
5831 foreach (var part in parts)
5832 { 6256 {
5833 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6257 try
6258 {
6259 foreach (var part in parts)
6260 {
6261 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6262 }
6263 }
6264 finally
6265 {
6266 }
5834 } 6267 }
5835 } 6268 }
5836 6269
@@ -5882,13 +6315,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5882 6315
5883 if (m_host.OwnerID == land.LandData.OwnerID) 6316 if (m_host.OwnerID == land.LandData.OwnerID)
5884 { 6317 {
5885 World.TeleportClientHome(agentID, presence.ControllingClient); 6318 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6319 presence.TeleportWithMomentum(pos, null);
6320 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5886 } 6321 }
5887 } 6322 }
5888 } 6323 }
5889 ScriptSleep(5000); 6324 ScriptSleep(5000);
5890 } 6325 }
5891 6326
6327 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6328 {
6329 return ParseString2List(str, separators, in_spacers, false);
6330 }
6331
5892 public LSL_Integer llOverMyLand(string id) 6332 public LSL_Integer llOverMyLand(string id)
5893 { 6333 {
5894 m_host.AddScriptLPS(1); 6334 m_host.AddScriptLPS(1);
@@ -5947,20 +6387,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5947 return agentSize; 6387 return agentSize;
5948 } 6388 }
5949 6389
5950 public LSL_Integer llSameGroup(string agent) 6390 public LSL_Integer llSameGroup(string id)
5951 { 6391 {
5952 m_host.AddScriptLPS(1); 6392 m_host.AddScriptLPS(1);
5953 UUID agentId = new UUID(); 6393 UUID uuid = new UUID();
5954 if (!UUID.TryParse(agent, out agentId)) 6394 if (!UUID.TryParse(id, out uuid))
5955 return new LSL_Integer(0);
5956 ScenePresence presence = World.GetScenePresence(agentId);
5957 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5958 return new LSL_Integer(0); 6395 return new LSL_Integer(0);
5959 IClientAPI client = presence.ControllingClient; 6396
5960 if (m_host.GroupID == client.ActiveGroupId) 6397 // Check if it's a group key
6398 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5961 return new LSL_Integer(1); 6399 return new LSL_Integer(1);
5962 else 6400
6401 // We got passed a UUID.Zero
6402 if (uuid == UUID.Zero)
5963 return new LSL_Integer(0); 6403 return new LSL_Integer(0);
6404
6405 // Handle the case where id names an avatar
6406 ScenePresence presence = World.GetScenePresence(uuid);
6407 if (presence != null)
6408 {
6409 if (presence.IsChildAgent)
6410 return new LSL_Integer(0);
6411
6412 IClientAPI client = presence.ControllingClient;
6413 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6414 return new LSL_Integer(1);
6415
6416 return new LSL_Integer(0);
6417 }
6418
6419 // Handle object case
6420 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6421 if (part != null)
6422 {
6423 // This will handle both deed and non-deed and also the no
6424 // group case
6425 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6426 return new LSL_Integer(1);
6427
6428 return new LSL_Integer(0);
6429 }
6430
6431 return new LSL_Integer(0);
5964 } 6432 }
5965 6433
5966 public void llUnSit(string id) 6434 public void llUnSit(string id)
@@ -6085,7 +6553,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6085 return m_host.ParentGroup.AttachmentPoint; 6553 return m_host.ParentGroup.AttachmentPoint;
6086 } 6554 }
6087 6555
6088 public LSL_Integer llGetFreeMemory() 6556 public virtual LSL_Integer llGetFreeMemory()
6089 { 6557 {
6090 m_host.AddScriptLPS(1); 6558 m_host.AddScriptLPS(1);
6091 // Make scripts designed for LSO happy 6559 // Make scripts designed for LSO happy
@@ -6202,7 +6670,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6202 SetParticleSystem(m_host, rules); 6670 SetParticleSystem(m_host, rules);
6203 } 6671 }
6204 6672
6205 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6673 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6674 {
6206 6675
6207 6676
6208 if (rules.Length == 0) 6677 if (rules.Length == 0)
@@ -6516,6 +6985,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6516 6985
6517 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6986 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6518 { 6987 {
6988 // LSL quaternions can normalize to 0, normal Quaternions can't.
6989 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6990 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6991
6519 part.SitTargetPosition = offset; 6992 part.SitTargetPosition = offset;
6520 part.SitTargetOrientation = rot; 6993 part.SitTargetOrientation = rot;
6521 part.ParentGroup.HasGroupChanged = true; 6994 part.ParentGroup.HasGroupChanged = true;
@@ -6671,13 +7144,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6671 UUID av = new UUID(); 7144 UUID av = new UUID();
6672 if (!UUID.TryParse(avatar,out av)) 7145 if (!UUID.TryParse(avatar,out av))
6673 { 7146 {
6674 LSLError("First parameter to llDialog needs to be a key"); 7147 //LSLError("First parameter to llDialog needs to be a key");
6675 return; 7148 return;
6676 } 7149 }
6677 if (buttons.Length < 1) 7150 if (buttons.Length < 1)
6678 { 7151 {
6679 LSLError("No less than 1 button can be shown"); 7152 buttons.Add("OK");
6680 return;
6681 } 7153 }
6682 if (buttons.Length > 12) 7154 if (buttons.Length > 12)
6683 { 7155 {
@@ -6694,7 +7166,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6694 } 7166 }
6695 if (buttons.Data[i].ToString().Length > 24) 7167 if (buttons.Data[i].ToString().Length > 24)
6696 { 7168 {
6697 LSLError("button label cannot be longer than 24 characters"); 7169 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6698 return; 7170 return;
6699 } 7171 }
6700 buts[i] = buttons.Data[i].ToString(); 7172 buts[i] = buttons.Data[i].ToString();
@@ -6761,9 +7233,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6761 return; 7233 return;
6762 } 7234 }
6763 7235
6764 // the rest of the permission checks are done in RezScript, so check the pin there as well 7236 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6765 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7237 if (dest != null)
7238 {
7239 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7240 {
7241 // the rest of the permission checks are done in RezScript, so check the pin there as well
7242 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6766 7243
7244 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7245 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7246 }
7247 }
6767 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7248 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6768 ScriptSleep(3000); 7249 ScriptSleep(3000);
6769 } 7250 }
@@ -6826,19 +7307,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6826 public LSL_String llMD5String(string src, int nonce) 7307 public LSL_String llMD5String(string src, int nonce)
6827 { 7308 {
6828 m_host.AddScriptLPS(1); 7309 m_host.AddScriptLPS(1);
6829 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7310 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6830 } 7311 }
6831 7312
6832 public LSL_String llSHA1String(string src) 7313 public LSL_String llSHA1String(string src)
6833 { 7314 {
6834 m_host.AddScriptLPS(1); 7315 m_host.AddScriptLPS(1);
6835 return Util.SHA1Hash(src).ToLower(); 7316 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6836 } 7317 }
6837 7318
6838 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7319 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6839 { 7320 {
6840 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7321 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6841 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7322 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7323 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7324 return shapeBlock;
6842 7325
6843 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7326 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6844 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7327 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6943,6 +7426,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6943 // Prim type box, cylinder and prism. 7426 // Prim type box, cylinder and prism.
6944 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) 7427 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve)
6945 { 7428 {
7429 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7430 return;
7431
6946 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7432 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6947 ObjectShapePacket.ObjectDataBlock shapeBlock; 7433 ObjectShapePacket.ObjectDataBlock shapeBlock;
6948 7434
@@ -6996,6 +7482,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6996 // Prim type sphere. 7482 // Prim type sphere.
6997 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7483 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6998 { 7484 {
7485 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7486 return;
7487
6999 ObjectShapePacket.ObjectDataBlock shapeBlock; 7488 ObjectShapePacket.ObjectDataBlock shapeBlock;
7000 7489
7001 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7490 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7037,6 +7526,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7037 // Prim type torus, tube and ring. 7526 // Prim type torus, tube and ring.
7038 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve) 7527 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve)
7039 { 7528 {
7529 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7530 return;
7531
7040 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7532 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7041 ObjectShapePacket.ObjectDataBlock shapeBlock; 7533 ObjectShapePacket.ObjectDataBlock shapeBlock;
7042 7534
@@ -7172,6 +7664,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7172 // Prim type sculpt. 7664 // Prim type sculpt.
7173 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7665 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7174 { 7666 {
7667 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7668 return;
7669
7175 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7670 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7176 UUID sculptId; 7671 UUID sculptId;
7177 7672
@@ -7196,7 +7691,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7196 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7691 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7197 { 7692 {
7198 // default 7693 // default
7199 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7694 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7200 } 7695 }
7201 7696
7202 part.Shape.SetSculptProperties((byte)type, sculptId); 7697 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7213,46 +7708,309 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7213 ScriptSleep(200); 7708 ScriptSleep(200);
7214 } 7709 }
7215 7710
7216 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7711 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7217 { 7712 {
7218 m_host.AddScriptLPS(1); 7713 m_host.AddScriptLPS(1);
7219 7714
7220 setLinkPrimParams(linknumber, rules); 7715 setLinkPrimParams(linknumber, rules);
7716 }
7717
7718 private void setLinkPrimParams(int linknumber, LSL_List rules)
7719 {
7720 List<object> parts = new List<object>();
7721 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7722 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7723 foreach (SceneObjectPart p in prims)
7724 parts.Add(p);
7725 foreach (ScenePresence p in avatars)
7726 parts.Add(p);
7727
7728 LSL_List remaining = null;
7729
7730 if (parts.Count > 0)
7731 {
7732 foreach (object part in parts)
7733 {
7734 if (part is SceneObjectPart)
7735 remaining = SetPrimParams((SceneObjectPart)part, rules);
7736 else
7737 remaining = SetPrimParams((ScenePresence)part, rules);
7738 }
7739
7740 while((object)remaining != null && remaining.Length > 2)
7741 {
7742 linknumber = remaining.GetLSLIntegerItem(0);
7743 rules = remaining.GetSublist(1,-1);
7744 parts.Clear();
7745 prims = GetLinkParts(linknumber);
7746 avatars = GetLinkAvatars(linknumber);
7747 foreach (SceneObjectPart p in prims)
7748 parts.Add(p);
7749 foreach (ScenePresence p in avatars)
7750 parts.Add(p);
7751
7752 foreach (object part in parts)
7753 {
7754 if (part is SceneObjectPart)
7755 remaining = SetPrimParams((SceneObjectPart)part, rules);
7756 else
7757 remaining = SetPrimParams((ScenePresence)part, rules);
7758 }
7759 }
7760 }
7761 }
7762
7763 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7764 float material_density, float material_friction,
7765 float material_restitution, float material_gravity_modifier)
7766 {
7767 ExtraPhysicsData physdata = new ExtraPhysicsData();
7768 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7769 physdata.Density = part.Density;
7770 physdata.Friction = part.Friction;
7771 physdata.Bounce = part.Bounciness;
7772 physdata.GravitationModifier = part.GravityModifier;
7773
7774 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7775 physdata.Density = material_density;
7776 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7777 physdata.Friction = material_friction;
7778 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7779 physdata.Bounce = material_restitution;
7780 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7781 physdata.GravitationModifier = material_gravity_modifier;
7782
7783 part.UpdateExtraPhysics(physdata);
7784 }
7785
7786 public void llSetPhysicsMaterial(int material_bits,
7787 float material_gravity_modifier, float material_restitution,
7788 float material_friction, float material_density)
7789 {
7790 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7791 }
7221 7792
7793 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7794 {
7795 llSetLinkPrimitiveParamsFast(linknumber, rules);
7222 ScriptSleep(200); 7796 ScriptSleep(200);
7223 } 7797 }
7224 7798
7225 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7799 // vector up using libomv (c&p from sop )
7800 // vector up rotated by r
7801 private Vector3 Zrot(Quaternion r)
7226 { 7802 {
7227 m_host.AddScriptLPS(1); 7803 double x, y, z, m;
7228 7804
7229 setLinkPrimParams(linknumber, rules); 7805 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7806 if (Math.Abs(1.0 - m) > 0.000001)
7807 {
7808 m = 1.0 / Math.Sqrt(m);
7809 r.X *= (float)m;
7810 r.Y *= (float)m;
7811 r.Z *= (float)m;
7812 r.W *= (float)m;
7813 }
7814
7815 x = 2 * (r.X * r.Z + r.Y * r.W);
7816 y = 2 * (-r.X * r.W + r.Y * r.Z);
7817 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7818
7819 return new Vector3((float)x, (float)y, (float)z);
7230 } 7820 }
7231 7821
7232 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7822 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules)
7233 { 7823 {
7234 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7824 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7235 7825
7236 LSL_List remaining = null; 7826 int idx = 0;
7237 7827
7238 foreach (SceneObjectPart part in parts) 7828 bool positionChanged = false;
7239 remaining = SetPrimParams(part, rules); 7829 Vector3 finalPos = Vector3.Zero;
7240 7830
7241 while(remaining != null && remaining.Length > 2) 7831 try
7242 { 7832 {
7243 linknumber = remaining.GetLSLIntegerItem(0); 7833 while (idx < rules.Length)
7244 rules = remaining.GetSublist(1,-1); 7834 {
7245 parts = GetLinkParts(linknumber); 7835 int code = rules.GetLSLIntegerItem(idx++);
7836
7837 int remain = rules.Length - idx;
7838
7839 switch (code)
7840 {
7841 case (int)ScriptBaseClass.PRIM_POSITION:
7842 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7843 {
7844 if (remain < 1)
7845 return null;
7846
7847 LSL_Vector v;
7848 v = rules.GetVector3Item(idx++);
7849
7850 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7851 if (part == null)
7852 break;
7853
7854 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7855 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7856 if (part.LinkNum > 1)
7857 {
7858 localRot = GetPartLocalRot(part);
7859 localPos = GetPartLocalPos(part);
7860 }
7861
7862 v -= localPos;
7863 v /= localRot;
7864
7865 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7866
7867 v = v + 2 * sitOffset;
7868
7869 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7870 av.SendAvatarDataToAllAgents();
7871
7872 }
7873 break;
7874
7875 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7876 case (int)ScriptBaseClass.PRIM_ROTATION:
7877 {
7878 if (remain < 1)
7879 return null;
7880
7881 LSL_Rotation r;
7882 r = rules.GetQuaternionItem(idx++);
7883
7884 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7885 if (part == null)
7886 break;
7887
7888 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7889 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7890
7891 if (part.LinkNum > 1)
7892 localRot = GetPartLocalRot(part);
7893
7894 r = r * llGetRootRotation() / localRot;
7895 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7896 av.SendAvatarDataToAllAgents();
7897 }
7898 break;
7899
7900 // parse rest doing nothing but number of parameters error check
7901 case (int)ScriptBaseClass.PRIM_SIZE:
7902 case (int)ScriptBaseClass.PRIM_MATERIAL:
7903 case (int)ScriptBaseClass.PRIM_PHANTOM:
7904 case (int)ScriptBaseClass.PRIM_PHYSICS:
7905 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7906 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7907 case (int)ScriptBaseClass.PRIM_NAME:
7908 case (int)ScriptBaseClass.PRIM_DESC:
7909 if (remain < 1)
7910 return null;
7911 idx++;
7912 break;
7913
7914 case (int)ScriptBaseClass.PRIM_GLOW:
7915 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7916 case (int)ScriptBaseClass.PRIM_TEXGEN:
7917 if (remain < 2)
7918 return null;
7919 idx += 2;
7920 break;
7921
7922 case (int)ScriptBaseClass.PRIM_TYPE:
7923 if (remain < 3)
7924 return null;
7925 code = (int)rules.GetLSLIntegerItem(idx++);
7926 remain = rules.Length - idx;
7927 switch (code)
7928 {
7929 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7930 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7931 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7932 if (remain < 6)
7933 return null;
7934 idx += 6;
7935 break;
7936
7937 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7938 if (remain < 5)
7939 return null;
7940 idx += 5;
7941 break;
7942
7943 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7944 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7945 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7946 if (remain < 11)
7947 return null;
7948 idx += 11;
7949 break;
7950
7951 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7952 if (remain < 2)
7953 return null;
7954 idx += 2;
7955 break;
7956 }
7957 break;
7958
7959 case (int)ScriptBaseClass.PRIM_COLOR:
7960 case (int)ScriptBaseClass.PRIM_TEXT:
7961 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7962 case (int)ScriptBaseClass.PRIM_OMEGA:
7963 if (remain < 3)
7964 return null;
7965 idx += 3;
7966 break;
7967
7968 case (int)ScriptBaseClass.PRIM_TEXTURE:
7969 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7970 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
7971 if (remain < 5)
7972 return null;
7973 idx += 5;
7974 break;
7975
7976 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
7977 if (remain < 7)
7978 return null;
7979
7980 idx += 7;
7981 break;
7982
7983 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7984 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7985 return null;
7246 7986
7247 foreach (SceneObjectPart part in parts) 7987 return rules.GetSublist(idx, -1);
7248 remaining = SetPrimParams(part, rules); 7988 }
7989 }
7249 } 7990 }
7991
7992 finally
7993 {
7994 if (positionChanged)
7995 {
7996 av.OffsetPosition = finalPos;
7997// av.SendAvatarDataToAllAgents();
7998 av.SendTerseUpdateToAllClients();
7999 positionChanged = false;
8000 }
8001 }
8002 return null;
7250 } 8003 }
7251 8004
7252 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules) 8005 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules)
7253 { 8006 {
8007 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8008 return null;
8009
7254 int idx = 0; 8010 int idx = 0;
7255 8011
8012 SceneObjectGroup parentgrp = part.ParentGroup;
8013
7256 bool positionChanged = false; 8014 bool positionChanged = false;
7257 LSL_Vector currentPosition = GetPartLocalPos(part); 8015 LSL_Vector currentPosition = GetPartLocalPos(part);
7258 8016
@@ -7275,8 +8033,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7275 return null; 8033 return null;
7276 8034
7277 v=rules.GetVector3Item(idx++); 8035 v=rules.GetVector3Item(idx++);
7278 positionChanged = true;
7279 currentPosition = GetSetPosTarget(part, v, currentPosition); 8036 currentPosition = GetSetPosTarget(part, v, currentPosition);
8037 positionChanged = true;
7280 8038
7281 break; 8039 break;
7282 case (int)ScriptBaseClass.PRIM_SIZE: 8040 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7292,8 +8050,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7292 return null; 8050 return null;
7293 8051
7294 LSL_Rotation q = rules.GetQuaternionItem(idx++); 8052 LSL_Rotation q = rules.GetQuaternionItem(idx++);
8053 SceneObjectPart rootPart = parentgrp.RootPart;
7295 // try to let this work as in SL... 8054 // try to let this work as in SL...
7296 if (part.ParentID == 0) 8055 if (rootPart == part)
7297 { 8056 {
7298 // special case: If we are root, rotate complete SOG to new rotation 8057 // special case: If we are root, rotate complete SOG to new rotation
7299 SetRot(part, q); 8058 SetRot(part, q);
@@ -7301,7 +8060,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7301 else 8060 else
7302 { 8061 {
7303 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 8062 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7304 SceneObjectPart rootPart = part.ParentGroup.RootPart; 8063 // sounds like sl bug that we need to replicate
7305 SetRot(part, rootPart.RotationOffset * (Quaternion)q); 8064 SetRot(part, rootPart.RotationOffset * (Quaternion)q);
7306 } 8065 }
7307 8066
@@ -7553,7 +8312,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7553 return null; 8312 return null;
7554 8313
7555 string ph = rules.Data[idx++].ToString(); 8314 string ph = rules.Data[idx++].ToString();
7556 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8315 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7557 8316
7558 break; 8317 break;
7559 8318
@@ -7571,12 +8330,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7571 part.ScriptSetPhysicsStatus(physics); 8330 part.ScriptSetPhysicsStatus(physics);
7572 break; 8331 break;
7573 8332
8333 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8334 if (remain < 1)
8335 return null;
8336
8337 int shape_type = rules.GetLSLIntegerItem(idx++);
8338
8339 ExtraPhysicsData physdata = new ExtraPhysicsData();
8340 physdata.Density = part.Density;
8341 physdata.Bounce = part.Bounciness;
8342 physdata.GravitationModifier = part.GravityModifier;
8343 physdata.PhysShapeType = (PhysShapeType)shape_type;
8344
8345 part.UpdateExtraPhysics(physdata);
8346
8347 break;
8348
8349 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8350 if (remain < 5)
8351 return null;
8352
8353 int material_bits = rules.GetLSLIntegerItem(idx++);
8354 float material_density = (float)rules.GetLSLFloatItem(idx++);
8355 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8356 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8357 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8358
8359 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8360
8361 break;
8362
7574 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8363 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7575 if (remain < 1) 8364 if (remain < 1)
7576 return null; 8365 return null;
7577 string temp = rules.Data[idx++].ToString(); 8366 string temp = rules.Data[idx++].ToString();
7578 8367
7579 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8368 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7580 8369
7581 break; 8370 break;
7582 8371
@@ -7648,7 +8437,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7648 if (part.ParentGroup.RootPart == part) 8437 if (part.ParentGroup.RootPart == part)
7649 { 8438 {
7650 SceneObjectGroup parent = part.ParentGroup; 8439 SceneObjectGroup parent = part.ParentGroup;
7651 parent.UpdateGroupPosition(currentPosition); 8440 Util.FireAndForget(delegate(object x) {
8441 parent.UpdateGroupPosition(currentPosition);
8442 });
7652 } 8443 }
7653 else 8444 else
7654 { 8445 {
@@ -7693,10 +8484,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7693 8484
7694 public LSL_String llXorBase64Strings(string str1, string str2) 8485 public LSL_String llXorBase64Strings(string str1, string str2)
7695 { 8486 {
7696 m_host.AddScriptLPS(1); 8487 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7697 Deprecated("llXorBase64Strings"); 8488
7698 ScriptSleep(300); 8489 ScriptSleep(300);
7699 return String.Empty; 8490 m_host.AddScriptLPS(1);
8491
8492 if (str1 == String.Empty)
8493 return String.Empty;
8494 if (str2 == String.Empty)
8495 return str1;
8496
8497 int len = str2.Length;
8498 if ((len % 4) != 0) // LL is EVIL!!!!
8499 {
8500 while (str2.EndsWith("="))
8501 str2 = str2.Substring(0, str2.Length - 1);
8502
8503 len = str2.Length;
8504 int mod = len % 4;
8505
8506 if (mod == 1)
8507 str2 = str2.Substring(0, str2.Length - 1);
8508 else if (mod == 2)
8509 str2 += "==";
8510 else if (mod == 3)
8511 str2 += "=";
8512 }
8513
8514 byte[] data1;
8515 byte[] data2;
8516 try
8517 {
8518 data1 = Convert.FromBase64String(str1);
8519 data2 = Convert.FromBase64String(str2);
8520 }
8521 catch (Exception)
8522 {
8523 return new LSL_String(String.Empty);
8524 }
8525
8526 // For cases where the decoded length of s2 is greater
8527 // than the decoded length of s1, simply perform a normal
8528 // decode and XOR
8529 //
8530 if (data2.Length >= data1.Length)
8531 {
8532 for (int pos = 0 ; pos < data1.Length ; pos++ )
8533 data1[pos] ^= data2[pos];
8534
8535 return Convert.ToBase64String(data1);
8536 }
8537
8538 // Remove padding
8539 while (str1.EndsWith("="))
8540 str1 = str1.Substring(0, str1.Length - 1);
8541 while (str2.EndsWith("="))
8542 str2 = str2.Substring(0, str2.Length - 1);
8543
8544 byte[] d1 = new byte[str1.Length];
8545 byte[] d2 = new byte[str2.Length];
8546
8547 for (int i = 0 ; i < str1.Length ; i++)
8548 {
8549 int idx = b64.IndexOf(str1.Substring(i, 1));
8550 if (idx == -1)
8551 idx = 0;
8552 d1[i] = (byte)idx;
8553 }
8554
8555 for (int i = 0 ; i < str2.Length ; i++)
8556 {
8557 int idx = b64.IndexOf(str2.Substring(i, 1));
8558 if (idx == -1)
8559 idx = 0;
8560 d2[i] = (byte)idx;
8561 }
8562
8563 string output = String.Empty;
8564
8565 for (int pos = 0 ; pos < d1.Length ; pos++)
8566 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8567
8568 while (output.Length % 3 > 0)
8569 output += "=";
8570
8571 return output;
7700 } 8572 }
7701 8573
7702 public void llRemoteDataSetRegion() 8574 public void llRemoteDataSetRegion()
@@ -7820,13 +8692,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7820 public LSL_Integer llGetNumberOfPrims() 8692 public LSL_Integer llGetNumberOfPrims()
7821 { 8693 {
7822 m_host.AddScriptLPS(1); 8694 m_host.AddScriptLPS(1);
7823 int avatarCount = 0; 8695 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7824 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8696
7825 {
7826 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7827 avatarCount++;
7828 });
7829
7830 return m_host.ParentGroup.PrimCount + avatarCount; 8697 return m_host.ParentGroup.PrimCount + avatarCount;
7831 } 8698 }
7832 8699
@@ -7842,55 +8709,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7842 m_host.AddScriptLPS(1); 8709 m_host.AddScriptLPS(1);
7843 UUID objID = UUID.Zero; 8710 UUID objID = UUID.Zero;
7844 LSL_List result = new LSL_List(); 8711 LSL_List result = new LSL_List();
8712
8713 // If the ID is not valid, return null result
7845 if (!UUID.TryParse(obj, out objID)) 8714 if (!UUID.TryParse(obj, out objID))
7846 { 8715 {
7847 result.Add(new LSL_Vector()); 8716 result.Add(new LSL_Vector());
7848 result.Add(new LSL_Vector()); 8717 result.Add(new LSL_Vector());
7849 return result; 8718 return result;
7850 } 8719 }
8720
8721 // Check if this is an attached prim. If so, replace
8722 // the UUID with the avatar UUID and report it's bounding box
8723 SceneObjectPart part = World.GetSceneObjectPart(objID);
8724 if (part != null && part.ParentGroup.IsAttachment)
8725 objID = part.ParentGroup.AttachedAvatar;
8726
8727 // Find out if this is an avatar ID. If so, return it's box
7851 ScenePresence presence = World.GetScenePresence(objID); 8728 ScenePresence presence = World.GetScenePresence(objID);
7852 if (presence != null) 8729 if (presence != null)
7853 { 8730 {
7854 if (presence.ParentID == 0) // not sat on an object 8731 // As per LSL Wiki, there is no difference between sitting
8732 // and standing avatar since server 1.36
8733 LSL_Vector lower;
8734 LSL_Vector upper;
8735 if (presence.Animator.Animations.DefaultAnimation.AnimID
8736 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7855 { 8737 {
7856 LSL_Vector lower; 8738 // This is for ground sitting avatars
7857 LSL_Vector upper; 8739 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7858 if (presence.Animator.Animations.DefaultAnimation.AnimID 8740 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7859 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8741 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7860 {
7861 // This is for ground sitting avatars
7862 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7863 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7864 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7865 }
7866 else
7867 {
7868 // This is for standing/flying avatars
7869 float height = presence.Appearance.AvatarHeight / 2.0f;
7870 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7871 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7872 }
7873 result.Add(lower);
7874 result.Add(upper);
7875 return result;
7876 } 8742 }
7877 else 8743 else
7878 { 8744 {
7879 // sitting on an object so we need the bounding box of that 8745 // This is for standing/flying avatars
7880 // which should include the avatar so set the UUID to the 8746 float height = presence.Appearance.AvatarHeight / 2.0f;
7881 // UUID of the object the avatar is sat on and allow it to fall through 8747 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7882 // to processing an object 8748 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7883 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7884 objID = p.UUID;
7885 } 8749 }
8750
8751 // Adjust to the documented error offsets (see LSL Wiki)
8752 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8753 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8754
8755 if (lower.x > upper.x)
8756 lower.x = upper.x;
8757 if (lower.y > upper.y)
8758 lower.y = upper.y;
8759 if (lower.z > upper.z)
8760 lower.z = upper.z;
8761
8762 result.Add(lower);
8763 result.Add(upper);
8764 return result;
7886 } 8765 }
7887 SceneObjectPart part = World.GetSceneObjectPart(objID); 8766
8767 part = World.GetSceneObjectPart(objID);
7888 // Currently only works for single prims without a sitting avatar 8768 // Currently only works for single prims without a sitting avatar
7889 if (part != null) 8769 if (part != null)
7890 { 8770 {
7891 Vector3 halfSize = part.Scale / 2.0f; 8771 float minX;
7892 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8772 float maxX;
7893 LSL_Vector upper = new LSL_Vector(halfSize); 8773 float minY;
8774 float maxY;
8775 float minZ;
8776 float maxZ;
8777
8778 // This BBox is in sim coordinates, with the offset being
8779 // a contained point.
8780 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8781 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8782
8783 minX -= offsets[0].X;
8784 maxX -= offsets[0].X;
8785 minY -= offsets[0].Y;
8786 maxY -= offsets[0].Y;
8787 minZ -= offsets[0].Z;
8788 maxZ -= offsets[0].Z;
8789
8790 LSL_Vector lower;
8791 LSL_Vector upper;
8792
8793 // Adjust to the documented error offsets (see LSL Wiki)
8794 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8795 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8796
8797 if (lower.x > upper.x)
8798 lower.x = upper.x;
8799 if (lower.y > upper.y)
8800 lower.y = upper.y;
8801 if (lower.z > upper.z)
8802 lower.z = upper.z;
8803
7894 result.Add(lower); 8804 result.Add(lower);
7895 result.Add(upper); 8805 result.Add(upper);
7896 return result; 8806 return result;
@@ -7904,7 +8814,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7904 8814
7905 public LSL_Vector llGetGeometricCenter() 8815 public LSL_Vector llGetGeometricCenter()
7906 { 8816 {
7907 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8817 Vector3 tmp = m_host.GetGeometricCenter();
8818 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7908 } 8819 }
7909 8820
7910 public LSL_List llGetPrimitiveParams(LSL_List rules) 8821 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7917,16 +8828,291 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7917 { 8828 {
7918 m_host.AddScriptLPS(1); 8829 m_host.AddScriptLPS(1);
7919 8830
8831 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8832 // keep other options as before
8833
7920 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8834 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8835 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7921 8836
7922 LSL_List res = new LSL_List(); 8837 LSL_List res = new LSL_List();
7923 8838
7924 foreach (var part in parts) 8839 if (parts.Count > 0)
8840 {
8841 foreach (var part in parts)
8842 {
8843 LSL_List partRes = GetLinkPrimitiveParams(part, rules);
8844 res += partRes;
8845 }
8846 }
8847 if (avatars.Count > 0)
7925 { 8848 {
7926 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8849 foreach (ScenePresence avatar in avatars)
7927 res += partRes; 8850 {
8851 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules);
8852 res += avaRes;
8853 }
7928 } 8854 }
8855 return res;
8856 }
8857
8858 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8859 {
8860 // avatars case
8861 // replies as SL wiki
8862
8863 LSL_List res = new LSL_List();
8864// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8865 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8866
8867 int idx = 0;
8868 while (idx < rules.Length)
8869 {
8870 int code = (int)rules.GetLSLIntegerItem(idx++);
8871 int remain = rules.Length - idx;
8872
8873 switch (code)
8874 {
8875 case (int)ScriptBaseClass.PRIM_MATERIAL:
8876 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
8877 break;
8878
8879 case (int)ScriptBaseClass.PRIM_PHYSICS:
8880 res.Add(new LSL_Integer(0));
8881 break;
8882
8883 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8884 res.Add(new LSL_Integer(0));
8885 break;
8886
8887 case (int)ScriptBaseClass.PRIM_PHANTOM:
8888 res.Add(new LSL_Integer(0));
8889 break;
8890
8891 case (int)ScriptBaseClass.PRIM_POSITION:
8892
8893 Vector3 pos = avatar.OffsetPosition;
8894
8895 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8896 pos -= sitOffset;
8897
8898 if( sitPart != null)
8899 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
7929 8900
8901 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8902 break;
8903
8904 case (int)ScriptBaseClass.PRIM_SIZE:
8905 // as in llGetAgentSize above
8906 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8907 break;
8908
8909 case (int)ScriptBaseClass.PRIM_ROTATION:
8910 Quaternion rot = avatar.Rotation;
8911 if (sitPart != null)
8912 {
8913 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8914 }
8915
8916 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8917 break;
8918
8919 case (int)ScriptBaseClass.PRIM_TYPE:
8920 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8921 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8922 res.Add(new LSL_Vector(0f,1.0f,0f));
8923 res.Add(new LSL_Float(0.0f));
8924 res.Add(new LSL_Vector(0, 0, 0));
8925 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8926 res.Add(new LSL_Vector(0, 0, 0));
8927 break;
8928
8929 case (int)ScriptBaseClass.PRIM_TEXTURE:
8930 if (remain < 1)
8931 return res;
8932
8933 int face = (int)rules.GetLSLIntegerItem(idx++);
8934 if (face == ScriptBaseClass.ALL_SIDES)
8935 {
8936 for (face = 0; face < 21; face++)
8937 {
8938 res.Add(new LSL_String(""));
8939 res.Add(new LSL_Vector(0,0,0));
8940 res.Add(new LSL_Vector(0,0,0));
8941 res.Add(new LSL_Float(0.0));
8942 }
8943 }
8944 else
8945 {
8946 if (face >= 0 && face < 21)
8947 {
8948 res.Add(new LSL_String(""));
8949 res.Add(new LSL_Vector(0,0,0));
8950 res.Add(new LSL_Vector(0,0,0));
8951 res.Add(new LSL_Float(0.0));
8952 }
8953 }
8954 break;
8955
8956 case (int)ScriptBaseClass.PRIM_COLOR:
8957 if (remain < 1)
8958 return res;
8959
8960 face = (int)rules.GetLSLIntegerItem(idx++);
8961
8962 if (face == ScriptBaseClass.ALL_SIDES)
8963 {
8964 for (face = 0; face < 21; face++)
8965 {
8966 res.Add(new LSL_Vector(0,0,0));
8967 res.Add(new LSL_Float(0));
8968 }
8969 }
8970 else
8971 {
8972 res.Add(new LSL_Vector(0,0,0));
8973 res.Add(new LSL_Float(0));
8974 }
8975 break;
8976
8977 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8978 if (remain < 1)
8979 return res;
8980 face = (int)rules.GetLSLIntegerItem(idx++);
8981
8982 if (face == ScriptBaseClass.ALL_SIDES)
8983 {
8984 for (face = 0; face < 21; face++)
8985 {
8986 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8987 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8988 }
8989 }
8990 else
8991 {
8992 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8993 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8994 }
8995 break;
8996
8997 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8998 if (remain < 1)
8999 return res;
9000 face = (int)rules.GetLSLIntegerItem(idx++);
9001
9002 if (face == ScriptBaseClass.ALL_SIDES)
9003 {
9004 for (face = 0; face < 21; face++)
9005 {
9006 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9007 }
9008 }
9009 else
9010 {
9011 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9012 }
9013 break;
9014
9015 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
9016 res.Add(new LSL_Integer(0));
9017 res.Add(new LSL_Integer(0));// softness
9018 res.Add(new LSL_Float(0.0f)); // gravity
9019 res.Add(new LSL_Float(0.0f)); // friction
9020 res.Add(new LSL_Float(0.0f)); // wind
9021 res.Add(new LSL_Float(0.0f)); // tension
9022 res.Add(new LSL_Vector(0f,0f,0f));
9023 break;
9024
9025 case (int)ScriptBaseClass.PRIM_TEXGEN:
9026 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9027 if (remain < 1)
9028 return res;
9029 face = (int)rules.GetLSLIntegerItem(idx++);
9030
9031 if (face == ScriptBaseClass.ALL_SIDES)
9032 {
9033 for (face = 0; face < 21; face++)
9034 {
9035 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9036 }
9037 }
9038 else
9039 {
9040 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9041 }
9042 break;
9043
9044 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
9045 res.Add(new LSL_Integer(0));
9046 res.Add(new LSL_Vector(0f,0f,0f));
9047 res.Add(new LSL_Float(0f)); // intensity
9048 res.Add(new LSL_Float(0f)); // radius
9049 res.Add(new LSL_Float(0f)); // falloff
9050 break;
9051
9052 case (int)ScriptBaseClass.PRIM_GLOW:
9053 if (remain < 1)
9054 return res;
9055 face = (int)rules.GetLSLIntegerItem(idx++);
9056
9057 if (face == ScriptBaseClass.ALL_SIDES)
9058 {
9059 for (face = 0; face < 21; face++)
9060 {
9061 res.Add(new LSL_Float(0f));
9062 }
9063 }
9064 else
9065 {
9066 res.Add(new LSL_Float(0f));
9067 }
9068 break;
9069
9070 case (int)ScriptBaseClass.PRIM_TEXT:
9071 res.Add(new LSL_String(""));
9072 res.Add(new LSL_Vector(0f,0f,0f));
9073 res.Add(new LSL_Float(1.0f));
9074 break;
9075
9076 case (int)ScriptBaseClass.PRIM_NAME:
9077 res.Add(new LSL_String(avatar.Name));
9078 break;
9079
9080 case (int)ScriptBaseClass.PRIM_DESC:
9081 res.Add(new LSL_String(""));
9082 break;
9083
9084 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9085 Quaternion lrot = avatar.Rotation;
9086
9087 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9088 {
9089 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9090 }
9091 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9092 break;
9093
9094 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9095 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9096 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9097 lpos -= lsitOffset;
9098
9099 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9100 {
9101 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9102 }
9103 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9104 break;
9105
9106 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9107 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9108 return res;
9109 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9110 LSL_List new_rules = rules.GetSublist(idx, -1);
9111
9112 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9113 return res;
9114 }
9115 }
7930 return res; 9116 return res;
7931 } 9117 }
7932 9118
@@ -7970,13 +9156,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7970 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 9156 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7971 part.AbsolutePosition.Y, 9157 part.AbsolutePosition.Y,
7972 part.AbsolutePosition.Z); 9158 part.AbsolutePosition.Z);
7973 // For some reason, the part.AbsolutePosition.* values do not change if the
7974 // linkset is rotated; they always reflect the child prim's world position
7975 // as though the linkset is unrotated. This is incompatible behavior with SL's
7976 // implementation, so will break scripts imported from there (not to mention it
7977 // makes it more difficult to determine a child prim's actual inworld position).
7978 if (part.ParentID != 0)
7979 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7980 res.Add(v); 9159 res.Add(v);
7981 break; 9160 break;
7982 9161
@@ -8147,56 +9326,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8147 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 9326 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8148 if (remain < 1) 9327 if (remain < 1)
8149 return res; 9328 return res;
8150 9329 face = (int)rules.GetLSLIntegerItem(idx++);
8151 face=(int)rules.GetLSLIntegerItem(idx++);
8152 9330
8153 tex = part.Shape.Textures; 9331 tex = part.Shape.Textures;
9332 int shiny;
8154 if (face == ScriptBaseClass.ALL_SIDES) 9333 if (face == ScriptBaseClass.ALL_SIDES)
8155 { 9334 {
8156 for (face = 0; face < GetNumberOfSides(part); face++) 9335 for (face = 0; face < GetNumberOfSides(part); face++)
8157 { 9336 {
8158 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9337 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8159 // Convert Shininess to PRIM_SHINY_* 9338 if (shinyness == Shininess.High)
8160 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9339 {
8161 // PRIM_BUMP_* 9340 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8162 res.Add(new LSL_Integer((int)texface.Bump)); 9341 }
9342 else if (shinyness == Shininess.Medium)
9343 {
9344 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9345 }
9346 else if (shinyness == Shininess.Low)
9347 {
9348 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9349 }
9350 else
9351 {
9352 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9353 }
9354 res.Add(new LSL_Integer(shiny));
9355 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8163 } 9356 }
8164 } 9357 }
8165 else 9358 else
8166 { 9359 {
8167 if (face >= 0 && face < GetNumberOfSides(part)) 9360 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9361 if (shinyness == Shininess.High)
8168 { 9362 {
8169 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9363 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8170 // Convert Shininess to PRIM_SHINY_* 9364 }
8171 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9365 else if (shinyness == Shininess.Medium)
8172 // PRIM_BUMP_* 9366 {
8173 res.Add(new LSL_Integer((int)texface.Bump)); 9367 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9368 }
9369 else if (shinyness == Shininess.Low)
9370 {
9371 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9372 }
9373 else
9374 {
9375 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8174 } 9376 }
9377 res.Add(new LSL_Integer(shiny));
9378 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8175 } 9379 }
8176 break; 9380 break;
8177 9381
8178 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 9382 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8179 if (remain < 1) 9383 if (remain < 1)
8180 return res; 9384 return res;
8181 9385 face = (int)rules.GetLSLIntegerItem(idx++);
8182 face=(int)rules.GetLSLIntegerItem(idx++);
8183 9386
8184 tex = part.Shape.Textures; 9387 tex = part.Shape.Textures;
9388 int fullbright;
8185 if (face == ScriptBaseClass.ALL_SIDES) 9389 if (face == ScriptBaseClass.ALL_SIDES)
8186 { 9390 {
8187 for (face = 0; face < GetNumberOfSides(part); face++) 9391 for (face = 0; face < GetNumberOfSides(part); face++)
8188 { 9392 {
8189 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9393 if (tex.GetFace((uint)face).Fullbright == true)
8190 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9394 {
9395 fullbright = ScriptBaseClass.TRUE;
9396 }
9397 else
9398 {
9399 fullbright = ScriptBaseClass.FALSE;
9400 }
9401 res.Add(new LSL_Integer(fullbright));
8191 } 9402 }
8192 } 9403 }
8193 else 9404 else
8194 { 9405 {
8195 if (face >= 0 && face < GetNumberOfSides(part)) 9406 if (tex.GetFace((uint)face).Fullbright == true)
8196 { 9407 {
8197 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9408 fullbright = ScriptBaseClass.TRUE;
8198 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8199 } 9409 }
9410 else
9411 {
9412 fullbright = ScriptBaseClass.FALSE;
9413 }
9414 res.Add(new LSL_Integer(fullbright));
8200 } 9415 }
8201 break; 9416 break;
8202 9417
@@ -8218,27 +9433,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8218 break; 9433 break;
8219 9434
8220 case (int)ScriptBaseClass.PRIM_TEXGEN: 9435 case (int)ScriptBaseClass.PRIM_TEXGEN:
9436 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8221 if (remain < 1) 9437 if (remain < 1)
8222 return res; 9438 return res;
8223 9439 face = (int)rules.GetLSLIntegerItem(idx++);
8224 face=(int)rules.GetLSLIntegerItem(idx++);
8225 9440
8226 tex = part.Shape.Textures; 9441 tex = part.Shape.Textures;
8227 if (face == ScriptBaseClass.ALL_SIDES) 9442 if (face == ScriptBaseClass.ALL_SIDES)
8228 { 9443 {
8229 for (face = 0; face < GetNumberOfSides(part); face++) 9444 for (face = 0; face < GetNumberOfSides(part); face++)
8230 { 9445 {
8231 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9446 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8232 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9447 {
8233 res.Add(new LSL_Integer((uint)texgen >> 1)); 9448 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9449 }
9450 else
9451 {
9452 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9453 }
8234 } 9454 }
8235 } 9455 }
8236 else 9456 else
8237 { 9457 {
8238 if (face >= 0 && face < GetNumberOfSides(part)) 9458 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8239 { 9459 {
8240 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9460 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8241 res.Add(new LSL_Integer((uint)texgen >> 1)); 9461 }
9462 else
9463 {
9464 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8242 } 9465 }
8243 } 9466 }
8244 break; 9467 break;
@@ -8261,25 +9484,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8261 case (int)ScriptBaseClass.PRIM_GLOW: 9484 case (int)ScriptBaseClass.PRIM_GLOW:
8262 if (remain < 1) 9485 if (remain < 1)
8263 return res; 9486 return res;
8264 9487 face = (int)rules.GetLSLIntegerItem(idx++);
8265 face=(int)rules.GetLSLIntegerItem(idx++);
8266 9488
8267 tex = part.Shape.Textures; 9489 tex = part.Shape.Textures;
9490 float primglow;
8268 if (face == ScriptBaseClass.ALL_SIDES) 9491 if (face == ScriptBaseClass.ALL_SIDES)
8269 { 9492 {
8270 for (face = 0; face < GetNumberOfSides(part); face++) 9493 for (face = 0; face < GetNumberOfSides(part); face++)
8271 { 9494 {
8272 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9495 primglow = tex.GetFace((uint)face).Glow;
8273 res.Add(new LSL_Float(texface.Glow)); 9496 res.Add(new LSL_Float(primglow));
8274 } 9497 }
8275 } 9498 }
8276 else 9499 else
8277 { 9500 {
8278 if (face >= 0 && face < GetNumberOfSides(part)) 9501 primglow = tex.GetFace((uint)face).Glow;
8279 { 9502 res.Add(new LSL_Float(primglow));
8280 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8281 res.Add(new LSL_Float(texface.Glow));
8282 }
8283 } 9503 }
8284 break; 9504 break;
8285 9505
@@ -8291,18 +9511,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8291 textColor.B)); 9511 textColor.B));
8292 res.Add(new LSL_Float(textColor.A)); 9512 res.Add(new LSL_Float(textColor.A));
8293 break; 9513 break;
9514
8294 case (int)ScriptBaseClass.PRIM_NAME: 9515 case (int)ScriptBaseClass.PRIM_NAME:
8295 res.Add(new LSL_String(part.Name)); 9516 res.Add(new LSL_String(part.Name));
8296 break; 9517 break;
9518
8297 case (int)ScriptBaseClass.PRIM_DESC: 9519 case (int)ScriptBaseClass.PRIM_DESC:
8298 res.Add(new LSL_String(part.Description)); 9520 res.Add(new LSL_String(part.Description));
8299 break; 9521 break;
9522
8300 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9523 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8301 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9524 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8302 break; 9525 break;
9526
8303 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9527 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8304 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9528 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8305 break; 9529 break;
9530 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9531 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9532 return res;
9533 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9534 LSL_List new_rules = rules.GetSublist(idx, -1);
9535 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9536 res += tres;
9537 return res;
8306 case (int)ScriptBaseClass.PRIM_SLICE: 9538 case (int)ScriptBaseClass.PRIM_SLICE:
8307 PrimType prim_type = part.GetPrimType(); 9539 PrimType prim_type = part.GetPrimType();
8308 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING); 9540 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING);
@@ -8904,8 +10136,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8904 // The function returns an ordered list 10136 // The function returns an ordered list
8905 // representing the tokens found in the supplied 10137 // representing the tokens found in the supplied
8906 // sources string. If two successive tokenizers 10138 // sources string. If two successive tokenizers
8907 // are encountered, then a NULL entry is added 10139 // are encountered, then a null-string entry is
8908 // to the list. 10140 // added to the list.
8909 // 10141 //
8910 // It is a precondition that the source and 10142 // It is a precondition that the source and
8911 // toekizer lisst are non-null. If they are null, 10143 // toekizer lisst are non-null. If they are null,
@@ -8913,7 +10145,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8913 // while their lengths are being determined. 10145 // while their lengths are being determined.
8914 // 10146 //
8915 // A small amount of working memoryis required 10147 // A small amount of working memoryis required
8916 // of approximately 8*#tokenizers. 10148 // of approximately 8*#tokenizers + 8*srcstrlen.
8917 // 10149 //
8918 // There are many ways in which this function 10150 // There are many ways in which this function
8919 // can be implemented, this implementation is 10151 // can be implemented, this implementation is
@@ -8929,155 +10161,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8929 // and eliminates redundant tokenizers as soon 10161 // and eliminates redundant tokenizers as soon
8930 // as is possible. 10162 // as is possible.
8931 // 10163 //
8932 // The implementation tries to avoid any copying 10164 // The implementation tries to minimize temporary
8933 // of arrays or other objects. 10165 // garbage generation.
8934 // </remarks> 10166 // </remarks>
8935 10167
8936 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 10168 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8937 { 10169 {
8938 int beginning = 0; 10170 return ParseString2List(src, separators, spacers, true);
8939 int srclen = src.Length; 10171 }
8940 int seplen = separators.Length;
8941 object[] separray = separators.Data;
8942 int spclen = spacers.Length;
8943 object[] spcarray = spacers.Data;
8944 int mlen = seplen+spclen;
8945
8946 int[] offset = new int[mlen+1];
8947 bool[] active = new bool[mlen];
8948
8949 int best;
8950 int j;
8951
8952 // Initial capacity reduces resize cost
8953 10172
8954 LSL_List tokens = new LSL_List(); 10173 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
10174 {
10175 int srclen = src.Length;
10176 int seplen = separators.Length;
10177 object[] separray = separators.Data;
10178 int spclen = spacers.Length;
10179 object[] spcarray = spacers.Data;
10180 int dellen = 0;
10181 string[] delarray = new string[seplen+spclen];
8955 10182
8956 // All entries are initially valid 10183 int outlen = 0;
10184 string[] outarray = new string[srclen*2+1];
8957 10185
8958 for (int i = 0; i < mlen; i++) 10186 int i, j;
8959 active[i] = true; 10187 string d;
8960 10188
8961 offset[mlen] = srclen; 10189 m_host.AddScriptLPS(1);
8962 10190
8963 while (beginning < srclen) 10191 /*
10192 * Convert separator and spacer lists to C# strings.
10193 * Also filter out null strings so we don't hang.
10194 */
10195 for (i = 0; i < seplen; i ++)
8964 { 10196 {
10197 d = separray[i].ToString();
10198 if (d.Length > 0)
10199 {
10200 delarray[dellen++] = d;
10201 }
10202 }
10203 seplen = dellen;
8965 10204
8966 best = mlen; // as bad as it gets 10205 for (i = 0; i < spclen; i ++)
10206 {
10207 d = spcarray[i].ToString();
10208 if (d.Length > 0)
10209 {
10210 delarray[dellen++] = d;
10211 }
10212 }
8967 10213
8968 // Scan for separators 10214 /*
10215 * Scan through source string from beginning to end.
10216 */
10217 for (i = 0;;)
10218 {
8969 10219
8970 for (j = 0; j < seplen; j++) 10220 /*
10221 * Find earliest delimeter in src starting at i (if any).
10222 */
10223 int earliestDel = -1;
10224 int earliestSrc = srclen;
10225 string earliestStr = null;
10226 for (j = 0; j < dellen; j ++)
8971 { 10227 {
8972 if (separray[j].ToString() == String.Empty) 10228 d = delarray[j];
8973 active[j] = false; 10229 if (d != null)
8974
8975 if (active[j])
8976 { 10230 {
8977 // scan all of the markers 10231 int index = src.IndexOf(d, i);
8978 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10232 if (index < 0)
8979 { 10233 {
8980 // not present at all 10234 delarray[j] = null; // delim nowhere in src, don't check it anymore
8981 active[j] = false;
8982 } 10235 }
8983 else 10236 else if (index < earliestSrc)
8984 { 10237 {
8985 // present and correct 10238 earliestSrc = index; // where delimeter starts in source string
8986 if (offset[j] < offset[best]) 10239 earliestDel = j; // where delimeter is in delarray[]
8987 { 10240 earliestStr = d; // the delimeter string from delarray[]
8988 // closest so far 10241 if (index == i) break; // can't do any better than found at beg of string
8989 best = j;
8990 if (offset[best] == beginning)
8991 break;
8992 }
8993 } 10242 }
8994 } 10243 }
8995 } 10244 }
8996 10245
8997 // Scan for spacers 10246 /*
8998 10247 * Output source string starting at i through start of earliest delimeter.
8999 if (offset[best] != beginning) 10248 */
10249 if (keepNulls || (earliestSrc > i))
9000 { 10250 {
9001 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10251 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9002 {
9003 if (spcarray[j-seplen].ToString() == String.Empty)
9004 active[j] = false;
9005
9006 if (active[j])
9007 {
9008 // scan all of the markers
9009 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9010 {
9011 // not present at all
9012 active[j] = false;
9013 }
9014 else
9015 {
9016 // present and correct
9017 if (offset[j] < offset[best])
9018 {
9019 // closest so far
9020 best = j;
9021 }
9022 }
9023 }
9024 }
9025 } 10252 }
9026 10253
9027 // This is the normal exit from the scanning loop 10254 /*
10255 * If no delimeter found at or after i, we're done scanning.
10256 */
10257 if (earliestDel < 0) break;
9028 10258
9029 if (best == mlen) 10259 /*
10260 * If delimeter was a spacer, output the spacer.
10261 */
10262 if (earliestDel >= seplen)
9030 { 10263 {
9031 // no markers were found on this pass 10264 outarray[outlen++] = earliestStr;
9032 // so we're pretty much done
9033 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9034 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9035 break;
9036 } 10265 }
9037 10266
9038 // Otherwise we just add the newly delimited token 10267 /*
9039 // and recalculate where the search should continue. 10268 * Look at rest of src string following delimeter.
9040 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10269 */
9041 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10270 i = earliestSrc + earliestStr.Length;
9042
9043 if (best < seplen)
9044 {
9045 beginning = offset[best] + (separray[best].ToString()).Length;
9046 }
9047 else
9048 {
9049 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9050 string str = spcarray[best - seplen].ToString();
9051 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9052 tokens.Add(new LSL_String(str));
9053 }
9054 } 10271 }
9055 10272
9056 // This an awkward an not very intuitive boundary case. If the 10273 /*
9057 // last substring is a tokenizer, then there is an implied trailing 10274 * Make up an exact-sized output array suitable for an LSL_List object.
9058 // null list entry. Hopefully the single comparison will not be too 10275 */
9059 // arduous. Alternatively the 'break' could be replced with a return 10276 object[] outlist = new object[outlen];
9060 // but that's shabby programming. 10277 for (i = 0; i < outlen; i ++)
9061
9062 if ((beginning == srclen) && (keepNulls))
9063 { 10278 {
9064 if (srclen != 0) 10279 outlist[i] = new LSL_String(outarray[i]);
9065 tokens.Add(new LSL_String(""));
9066 } 10280 }
9067 10281 return new LSL_List(outlist);
9068 return tokens;
9069 }
9070
9071 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9072 {
9073 m_host.AddScriptLPS(1);
9074 return this.ParseString(src, separators, spacers, false);
9075 }
9076
9077 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9078 {
9079 m_host.AddScriptLPS(1);
9080 return this.ParseString(src, separators, spacers, true);
9081 } 10282 }
9082 10283
9083 public LSL_Integer llGetObjectPermMask(int mask) 10284 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9172,6 +10373,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9172 case 4: 10373 case 4:
9173 return (int)item.NextPermissions; 10374 return (int)item.NextPermissions;
9174 } 10375 }
10376 m_host.TaskInventory.LockItemsForRead(false);
9175 10377
9176 return -1; 10378 return -1;
9177 } 10379 }
@@ -9362,9 +10564,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9362 { 10564 {
9363 try 10565 try
9364 { 10566 {
10567 /*
9365 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10568 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9366 if (obj != null) 10569 if (obj != null)
9367 return (double)obj.GetMass(); 10570 return (double)obj.GetMass();
10571 */
10572 // return total object mass
10573 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10574 if (obj != null)
10575 return obj.GetMass();
10576
9368 // the object is null so the key is for an avatar 10577 // the object is null so the key is for an avatar
9369 ScenePresence avatar = World.GetScenePresence(key); 10578 ScenePresence avatar = World.GetScenePresence(key);
9370 if (avatar != null) 10579 if (avatar != null)
@@ -9384,7 +10593,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9384 } 10593 }
9385 10594
9386 /// <summary> 10595 /// <summary>
9387 /// illListReplaceList removes the sub-list defined by the inclusive indices 10596 /// llListReplaceList removes the sub-list defined by the inclusive indices
9388 /// start and end and inserts the src list in its place. The inclusive 10597 /// start and end and inserts the src list in its place. The inclusive
9389 /// nature of the indices means that at least one element must be deleted 10598 /// nature of the indices means that at least one element must be deleted
9390 /// if the indices are within the bounds of the existing list. I.e. 2,2 10599 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9441,16 +10650,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9441 // based upon end. Note that if end exceeds the upper 10650 // based upon end. Note that if end exceeds the upper
9442 // bound in this case, the entire destination list 10651 // bound in this case, the entire destination list
9443 // is removed. 10652 // is removed.
9444 else 10653 else if (start == 0)
9445 { 10654 {
9446 if (end + 1 < dest.Length) 10655 if (end + 1 < dest.Length)
9447 {
9448 return src + dest.GetSublist(end + 1, -1); 10656 return src + dest.GetSublist(end + 1, -1);
9449 }
9450 else 10657 else
9451 {
9452 return src; 10658 return src;
9453 } 10659 }
10660 else // Start < 0
10661 {
10662 if (end + 1 < dest.Length)
10663 return dest.GetSublist(end + 1, -1);
10664 else
10665 return new LSL_List();
9454 } 10666 }
9455 } 10667 }
9456 // Finally, if start > end, we strip away a prefix and 10668 // Finally, if start > end, we strip away a prefix and
@@ -9501,17 +10713,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9501 int width = 0; 10713 int width = 0;
9502 int height = 0; 10714 int height = 0;
9503 10715
9504 ParcelMediaCommandEnum? commandToSend = null; 10716 uint commandToSend = 0;
9505 float time = 0.0f; // default is from start 10717 float time = 0.0f; // default is from start
9506 10718
9507 ScenePresence presence = null; 10719 ScenePresence presence = null;
9508 10720
9509 for (int i = 0; i < commandList.Data.Length; i++) 10721 for (int i = 0; i < commandList.Data.Length; i++)
9510 { 10722 {
9511 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10723 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9512 switch (command) 10724 switch (command)
9513 { 10725 {
9514 case ParcelMediaCommandEnum.Agent: 10726 case (uint)ParcelMediaCommandEnum.Agent:
9515 // we send only to one agent 10727 // we send only to one agent
9516 if ((i + 1) < commandList.Length) 10728 if ((i + 1) < commandList.Length)
9517 { 10729 {
@@ -9528,25 +10740,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9528 } 10740 }
9529 break; 10741 break;
9530 10742
9531 case ParcelMediaCommandEnum.Loop: 10743 case (uint)ParcelMediaCommandEnum.Loop:
9532 loop = 1; 10744 loop = 1;
9533 commandToSend = command; 10745 commandToSend = command;
9534 update = true; //need to send the media update packet to set looping 10746 update = true; //need to send the media update packet to set looping
9535 break; 10747 break;
9536 10748
9537 case ParcelMediaCommandEnum.Play: 10749 case (uint)ParcelMediaCommandEnum.Play:
9538 loop = 0; 10750 loop = 0;
9539 commandToSend = command; 10751 commandToSend = command;
9540 update = true; //need to send the media update packet to make sure it doesn't loop 10752 update = true; //need to send the media update packet to make sure it doesn't loop
9541 break; 10753 break;
9542 10754
9543 case ParcelMediaCommandEnum.Pause: 10755 case (uint)ParcelMediaCommandEnum.Pause:
9544 case ParcelMediaCommandEnum.Stop: 10756 case (uint)ParcelMediaCommandEnum.Stop:
9545 case ParcelMediaCommandEnum.Unload: 10757 case (uint)ParcelMediaCommandEnum.Unload:
9546 commandToSend = command; 10758 commandToSend = command;
9547 break; 10759 break;
9548 10760
9549 case ParcelMediaCommandEnum.Url: 10761 case (uint)ParcelMediaCommandEnum.Url:
9550 if ((i + 1) < commandList.Length) 10762 if ((i + 1) < commandList.Length)
9551 { 10763 {
9552 if (commandList.Data[i + 1] is LSL_String) 10764 if (commandList.Data[i + 1] is LSL_String)
@@ -9559,7 +10771,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9559 } 10771 }
9560 break; 10772 break;
9561 10773
9562 case ParcelMediaCommandEnum.Texture: 10774 case (uint)ParcelMediaCommandEnum.Texture:
9563 if ((i + 1) < commandList.Length) 10775 if ((i + 1) < commandList.Length)
9564 { 10776 {
9565 if (commandList.Data[i + 1] is LSL_String) 10777 if (commandList.Data[i + 1] is LSL_String)
@@ -9572,7 +10784,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9572 } 10784 }
9573 break; 10785 break;
9574 10786
9575 case ParcelMediaCommandEnum.Time: 10787 case (uint)ParcelMediaCommandEnum.Time:
9576 if ((i + 1) < commandList.Length) 10788 if ((i + 1) < commandList.Length)
9577 { 10789 {
9578 if (commandList.Data[i + 1] is LSL_Float) 10790 if (commandList.Data[i + 1] is LSL_Float)
@@ -9584,7 +10796,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9584 } 10796 }
9585 break; 10797 break;
9586 10798
9587 case ParcelMediaCommandEnum.AutoAlign: 10799 case (uint)ParcelMediaCommandEnum.AutoAlign:
9588 if ((i + 1) < commandList.Length) 10800 if ((i + 1) < commandList.Length)
9589 { 10801 {
9590 if (commandList.Data[i + 1] is LSL_Integer) 10802 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9598,7 +10810,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9598 } 10810 }
9599 break; 10811 break;
9600 10812
9601 case ParcelMediaCommandEnum.Type: 10813 case (uint)ParcelMediaCommandEnum.Type:
9602 if ((i + 1) < commandList.Length) 10814 if ((i + 1) < commandList.Length)
9603 { 10815 {
9604 if (commandList.Data[i + 1] is LSL_String) 10816 if (commandList.Data[i + 1] is LSL_String)
@@ -9611,7 +10823,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9611 } 10823 }
9612 break; 10824 break;
9613 10825
9614 case ParcelMediaCommandEnum.Desc: 10826 case (uint)ParcelMediaCommandEnum.Desc:
9615 if ((i + 1) < commandList.Length) 10827 if ((i + 1) < commandList.Length)
9616 { 10828 {
9617 if (commandList.Data[i + 1] is LSL_String) 10829 if (commandList.Data[i + 1] is LSL_String)
@@ -9624,7 +10836,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9624 } 10836 }
9625 break; 10837 break;
9626 10838
9627 case ParcelMediaCommandEnum.Size: 10839 case (uint)ParcelMediaCommandEnum.Size:
9628 if ((i + 2) < commandList.Length) 10840 if ((i + 2) < commandList.Length)
9629 { 10841 {
9630 if (commandList.Data[i + 1] is LSL_Integer) 10842 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9694,7 +10906,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9694 } 10906 }
9695 } 10907 }
9696 10908
9697 if (commandToSend != null) 10909 if (commandToSend != 0)
9698 { 10910 {
9699 // the commandList contained a start/stop/... command, too 10911 // the commandList contained a start/stop/... command, too
9700 if (presence == null) 10912 if (presence == null)
@@ -9731,7 +10943,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9731 10943
9732 if (aList.Data[i] != null) 10944 if (aList.Data[i] != null)
9733 { 10945 {
9734 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10946 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9735 { 10947 {
9736 case ParcelMediaCommandEnum.Url: 10948 case ParcelMediaCommandEnum.Url:
9737 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10949 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9788,15 +11000,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9788 11000
9789 if (quick_pay_buttons.Data.Length < 4) 11001 if (quick_pay_buttons.Data.Length < 4)
9790 { 11002 {
9791 LSLError("List must have at least 4 elements"); 11003 int x;
9792 return; 11004 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
11005 {
11006 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
11007 }
9793 } 11008 }
9794 m_host.ParentGroup.RootPart.PayPrice[0]=price; 11009 int[] nPrice = new int[5];
9795 11010 nPrice[0] = price;
9796 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 11011 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9797 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 11012 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9798 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 11013 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9799 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 11014 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
11015 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9800 m_host.ParentGroup.HasGroupChanged = true; 11016 m_host.ParentGroup.HasGroupChanged = true;
9801 } 11017 }
9802 11018
@@ -9813,7 +11029,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9813 return new LSL_Vector(); 11029 return new LSL_Vector();
9814 } 11030 }
9815 11031
9816 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11032// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11033 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9817 if (presence != null) 11034 if (presence != null)
9818 { 11035 {
9819 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 11036 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9835,7 +11052,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9835 return new LSL_Rotation(); 11052 return new LSL_Rotation();
9836 } 11053 }
9837 11054
9838 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11055// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11056 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9839 if (presence != null) 11057 if (presence != null)
9840 { 11058 {
9841 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 11059 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9895,14 +11113,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9895 { 11113 {
9896 m_host.AddScriptLPS(1); 11114 m_host.AddScriptLPS(1);
9897 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 11115 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9898 if (detectedParams == null) return; // only works on the first detected avatar 11116 if (detectedParams == null)
9899 11117 {
11118 if (m_host.ParentGroup.IsAttachment == true)
11119 {
11120 detectedParams = new DetectParams();
11121 detectedParams.Key = m_host.OwnerID;
11122 }
11123 else
11124 {
11125 return;
11126 }
11127 }
11128
9900 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 11129 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9901 if (avatar != null) 11130 if (avatar != null)
9902 { 11131 {
9903 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 11132 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9904 simname, pos, lookAt); 11133 simname, pos, lookAt);
9905 } 11134 }
11135
9906 ScriptSleep(1000); 11136 ScriptSleep(1000);
9907 } 11137 }
9908 11138
@@ -10026,12 +11256,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10026 11256
10027 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11257 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10028 object[] data = rules.Data; 11258 object[] data = rules.Data;
10029 for (int i = 0; i < data.Length; ++i) { 11259 for (int i = 0; i < data.Length; ++i)
11260 {
10030 int type = Convert.ToInt32(data[i++].ToString()); 11261 int type = Convert.ToInt32(data[i++].ToString());
10031 if (i >= data.Length) break; // odd number of entries => ignore the last 11262 if (i >= data.Length) break; // odd number of entries => ignore the last
10032 11263
10033 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11264 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10034 switch (type) { 11265 switch (type)
11266 {
10035 case ScriptBaseClass.CAMERA_FOCUS: 11267 case ScriptBaseClass.CAMERA_FOCUS:
10036 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11268 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10037 case ScriptBaseClass.CAMERA_POSITION: 11269 case ScriptBaseClass.CAMERA_POSITION:
@@ -10137,19 +11369,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10137 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11369 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10138 { 11370 {
10139 m_host.AddScriptLPS(1); 11371 m_host.AddScriptLPS(1);
10140 string ret = String.Empty; 11372
10141 string src1 = llBase64ToString(str1); 11373 if (str1 == String.Empty)
10142 string src2 = llBase64ToString(str2); 11374 return String.Empty;
10143 int c = 0; 11375 if (str2 == String.Empty)
10144 for (int i = 0; i < src1.Length; i++) 11376 return str1;
11377
11378 int len = str2.Length;
11379 if ((len % 4) != 0) // LL is EVIL!!!!
10145 { 11380 {
10146 ret += (char) (src1[i] ^ src2[c]); 11381 while (str2.EndsWith("="))
11382 str2 = str2.Substring(0, str2.Length - 1);
10147 11383
10148 c++; 11384 len = str2.Length;
10149 if (c >= src2.Length) 11385 int mod = len % 4;
10150 c = 0; 11386
11387 if (mod == 1)
11388 str2 = str2.Substring(0, str2.Length - 1);
11389 else if (mod == 2)
11390 str2 += "==";
11391 else if (mod == 3)
11392 str2 += "=";
10151 } 11393 }
10152 return llStringToBase64(ret); 11394
11395 byte[] data1;
11396 byte[] data2;
11397 try
11398 {
11399 data1 = Convert.FromBase64String(str1);
11400 data2 = Convert.FromBase64String(str2);
11401 }
11402 catch (Exception)
11403 {
11404 return new LSL_String(String.Empty);
11405 }
11406
11407 byte[] d2 = new Byte[data1.Length];
11408 int pos = 0;
11409
11410 if (data1.Length <= data2.Length)
11411 {
11412 Array.Copy(data2, 0, d2, 0, data1.Length);
11413 }
11414 else
11415 {
11416 while (pos < data1.Length)
11417 {
11418 len = data1.Length - pos;
11419 if (len > data2.Length)
11420 len = data2.Length;
11421
11422 Array.Copy(data2, 0, d2, pos, len);
11423 pos += len;
11424 }
11425 }
11426
11427 for (pos = 0 ; pos < data1.Length ; pos++ )
11428 data1[pos] ^= d2[pos];
11429
11430 return Convert.ToBase64String(data1);
10153 } 11431 }
10154 11432
10155 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11433 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10202,16 +11480,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10202 if (userAgent != null) 11480 if (userAgent != null)
10203 httpHeaders["User-Agent"] = userAgent; 11481 httpHeaders["User-Agent"] = userAgent;
10204 11482
11483 // See if the URL contains any header hacks
11484 string[] urlParts = url.Split(new char[] {'\n'});
11485 if (urlParts.Length > 1)
11486 {
11487 // Iterate the passed headers and parse them
11488 for (int i = 1 ; i < urlParts.Length ; i++ )
11489 {
11490 // The rest of those would be added to the body in SL.
11491 // Let's not do that.
11492 if (urlParts[i] == String.Empty)
11493 break;
11494
11495 // See if this could be a valid header
11496 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11497 if (headerParts.Length != 2)
11498 continue;
11499
11500 string headerName = headerParts[0].Trim();
11501 string headerValue = headerParts[1].Trim();
11502
11503 // Filter out headers that could be used to abuse
11504 // another system or cloak the request
11505 if (headerName.ToLower() == "x-secondlife-shard" ||
11506 headerName.ToLower() == "x-secondlife-object-name" ||
11507 headerName.ToLower() == "x-secondlife-object-key" ||
11508 headerName.ToLower() == "x-secondlife-region" ||
11509 headerName.ToLower() == "x-secondlife-local-position" ||
11510 headerName.ToLower() == "x-secondlife-local-velocity" ||
11511 headerName.ToLower() == "x-secondlife-local-rotation" ||
11512 headerName.ToLower() == "x-secondlife-owner-name" ||
11513 headerName.ToLower() == "x-secondlife-owner-key" ||
11514 headerName.ToLower() == "connection" ||
11515 headerName.ToLower() == "content-length" ||
11516 headerName.ToLower() == "from" ||
11517 headerName.ToLower() == "host" ||
11518 headerName.ToLower() == "proxy-authorization" ||
11519 headerName.ToLower() == "referer" ||
11520 headerName.ToLower() == "trailer" ||
11521 headerName.ToLower() == "transfer-encoding" ||
11522 headerName.ToLower() == "via" ||
11523 headerName.ToLower() == "authorization")
11524 continue;
11525
11526 httpHeaders[headerName] = headerValue;
11527 }
11528
11529 // Finally, strip any protocol specifier from the URL
11530 url = urlParts[0].Trim();
11531 int idx = url.IndexOf(" HTTP/");
11532 if (idx != -1)
11533 url = url.Substring(0, idx);
11534 }
11535
10205 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11536 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10206 Regex r = new Regex(authregex); 11537 Regex r = new Regex(authregex);
10207 int[] gnums = r.GetGroupNumbers(); 11538 int[] gnums = r.GetGroupNumbers();
10208 Match m = r.Match(url); 11539 Match m = r.Match(url);
10209 if (m.Success) { 11540 if (m.Success)
10210 for (int i = 1; i < gnums.Length; i++) { 11541 {
11542 for (int i = 1; i < gnums.Length; i++)
11543 {
10211 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11544 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10212 //CaptureCollection cc = g.Captures; 11545 //CaptureCollection cc = g.Captures;
10213 } 11546 }
10214 if (m.Groups.Count == 5) { 11547 if (m.Groups.Count == 5)
11548 {
10215 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11549 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10216 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11550 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10217 } 11551 }
@@ -10414,6 +11748,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10414 11748
10415 LSL_List ret = new LSL_List(); 11749 LSL_List ret = new LSL_List();
10416 UUID key = new UUID(); 11750 UUID key = new UUID();
11751
11752
10417 if (UUID.TryParse(id, out key)) 11753 if (UUID.TryParse(id, out key))
10418 { 11754 {
10419 ScenePresence av = World.GetScenePresence(key); 11755 ScenePresence av = World.GetScenePresence(key);
@@ -10431,13 +11767,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10431 ret.Add(new LSL_String("")); 11767 ret.Add(new LSL_String(""));
10432 break; 11768 break;
10433 case ScriptBaseClass.OBJECT_POS: 11769 case ScriptBaseClass.OBJECT_POS:
10434 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11770 Vector3 avpos;
11771
11772 if (av.ParentID != 0 && av.ParentPart != null)
11773 {
11774 avpos = av.OffsetPosition;
11775
11776 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11777 avpos -= sitOffset;
11778
11779 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11780 }
11781 else
11782 avpos = av.AbsolutePosition;
11783
11784 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10435 break; 11785 break;
10436 case ScriptBaseClass.OBJECT_ROT: 11786 case ScriptBaseClass.OBJECT_ROT:
10437 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11787 Quaternion avrot = av.Rotation;
11788 if (av.ParentID != 0 && av.ParentPart != null)
11789 {
11790 avrot = av.ParentPart.GetWorldRotation() * avrot;
11791 }
11792 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10438 break; 11793 break;
10439 case ScriptBaseClass.OBJECT_VELOCITY: 11794 case ScriptBaseClass.OBJECT_VELOCITY:
10440 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11795 Vector3 avvel = av.Velocity;
11796 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10441 break; 11797 break;
10442 case ScriptBaseClass.OBJECT_OWNER: 11798 case ScriptBaseClass.OBJECT_OWNER:
10443 ret.Add(new LSL_String(id)); 11799 ret.Add(new LSL_String(id));
@@ -10493,11 +11849,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10493 case ScriptBaseClass.OBJECT_NAME: 11849 case ScriptBaseClass.OBJECT_NAME:
10494 ret.Add(new LSL_String(obj.Name)); 11850 ret.Add(new LSL_String(obj.Name));
10495 break; 11851 break;
10496 case ScriptBaseClass.OBJECT_DESC: 11852 case ScriptBaseClass.OBJECT_DESC:
10497 ret.Add(new LSL_String(obj.Description)); 11853 ret.Add(new LSL_String(obj.Description));
10498 break; 11854 break;
10499 case ScriptBaseClass.OBJECT_POS: 11855 case ScriptBaseClass.OBJECT_POS:
10500 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11856 Vector3 opos = obj.AbsolutePosition;
11857 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10501 break; 11858 break;
10502 case ScriptBaseClass.OBJECT_ROT: 11859 case ScriptBaseClass.OBJECT_ROT:
10503 { 11860 {
@@ -10547,9 +11904,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10547 // The value returned in SL for normal prims is prim count 11904 // The value returned in SL for normal prims is prim count
10548 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11905 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10549 break; 11906 break;
10550 // The following 3 costs I have intentionaly coded to return zero. They are part of 11907
10551 // "Land Impact" calculations. These calculations are probably not applicable 11908 // costs below may need to be diferent for root parts, need to check
10552 // to OpenSim and are not yet complete in SL
10553 case ScriptBaseClass.OBJECT_SERVER_COST: 11909 case ScriptBaseClass.OBJECT_SERVER_COST:
10554 // The linden calculation is here 11910 // The linden calculation is here
10555 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11911 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10557,16 +11913,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10557 ret.Add(new LSL_Float(0)); 11913 ret.Add(new LSL_Float(0));
10558 break; 11914 break;
10559 case ScriptBaseClass.OBJECT_STREAMING_COST: 11915 case ScriptBaseClass.OBJECT_STREAMING_COST:
10560 // The linden calculation is here 11916 // The value returned in SL for normal prims is prim count * 0.06
10561 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11917 ret.Add(new LSL_Float(obj.StreamingCost));
10562 // The value returned in SL for normal prims looks like the prim count * 0.06
10563 ret.Add(new LSL_Float(0));
10564 break; 11918 break;
10565 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11919 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10566 // The linden calculation is here 11920 // The value returned in SL for normal prims is prim count
10567 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11921 ret.Add(new LSL_Float(obj.PhysicsCost));
10568 // The value returned in SL for normal prims looks like the prim count
10569 ret.Add(new LSL_Float(0));
10570 break; 11922 break;
10571 default: 11923 default:
10572 // Invalid or unhandled constant. 11924 // Invalid or unhandled constant.
@@ -10764,15 +12116,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10764 return GetLinkPrimitiveParams(obj, rules); 12116 return GetLinkPrimitiveParams(obj, rules);
10765 } 12117 }
10766 12118
10767 public void print(string str) 12119 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10768 { 12120 {
10769 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 12121 List<SceneObjectPart> parts = GetLinkParts(link);
10770 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 12122 if (parts.Count < 1)
10771 if (ossl != null) 12123 return 0;
10772 { 12124
10773 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12125 return GetNumberOfSides(parts[0]);
10774 m_log.Info("LSL print():" + str);
10775 }
10776 } 12126 }
10777 12127
10778 private string Name2Username(string name) 12128 private string Name2Username(string name)
@@ -10817,7 +12167,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10817 12167
10818 return rq.ToString(); 12168 return rq.ToString();
10819 } 12169 }
10820 12170/*
12171 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12172 {
12173 m_SayShoutCount = 0;
12174 }
12175*/
10821 private struct Tri 12176 private struct Tri
10822 { 12177 {
10823 public Vector3 p1; 12178 public Vector3 p1;
@@ -10957,9 +12312,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10957 12312
10958 ContactResult result = new ContactResult (); 12313 ContactResult result = new ContactResult ();
10959 result.ConsumerID = group.LocalId; 12314 result.ConsumerID = group.LocalId;
10960 result.Depth = intersection.distance; 12315// result.Depth = intersection.distance;
10961 result.Normal = intersection.normal; 12316 result.Normal = intersection.normal;
10962 result.Pos = intersection.ipoint; 12317 result.Pos = intersection.ipoint;
12318 result.Depth = Vector3.Mag(rayStart - result.Pos);
10963 12319
10964 contacts.Add(result); 12320 contacts.Add(result);
10965 }); 12321 });
@@ -11092,6 +12448,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11092 12448
11093 return contacts[0]; 12449 return contacts[0];
11094 } 12450 }
12451/*
12452 // not done:
12453 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12454 {
12455 ContactResult[] contacts = null;
12456 World.ForEachSOG(delegate(SceneObjectGroup group)
12457 {
12458 if (m_host.ParentGroup == group)
12459 return;
12460
12461 if (group.IsAttachment)
12462 return;
12463
12464 if(group.RootPart.PhysActor != null)
12465 return;
12466
12467 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12468 });
12469 return contacts;
12470 }
12471*/
11095 12472
11096 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12473 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11097 { 12474 {
@@ -11133,32 +12510,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11133 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12510 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11134 12511
11135 12512
11136 if (checkTerrain) 12513 if (World.SuportsRayCastFiltered())
11137 { 12514 {
11138 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12515 if (dist == 0)
11139 if (groundContact != null) 12516 return list;
11140 results.Add((ContactResult)groundContact);
11141 }
11142 12517
11143 if (checkAgents) 12518 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11144 { 12519 if (checkTerrain)
11145 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12520 rayfilter |= RayFilterFlags.land;
11146 foreach (ContactResult r in agentHits) 12521// if (checkAgents)
11147 results.Add(r); 12522// rayfilter |= RayFilterFlags.agent;
11148 } 12523 if (checkPhysical)
12524 rayfilter |= RayFilterFlags.physical;
12525 if (checkNonPhysical)
12526 rayfilter |= RayFilterFlags.nonphysical;
12527 if (detectPhantom)
12528 rayfilter |= RayFilterFlags.LSLPhanton;
12529
12530 Vector3 direction = dir * ( 1/dist);
11149 12531
11150 if (checkPhysical || checkNonPhysical || detectPhantom) 12532 if(rayfilter == 0)
12533 {
12534 list.Add(new LSL_Integer(0));
12535 return list;
12536 }
12537
12538 // get some more contacts to sort ???
12539 int physcount = 4 * count;
12540 if (physcount > 20)
12541 physcount = 20;
12542
12543 object physresults;
12544 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12545
12546 if (physresults == null)
12547 {
12548 list.Add(new LSL_Integer(-3)); // timeout error
12549 return list;
12550 }
12551
12552 results = (List<ContactResult>)physresults;
12553
12554 // for now physics doesn't detect sitted avatars so do it outside physics
12555 if (checkAgents)
12556 {
12557 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12558 foreach (ContactResult r in agentHits)
12559 results.Add(r);
12560 }
12561
12562 // TODO: Replace this with a better solution. ObjectIntersection can only
12563 // detect nonphysical phantoms. They are detected by virtue of being
12564 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12565 // physicsl phantoms as done by the physics scene
12566 // We don't want anything else but phantoms here.
12567 if (detectPhantom)
12568 {
12569 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12570 foreach (ContactResult r in objectHits)
12571 results.Add(r);
12572 }
12573 }
12574 else
11151 { 12575 {
11152 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12576 if (checkTerrain)
11153 foreach (ContactResult r in objectHits) 12577 {
11154 results.Add(r); 12578 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12579 if (groundContact != null)
12580 results.Add((ContactResult)groundContact);
12581 }
12582
12583 if (checkAgents)
12584 {
12585 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12586 foreach (ContactResult r in agentHits)
12587 results.Add(r);
12588 }
12589
12590 if (checkPhysical || checkNonPhysical || detectPhantom)
12591 {
12592 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12593 foreach (ContactResult r in objectHits)
12594 results.Add(r);
12595 }
11155 } 12596 }
11156 12597
11157 results.Sort(delegate(ContactResult a, ContactResult b) 12598 results.Sort(delegate(ContactResult a, ContactResult b)
11158 { 12599 {
11159 return a.Depth.CompareTo(b.Depth); 12600 return a.Depth.CompareTo(b.Depth);
11160 }); 12601 });
11161 12602
11162 int values = 0; 12603 int values = 0;
11163 SceneObjectGroup thisgrp = m_host.ParentGroup; 12604 SceneObjectGroup thisgrp = m_host.ParentGroup;
11164 12605
@@ -11251,7 +12692,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11251 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12692 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11252 if (!isAccount) return 0; 12693 if (!isAccount) return 0;
11253 if (estate.HasAccess(id)) return 1; 12694 if (estate.HasAccess(id)) return 1;
11254 if (estate.IsBanned(id)) 12695 if (estate.IsBanned(id, World.GetUserFlags(id)))
11255 estate.RemoveBan(id); 12696 estate.RemoveBan(id);
11256 estate.AddEstateUser(id); 12697 estate.AddEstateUser(id);
11257 break; 12698 break;
@@ -11270,14 +12711,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11270 break; 12711 break;
11271 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12712 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11272 if (!isAccount) return 0; 12713 if (!isAccount) return 0;
11273 if (estate.IsBanned(id)) return 1; 12714 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11274 EstateBan ban = new EstateBan(); 12715 EstateBan ban = new EstateBan();
11275 ban.EstateID = estate.EstateID; 12716 ban.EstateID = estate.EstateID;
11276 ban.BannedUserID = id; 12717 ban.BannedUserID = id;
11277 estate.AddBan(ban); 12718 estate.AddBan(ban);
11278 break; 12719 break;
11279 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12720 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11280 if (!isAccount || !estate.IsBanned(id)) return 0; 12721 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11281 estate.RemoveBan(id); 12722 estate.RemoveBan(id);
11282 break; 12723 break;
11283 default: return 0; 12724 default: return 0;
@@ -11306,7 +12747,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11306 return 16384; 12747 return 16384;
11307 } 12748 }
11308 12749
11309 public LSL_Integer llGetUsedMemory() 12750 public virtual LSL_Integer llGetUsedMemory()
11310 { 12751 {
11311 m_host.AddScriptLPS(1); 12752 m_host.AddScriptLPS(1);
11312 // The value returned for LSO scripts in SL 12753 // The value returned for LSO scripts in SL
@@ -11334,7 +12775,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11334 public void llSetSoundQueueing(int queue) 12775 public void llSetSoundQueueing(int queue)
11335 { 12776 {
11336 m_host.AddScriptLPS(1); 12777 m_host.AddScriptLPS(1);
11337 NotImplemented("llSetSoundQueueing");
11338 } 12778 }
11339 12779
11340 public void llCollisionSprite(string impact_sprite) 12780 public void llCollisionSprite(string impact_sprite)
@@ -11346,10 +12786,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11346 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12786 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11347 { 12787 {
11348 m_host.AddScriptLPS(1); 12788 m_host.AddScriptLPS(1);
11349 NotImplemented("llGodLikeRezObject"); 12789
12790 if (!World.Permissions.IsGod(m_host.OwnerID))
12791 NotImplemented("llGodLikeRezObject");
12792
12793 AssetBase rezAsset = World.AssetService.Get(inventory);
12794 if (rezAsset == null)
12795 {
12796 llSay(0, "Asset not found");
12797 return;
12798 }
12799
12800 SceneObjectGroup group = null;
12801
12802 try
12803 {
12804 string xmlData = Utils.BytesToString(rezAsset.Data);
12805 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12806 }
12807 catch
12808 {
12809 llSay(0, "Asset not found");
12810 return;
12811 }
12812
12813 if (group == null)
12814 {
12815 llSay(0, "Asset not found");
12816 return;
12817 }
12818
12819 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12820 group.RootPart.AttachOffset = group.AbsolutePosition;
12821
12822 group.ResetIDs();
12823
12824 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12825 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12826 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12827 group.ScheduleGroupForFullUpdate();
12828
12829 // objects rezzed with this method are die_at_edge by default.
12830 group.RootPart.SetDieAtEdge(true);
12831
12832 group.ResumeScripts();
12833
12834 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12835 "object_rez", new Object[] {
12836 new LSL_String(
12837 group.RootPart.UUID.ToString()) },
12838 new DetectParams[0]));
12839 }
12840
12841 public LSL_String llTransferLindenDollars(string destination, int amount)
12842 {
12843 UUID txn = UUID.Random();
12844
12845 Util.FireAndForget(delegate(object x)
12846 {
12847 int replycode = 0;
12848 string replydata = destination + "," + amount.ToString();
12849
12850 try
12851 {
12852 TaskInventoryItem item = m_item;
12853 if (item == null)
12854 {
12855 replydata = "SERVICE_ERROR";
12856 return;
12857 }
12858
12859 m_host.AddScriptLPS(1);
12860
12861 if (item.PermsGranter == UUID.Zero)
12862 {
12863 replydata = "MISSING_PERMISSION_DEBIT";
12864 return;
12865 }
12866
12867 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12868 {
12869 replydata = "MISSING_PERMISSION_DEBIT";
12870 return;
12871 }
12872
12873 UUID toID = new UUID();
12874
12875 if (!UUID.TryParse(destination, out toID))
12876 {
12877 replydata = "INVALID_AGENT";
12878 return;
12879 }
12880
12881 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12882
12883 if (money == null)
12884 {
12885 replydata = "TRANSFERS_DISABLED";
12886 return;
12887 }
12888
12889 bool result = money.ObjectGiveMoney(
12890 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12891
12892 if (result)
12893 {
12894 replycode = 1;
12895 return;
12896 }
12897
12898 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12899 }
12900 finally
12901 {
12902 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12903 "transaction_result", new Object[] {
12904 new LSL_String(txn.ToString()),
12905 new LSL_Integer(replycode),
12906 new LSL_String(replydata) },
12907 new DetectParams[0]));
12908 }
12909 });
12910
12911 return txn.ToString();
11350 } 12912 }
11351 12913
11352 #endregion 12914 #endregion
12915
12916 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12917 {
12918 SceneObjectGroup group = m_host.ParentGroup;
12919
12920 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12921 return;
12922 if (group.IsAttachment)
12923 return;
12924
12925 if (frames.Data.Length > 0) // We are getting a new motion
12926 {
12927 if (group.RootPart.KeyframeMotion != null)
12928 group.RootPart.KeyframeMotion.Stop();
12929 group.RootPart.KeyframeMotion = null;
12930
12931 int idx = 0;
12932
12933 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12934 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12935
12936 while (idx < options.Data.Length)
12937 {
12938 int option = (int)options.GetLSLIntegerItem(idx++);
12939 int remain = options.Data.Length - idx;
12940
12941 switch (option)
12942 {
12943 case ScriptBaseClass.KFM_MODE:
12944 if (remain < 1)
12945 break;
12946 int modeval = (int)options.GetLSLIntegerItem(idx++);
12947 switch(modeval)
12948 {
12949 case ScriptBaseClass.KFM_FORWARD:
12950 mode = KeyframeMotion.PlayMode.Forward;
12951 break;
12952 case ScriptBaseClass.KFM_REVERSE:
12953 mode = KeyframeMotion.PlayMode.Reverse;
12954 break;
12955 case ScriptBaseClass.KFM_LOOP:
12956 mode = KeyframeMotion.PlayMode.Loop;
12957 break;
12958 case ScriptBaseClass.KFM_PING_PONG:
12959 mode = KeyframeMotion.PlayMode.PingPong;
12960 break;
12961 }
12962 break;
12963 case ScriptBaseClass.KFM_DATA:
12964 if (remain < 1)
12965 break;
12966 int dataval = (int)options.GetLSLIntegerItem(idx++);
12967 data = (KeyframeMotion.DataFormat)dataval;
12968 break;
12969 }
12970 }
12971
12972 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12973
12974 idx = 0;
12975
12976 int elemLength = 2;
12977 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12978 elemLength = 3;
12979
12980 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12981 while (idx < frames.Data.Length)
12982 {
12983 int remain = frames.Data.Length - idx;
12984
12985 if (remain < elemLength)
12986 break;
12987
12988 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12989 frame.Position = null;
12990 frame.Rotation = null;
12991
12992 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12993 {
12994 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12995 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12996 }
12997 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12998 {
12999 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
13000 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
13001 }
13002
13003 float tempf = (float)frames.GetLSLFloatItem(idx++);
13004 frame.TimeMS = (int)(tempf * 1000.0f);
13005
13006 keyframes.Add(frame);
13007 }
13008
13009 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
13010 group.RootPart.KeyframeMotion.Start();
13011 }
13012 else
13013 {
13014 if (group.RootPart.KeyframeMotion == null)
13015 return;
13016
13017 if (options.Data.Length == 0)
13018 {
13019 group.RootPart.KeyframeMotion.Stop();
13020 return;
13021 }
13022
13023 int code = (int)options.GetLSLIntegerItem(0);
13024
13025 int idx = 0;
13026
13027 while (idx < options.Data.Length)
13028 {
13029 int option = (int)options.GetLSLIntegerItem(idx++);
13030 int remain = options.Data.Length - idx;
13031
13032 switch (option)
13033 {
13034 case ScriptBaseClass.KFM_COMMAND:
13035 int cmd = (int)options.GetLSLIntegerItem(idx++);
13036 switch (cmd)
13037 {
13038 case ScriptBaseClass.KFM_CMD_PLAY:
13039 group.RootPart.KeyframeMotion.Start();
13040 break;
13041 case ScriptBaseClass.KFM_CMD_STOP:
13042 group.RootPart.KeyframeMotion.Stop();
13043 break;
13044 case ScriptBaseClass.KFM_CMD_PAUSE:
13045 group.RootPart.KeyframeMotion.Pause();
13046 break;
13047 }
13048 break;
13049 }
13050 }
13051 }
13052 }
11353 } 13053 }
11354 13054
11355 public class NotecardCache 13055 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 5e7c2d9..a81c39c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -138,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
139 internal float m_ScriptDelayFactor = 1.0f; 139 internal float m_ScriptDelayFactor = 1.0f;
140 internal float m_ScriptDistanceFactor = 1.0f; 140 internal float m_ScriptDistanceFactor = 1.0f;
141 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 143
143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_ScriptEngine = ScriptEngine; 146 m_ScriptEngine = ScriptEngine;
146 m_host = host; 147 m_host = host;
147 m_item = item; 148 m_item = item;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -206,7 +208,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
206 208
207 internal void OSSLError(string msg) 209 internal void OSSLError(string msg)
208 { 210 {
209 throw new Exception("OSSL Runtime Error: " + msg); 211 if (m_debuggerSafe)
212 {
213 OSSLShoutError(msg);
214 }
215 else
216 {
217 throw new Exception("OSSL Runtime Error: " + msg);
218 }
210 } 219 }
211 220
212 /// <summary> 221 /// <summary>
@@ -914,18 +923,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
914 if (target != null) 923 if (target != null)
915 { 924 {
916 UUID animID=UUID.Zero; 925 UUID animID=UUID.Zero;
917 lock (m_host.TaskInventory) 926 m_host.TaskInventory.LockItemsForRead(true);
927 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
918 { 928 {
919 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 929 if (inv.Value.Name == animation)
920 { 930 {
921 if (inv.Value.Name == animation) 931 if (inv.Value.Type == (int)AssetType.Animation)
922 { 932 animID = inv.Value.AssetID;
923 if (inv.Value.Type == (int)AssetType.Animation) 933 continue;
924 animID = inv.Value.AssetID;
925 continue;
926 }
927 } 934 }
928 } 935 }
936 m_host.TaskInventory.LockItemsForRead(false);
929 if (animID == UUID.Zero) 937 if (animID == UUID.Zero)
930 target.Animator.AddAnimation(animation, m_host.UUID); 938 target.Animator.AddAnimation(animation, m_host.UUID);
931 else 939 else
@@ -966,6 +974,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
966 else 974 else
967 animID = UUID.Zero; 975 animID = UUID.Zero;
968 } 976 }
977 m_host.TaskInventory.LockItemsForRead(false);
969 978
970 if (animID == UUID.Zero) 979 if (animID == UUID.Zero)
971 target.Animator.RemoveAnimation(animation); 980 target.Animator.RemoveAnimation(animation);
@@ -1799,6 +1808,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1799 1808
1800 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1809 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1801 { 1810 {
1811 m_host.TaskInventory.LockItemsForRead(true);
1802 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1812 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1803 { 1813 {
1804 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1814 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1806,6 +1816,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1806 assetID = item.AssetID; 1816 assetID = item.AssetID;
1807 } 1817 }
1808 } 1818 }
1819 m_host.TaskInventory.LockItemsForRead(false);
1809 } 1820 }
1810 1821
1811 if (assetID == UUID.Zero) 1822 if (assetID == UUID.Zero)
@@ -2277,7 +2288,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2277 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2288 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2278 m_host.AddScriptLPS(1); 2289 m_host.AddScriptLPS(1);
2279 2290
2280 return NpcCreate(firstname, lastname, position, notecard, false, false); 2291 return NpcCreate(firstname, lastname, position, notecard, true, false);
2281 } 2292 }
2282 2293
2283 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2294 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2288,24 +2299,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2288 return NpcCreate( 2299 return NpcCreate(
2289 firstname, lastname, position, notecard, 2300 firstname, lastname, position, notecard,
2290 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2301 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2291 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2302 false);
2303// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2292 } 2304 }
2293 2305
2294 private LSL_Key NpcCreate( 2306 private LSL_Key NpcCreate(
2295 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2307 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2296 { 2308 {
2309 if (!owned)
2310 OSSLError("Unowned NPCs are unsupported");
2311
2312 string groupTitle = String.Empty;
2313
2314 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2315 return new LSL_Key(UUID.Zero.ToString());
2316
2317 if (firstname != String.Empty || lastname != String.Empty)
2318 {
2319 if (firstname != "Shown outfit:")
2320 groupTitle = "- NPC -";
2321 }
2322
2297 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2323 INPCModule module = World.RequestModuleInterface<INPCModule>();
2298 if (module != null) 2324 if (module != null)
2299 { 2325 {
2300 AvatarAppearance appearance = null; 2326 AvatarAppearance appearance = null;
2301 2327
2302 UUID id; 2328// UUID id;
2303 if (UUID.TryParse(notecard, out id)) 2329// if (UUID.TryParse(notecard, out id))
2304 { 2330// {
2305 ScenePresence clonePresence = World.GetScenePresence(id); 2331// ScenePresence clonePresence = World.GetScenePresence(id);
2306 if (clonePresence != null) 2332// if (clonePresence != null)
2307 appearance = clonePresence.Appearance; 2333// appearance = clonePresence.Appearance;
2308 } 2334// }
2309 2335
2310 if (appearance == null) 2336 if (appearance == null)
2311 { 2337 {
@@ -2333,6 +2359,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2333 World, 2359 World,
2334 appearance); 2360 appearance);
2335 2361
2362 ScenePresence sp;
2363 if (World.TryGetScenePresence(x, out sp))
2364 {
2365 sp.Grouptitle = groupTitle;
2366 sp.SendAvatarDataToAllAgents();
2367 }
2336 return new LSL_Key(x.ToString()); 2368 return new LSL_Key(x.ToString());
2337 } 2369 }
2338 2370
@@ -2632,16 +2664,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2632 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2664 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2633 m_host.AddScriptLPS(1); 2665 m_host.AddScriptLPS(1);
2634 2666
2635 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2667 ManualResetEvent ev = new ManualResetEvent(false);
2636 if (module != null)
2637 {
2638 UUID npcId = new UUID(npc.m_string);
2639 2668
2640 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2669 Util.FireAndForget(delegate(object x) {
2641 return; 2670 try
2671 {
2672 INPCModule module = World.RequestModuleInterface<INPCModule>();
2673 if (module != null)
2674 {
2675 UUID npcId = new UUID(npc.m_string);
2642 2676
2643 module.DeleteNPC(npcId, World); 2677 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2644 } 2678 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2679 {
2680 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2681 return;
2682 }
2683
2684 module.DeleteNPC(npcId, World);
2685 }
2686 }
2687 finally
2688 {
2689 ev.Set();
2690 }
2691 });
2692 ev.WaitOne();
2645 } 2693 }
2646 2694
2647 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2695 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3345,4 +3393,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3345 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString()); 3393 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString());
3346 } 3394 }
3347 } 3395 }
3348} \ No newline at end of file 3396}
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 3fb463b..af35258 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -126,6 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
126 LSL_Float llGetEnergy(); 126 LSL_Float llGetEnergy();
127 LSL_Vector llGetForce(); 127 LSL_Vector llGetForce();
128 LSL_Integer llGetFreeMemory(); 128 LSL_Integer llGetFreeMemory();
129 LSL_Integer llGetUsedMemory();
129 LSL_Integer llGetFreeURLs(); 130 LSL_Integer llGetFreeURLs();
130 LSL_Vector llGetGeometricCenter(); 131 LSL_Vector llGetGeometricCenter();
131 LSL_Float llGetGMTclock(); 132 LSL_Float llGetGMTclock();
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
149 LSL_Vector llGetLocalPos(); 150 LSL_Vector llGetLocalPos();
150 LSL_Rotation llGetLocalRot(); 151 LSL_Rotation llGetLocalRot();
151 LSL_Float llGetMass(); 152 LSL_Float llGetMass();
153 LSL_Float llGetMassMKS();
152 LSL_Integer llGetMemoryLimit(); 154 LSL_Integer llGetMemoryLimit();
153 void llGetNextEmail(string address, string subject); 155 void llGetNextEmail(string address, string subject);
154 LSL_String llGetNotecardLine(string name, int line); 156 LSL_String llGetNotecardLine(string name, int line);
@@ -202,12 +204,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
202 LSL_String llGetTimestamp(); 204 LSL_String llGetTimestamp();
203 LSL_Vector llGetTorque(); 205 LSL_Vector llGetTorque();
204 LSL_Integer llGetUnixTime(); 206 LSL_Integer llGetUnixTime();
205 LSL_Integer llGetUsedMemory();
206 LSL_Vector llGetVel(); 207 LSL_Vector llGetVel();
207 LSL_Float llGetWallclock(); 208 LSL_Float llGetWallclock();
208 void llGiveInventory(string destination, string inventory); 209 void llGiveInventory(string destination, string inventory);
209 void llGiveInventoryList(string destination, string category, LSL_List inventory); 210 void llGiveInventoryList(string destination, string category, LSL_List inventory);
210 LSL_Integer llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
212 LSL_String llTransferLindenDollars(string destination, int amount);
211 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
212 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
213 LSL_Vector llGroundContour(LSL_Vector offset); 215 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -330,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
330 void llSensorRemove(); 332 void llSensorRemove();
331 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate); 333 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate);
332 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
333 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
334 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
335 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -355,11 +358,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
355 void llSetParcelMusicURL(string url); 358 void llSetParcelMusicURL(string url);
356 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 359 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
357 void llSetPos(LSL_Vector pos); 360 void llSetPos(LSL_Vector pos);
361 LSL_Integer llSetRegionPos(LSL_Vector pos);
358 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 362 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
359 void llSetPrimitiveParams(LSL_List rules); 363 void llSetPrimitiveParams(LSL_List rules);
360 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 364 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
361 void llSetPrimURL(string url); 365 void llSetPrimURL(string url);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
363 void llSetRemoteScriptAccessPin(int pin); 366 void llSetRemoteScriptAccessPin(int pin);
364 void llSetRot(LSL_Rotation rot); 367 void llSetRot(LSL_Rotation rot);
365 void llSetScale(LSL_Vector scale); 368 void llSetScale(LSL_Vector scale);
@@ -379,6 +382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
379 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 382 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
380 void llSetVehicleType(int type); 383 void llSetVehicleType(int type);
381 void llSetVehicleVectorParam(int param, LSL_Vector vec); 384 void llSetVehicleVectorParam(int param, LSL_Vector vec);
385 void llSetVelocity(LSL_Vector velocity, int local);
382 void llShout(int channelID, string text); 386 void llShout(int channelID, string text);
383 LSL_Float llSin(double f); 387 LSL_Float llSin(double f);
384 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 388 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -422,9 +426,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
422 LSL_Vector llWind(LSL_Vector offset); 426 LSL_Vector llWind(LSL_Vector offset);
423 LSL_String llXorBase64Strings(string str1, string str2); 427 LSL_String llXorBase64Strings(string str1, string str2);
424 LSL_String llXorBase64StringsCorrect(string str1, string str2); 428 LSL_String llXorBase64StringsCorrect(string str1, string str2);
425 void print(string str); 429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
426 431
427 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
428 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 433 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
429 } 435 }
430} 436}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 9ad1c22..8101da5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -85,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
85 // Avatar Info Commands 85 // Avatar Info Commands
86 string osGetAgentIP(string agent); 86 string osGetAgentIP(string agent);
87 LSL_List osGetAgents(); 87 LSL_List osGetAgents();
88 88
89 // Teleport commands 89 // Teleport commands
90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 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 9d9df9c..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 }
@@ -1137,7 +1134,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1137 { 1134 {
1138 list ret = new list(); 1135 list ret = new list();
1139 double entry; 1136 double entry;
1140 for (int i = 0; i < src.Data.Length - 1; i++) 1137 for (int i = 0; i < src.Data.Length; i++)
1141 { 1138 {
1142 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1139 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1143 { 1140 {
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 {