aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3168
-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, 3215 insertions, 1028 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 b001c51..5316d08 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);
3972 4329
3973 GridInstantMessage msg = new GridInstantMessage(World, 4330 GridInstantMessage msg = new GridInstantMessage(World,
3974 m_host.UUID, m_host.Name + ", an object owned by " + 4331 m_host.OwnerID, m_host.Name, destId,
3975 resolveName(m_host.OwnerID) + ",", destId, 4332 (byte)InstantMessageDialog.TaskInventoryOffered,
3976 (byte)InstantMessageDialog.TaskInventoryOffered, 4333 false, item.Name+". "+m_host.Name+" is located at "+
3977 false, item.Name + "\n" + m_host.Name + " is located at " + 4334 World.RegionInfo.RegionName+" "+
3978 World.RegionInfo.RegionName+" "+ 4335 m_host.AbsolutePosition.ToString(),
3979 m_host.AbsolutePosition.ToString(), 4336 agentItem.ID, true, m_host.AbsolutePosition,
3980 agentItem.ID, true, m_host.AbsolutePosition, 4337 bucket);
3981 bucket);
3982 4338
3983 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4339 ScenePresence sp;
3984 }
3985 4340
4341 if (World.TryGetScenePresence(destId, out sp))
4342 {
4343 sp.ControllingClient.SendInstantMessage(msg);
4344 }
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
@@ -5828,9 +6253,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5828 6253
5829 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6254 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5830 6255
5831 foreach (SceneObjectPart part in parts) 6256 try
6257 {
6258 foreach (SceneObjectPart part in parts)
6259 {
6260 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6261 }
6262 }
6263 finally
5832 { 6264 {
5833 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5834 } 6265 }
5835 } 6266 }
5836 6267
@@ -5882,13 +6313,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5882 6313
5883 if (m_host.OwnerID == land.LandData.OwnerID) 6314 if (m_host.OwnerID == land.LandData.OwnerID)
5884 { 6315 {
5885 World.TeleportClientHome(agentID, presence.ControllingClient); 6316 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6317 presence.TeleportWithMomentum(pos, null);
6318 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5886 } 6319 }
5887 } 6320 }
5888 } 6321 }
5889 ScriptSleep(5000); 6322 ScriptSleep(5000);
5890 } 6323 }
5891 6324
6325 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6326 {
6327 return ParseString2List(str, separators, in_spacers, false);
6328 }
6329
5892 public LSL_Integer llOverMyLand(string id) 6330 public LSL_Integer llOverMyLand(string id)
5893 { 6331 {
5894 m_host.AddScriptLPS(1); 6332 m_host.AddScriptLPS(1);
@@ -5947,20 +6385,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5947 return agentSize; 6385 return agentSize;
5948 } 6386 }
5949 6387
5950 public LSL_Integer llSameGroup(string agent) 6388 public LSL_Integer llSameGroup(string id)
5951 { 6389 {
5952 m_host.AddScriptLPS(1); 6390 m_host.AddScriptLPS(1);
5953 UUID agentId = new UUID(); 6391 UUID uuid = new UUID();
5954 if (!UUID.TryParse(agent, out agentId)) 6392 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); 6393 return new LSL_Integer(0);
5959 IClientAPI client = presence.ControllingClient; 6394
5960 if (m_host.GroupID == client.ActiveGroupId) 6395 // Check if it's a group key
6396 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5961 return new LSL_Integer(1); 6397 return new LSL_Integer(1);
5962 else 6398
6399 // We got passed a UUID.Zero
6400 if (uuid == UUID.Zero)
6401 return new LSL_Integer(0);
6402
6403 // Handle the case where id names an avatar
6404 ScenePresence presence = World.GetScenePresence(uuid);
6405 if (presence != null)
6406 {
6407 if (presence.IsChildAgent)
6408 return new LSL_Integer(0);
6409
6410 IClientAPI client = presence.ControllingClient;
6411 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6412 return new LSL_Integer(1);
6413
5963 return new LSL_Integer(0); 6414 return new LSL_Integer(0);
6415 }
6416
6417 // Handle object case
6418 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6419 if (part != null)
6420 {
6421 // This will handle both deed and non-deed and also the no
6422 // group case
6423 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6424 return new LSL_Integer(1);
6425
6426 return new LSL_Integer(0);
6427 }
6428
6429 return new LSL_Integer(0);
5964 } 6430 }
5965 6431
5966 public void llUnSit(string id) 6432 public void llUnSit(string id)
@@ -6085,7 +6551,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6085 return m_host.ParentGroup.AttachmentPoint; 6551 return m_host.ParentGroup.AttachmentPoint;
6086 } 6552 }
6087 6553
6088 public LSL_Integer llGetFreeMemory() 6554 public virtual LSL_Integer llGetFreeMemory()
6089 { 6555 {
6090 m_host.AddScriptLPS(1); 6556 m_host.AddScriptLPS(1);
6091 // Make scripts designed for LSO happy 6557 // Make scripts designed for LSO happy
@@ -6202,7 +6668,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6202 SetParticleSystem(m_host, rules); 6668 SetParticleSystem(m_host, rules);
6203 } 6669 }
6204 6670
6205 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6671 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6672 {
6206 6673
6207 6674
6208 if (rules.Length == 0) 6675 if (rules.Length == 0)
@@ -6516,6 +6983,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6516 6983
6517 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6984 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6518 { 6985 {
6986 // LSL quaternions can normalize to 0, normal Quaternions can't.
6987 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6988 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6989
6519 part.SitTargetPosition = offset; 6990 part.SitTargetPosition = offset;
6520 part.SitTargetOrientation = rot; 6991 part.SitTargetOrientation = rot;
6521 part.ParentGroup.HasGroupChanged = true; 6992 part.ParentGroup.HasGroupChanged = true;
@@ -6671,13 +7142,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6671 UUID av = new UUID(); 7142 UUID av = new UUID();
6672 if (!UUID.TryParse(avatar,out av)) 7143 if (!UUID.TryParse(avatar,out av))
6673 { 7144 {
6674 LSLError("First parameter to llDialog needs to be a key"); 7145 //LSLError("First parameter to llDialog needs to be a key");
6675 return; 7146 return;
6676 } 7147 }
6677 if (buttons.Length < 1) 7148 if (buttons.Length < 1)
6678 { 7149 {
6679 LSLError("No less than 1 button can be shown"); 7150 buttons.Add("OK");
6680 return;
6681 } 7151 }
6682 if (buttons.Length > 12) 7152 if (buttons.Length > 12)
6683 { 7153 {
@@ -6694,7 +7164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6694 } 7164 }
6695 if (buttons.Data[i].ToString().Length > 24) 7165 if (buttons.Data[i].ToString().Length > 24)
6696 { 7166 {
6697 LSLError("button label cannot be longer than 24 characters"); 7167 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6698 return; 7168 return;
6699 } 7169 }
6700 buts[i] = buttons.Data[i].ToString(); 7170 buts[i] = buttons.Data[i].ToString();
@@ -6761,9 +7231,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6761 return; 7231 return;
6762 } 7232 }
6763 7233
6764 // the rest of the permission checks are done in RezScript, so check the pin there as well 7234 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6765 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7235 if (dest != null)
7236 {
7237 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7238 {
7239 // the rest of the permission checks are done in RezScript, so check the pin there as well
7240 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6766 7241
7242 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7243 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7244 }
7245 }
6767 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7246 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6768 ScriptSleep(3000); 7247 ScriptSleep(3000);
6769 } 7248 }
@@ -6826,19 +7305,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6826 public LSL_String llMD5String(string src, int nonce) 7305 public LSL_String llMD5String(string src, int nonce)
6827 { 7306 {
6828 m_host.AddScriptLPS(1); 7307 m_host.AddScriptLPS(1);
6829 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7308 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6830 } 7309 }
6831 7310
6832 public LSL_String llSHA1String(string src) 7311 public LSL_String llSHA1String(string src)
6833 { 7312 {
6834 m_host.AddScriptLPS(1); 7313 m_host.AddScriptLPS(1);
6835 return Util.SHA1Hash(src).ToLower(); 7314 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6836 } 7315 }
6837 7316
6838 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7317 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6839 { 7318 {
6840 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7319 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6841 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7320 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7321 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7322 return shapeBlock;
6842 7323
6843 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7324 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6844 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7325 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6943,6 +7424,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6943 // Prim type box, cylinder and prism. 7424 // 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) 7425 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 { 7426 {
7427 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7428 return;
7429
6946 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7430 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6947 ObjectShapePacket.ObjectDataBlock shapeBlock; 7431 ObjectShapePacket.ObjectDataBlock shapeBlock;
6948 7432
@@ -6996,6 +7480,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6996 // Prim type sphere. 7480 // 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) 7481 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6998 { 7482 {
7483 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7484 return;
7485
6999 ObjectShapePacket.ObjectDataBlock shapeBlock; 7486 ObjectShapePacket.ObjectDataBlock shapeBlock;
7000 7487
7001 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7488 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7037,6 +7524,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7037 // Prim type torus, tube and ring. 7524 // 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) 7525 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 { 7526 {
7527 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7528 return;
7529
7040 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7530 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7041 ObjectShapePacket.ObjectDataBlock shapeBlock; 7531 ObjectShapePacket.ObjectDataBlock shapeBlock;
7042 7532
@@ -7172,6 +7662,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7172 // Prim type sculpt. 7662 // Prim type sculpt.
7173 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7663 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7174 { 7664 {
7665 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7666 return;
7667
7175 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7668 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7176 UUID sculptId; 7669 UUID sculptId;
7177 7670
@@ -7196,7 +7689,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7196 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7689 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7197 { 7690 {
7198 // default 7691 // default
7199 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7692 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7200 } 7693 }
7201 7694
7202 part.Shape.SetSculptProperties((byte)type, sculptId); 7695 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7213,46 +7706,126 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7213 ScriptSleep(200); 7706 ScriptSleep(200);
7214 } 7707 }
7215 7708
7216 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7709 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7217 { 7710 {
7218 m_host.AddScriptLPS(1); 7711 m_host.AddScriptLPS(1);
7219 7712
7220 setLinkPrimParams(linknumber, rules); 7713 setLinkPrimParams(linknumber, rules);
7714 }
7221 7715
7222 ScriptSleep(200); 7716 private void setLinkPrimParams(int linknumber, LSL_List rules)
7717 {
7718 List<object> parts = new List<object>();
7719 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7720 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7721 foreach (SceneObjectPart p in prims)
7722 parts.Add(p);
7723 foreach (ScenePresence p in avatars)
7724 parts.Add(p);
7725
7726 LSL_List remaining = null;
7727
7728 if (parts.Count > 0)
7729 {
7730 foreach (object part in parts)
7731 {
7732 if (part is SceneObjectPart)
7733 remaining = SetPrimParams((SceneObjectPart)part, rules);
7734 else
7735 remaining = SetPrimParams((ScenePresence)part, rules);
7736 }
7737
7738 while ((object)remaining != null && remaining.Length > 2)
7739 {
7740 linknumber = remaining.GetLSLIntegerItem(0);
7741 rules = remaining.GetSublist(1, -1);
7742 parts.Clear();
7743 prims = GetLinkParts(linknumber);
7744 avatars = GetLinkAvatars(linknumber);
7745 foreach (SceneObjectPart p in prims)
7746 parts.Add(p);
7747 foreach (ScenePresence p in avatars)
7748 parts.Add(p);
7749
7750 foreach (object part in parts)
7751 {
7752 if (part is SceneObjectPart)
7753 remaining = SetPrimParams((SceneObjectPart)part, rules);
7754 else
7755 remaining = SetPrimParams((ScenePresence)part, rules);
7756 }
7757 }
7758 }
7223 } 7759 }
7224 7760
7225 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7761 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7762 float material_density, float material_friction,
7763 float material_restitution, float material_gravity_modifier)
7226 { 7764 {
7227 m_host.AddScriptLPS(1); 7765 ExtraPhysicsData physdata = new ExtraPhysicsData();
7766 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7767 physdata.Density = part.Density;
7768 physdata.Friction = part.Friction;
7769 physdata.Bounce = part.Bounciness;
7770 physdata.GravitationModifier = part.GravityModifier;
7228 7771
7229 setLinkPrimParams(linknumber, rules); 7772 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7773 physdata.Density = material_density;
7774 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7775 physdata.Friction = material_friction;
7776 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7777 physdata.Bounce = material_restitution;
7778 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7779 physdata.GravitationModifier = material_gravity_modifier;
7780
7781 part.UpdateExtraPhysics(physdata);
7230 } 7782 }
7231 7783
7232 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7784 public void llSetPhysicsMaterial(int material_bits,
7785 float material_gravity_modifier, float material_restitution,
7786 float material_friction, float material_density)
7233 { 7787 {
7234 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7788 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7789 }
7235 7790
7236 LSL_List remaining = null; 7791 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7792 {
7793 llSetLinkPrimitiveParamsFast(linknumber, rules);
7794 ScriptSleep(200);
7795 }
7237 7796
7238 foreach (SceneObjectPart part in parts) 7797 // vector up using libomv (c&p from sop )
7239 remaining = SetPrimParams(part, rules); 7798 // vector up rotated by r
7799 private Vector3 Zrot(Quaternion r)
7800 {
7801 double x, y, z, m;
7240 7802
7241 while (remaining != null && remaining.Length > 2) 7803 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7804 if (Math.Abs(1.0 - m) > 0.000001)
7242 { 7805 {
7243 linknumber = remaining.GetLSLIntegerItem(0); 7806 m = 1.0 / Math.Sqrt(m);
7244 rules = remaining.GetSublist(1, -1); 7807 r.X *= (float)m;
7245 parts = GetLinkParts(linknumber); 7808 r.Y *= (float)m;
7246 7809 r.Z *= (float)m;
7247 foreach (SceneObjectPart part in parts) 7810 r.W *= (float)m;
7248 remaining = SetPrimParams(part, rules);
7249 } 7811 }
7812
7813 x = 2 * (r.X * r.Z + r.Y * r.W);
7814 y = 2 * (-r.X * r.W + r.Y * r.Z);
7815 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7816
7817 return new Vector3((float)x, (float)y, (float)z);
7250 } 7818 }
7251 7819
7252 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules) 7820 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules)
7253 { 7821 {
7822 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7823 return null;
7824
7254 int idx = 0; 7825 int idx = 0;
7255 7826
7827 SceneObjectGroup parentgrp = part.ParentGroup;
7828
7256 bool positionChanged = false; 7829 bool positionChanged = false;
7257 LSL_Vector currentPosition = GetPartLocalPos(part); 7830 LSL_Vector currentPosition = GetPartLocalPos(part);
7258 7831
@@ -7275,8 +7848,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7275 return null; 7848 return null;
7276 7849
7277 v=rules.GetVector3Item(idx++); 7850 v=rules.GetVector3Item(idx++);
7278 positionChanged = true;
7279 currentPosition = GetSetPosTarget(part, v, currentPosition); 7851 currentPosition = GetSetPosTarget(part, v, currentPosition);
7852 positionChanged = true;
7280 7853
7281 break; 7854 break;
7282 case (int)ScriptBaseClass.PRIM_SIZE: 7855 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7292,8 +7865,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7292 return null; 7865 return null;
7293 7866
7294 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7867 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7868 SceneObjectPart rootPart = parentgrp.RootPart;
7295 // try to let this work as in SL... 7869 // try to let this work as in SL...
7296 if (part.ParentID == 0) 7870 if (rootPart == part)
7297 { 7871 {
7298 // special case: If we are root, rotate complete SOG to new rotation 7872 // special case: If we are root, rotate complete SOG to new rotation
7299 SetRot(part, q); 7873 SetRot(part, q);
@@ -7301,7 +7875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7301 else 7875 else
7302 { 7876 {
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. 7877 // 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; 7878 // sounds like sl bug that we need to replicate
7305 SetRot(part, rootPart.RotationOffset * (Quaternion)q); 7879 SetRot(part, rootPart.RotationOffset * (Quaternion)q);
7306 } 7880 }
7307 7881
@@ -7553,7 +8127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7553 return null; 8127 return null;
7554 8128
7555 string ph = rules.Data[idx++].ToString(); 8129 string ph = rules.Data[idx++].ToString();
7556 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8130 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7557 8131
7558 break; 8132 break;
7559 8133
@@ -7571,12 +8145,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7571 part.ScriptSetPhysicsStatus(physics); 8145 part.ScriptSetPhysicsStatus(physics);
7572 break; 8146 break;
7573 8147
8148 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8149 if (remain < 1)
8150 return null;
8151
8152 int shape_type = rules.GetLSLIntegerItem(idx++);
8153
8154 ExtraPhysicsData physdata = new ExtraPhysicsData();
8155 physdata.Density = part.Density;
8156 physdata.Bounce = part.Bounciness;
8157 physdata.GravitationModifier = part.GravityModifier;
8158 physdata.PhysShapeType = (PhysShapeType)shape_type;
8159
8160 part.UpdateExtraPhysics(physdata);
8161
8162 break;
8163
8164 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8165 if (remain < 5)
8166 return null;
8167
8168 int material_bits = rules.GetLSLIntegerItem(idx++);
8169 float material_density = (float)rules.GetLSLFloatItem(idx++);
8170 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8171 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8172 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8173
8174 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8175
8176 break;
8177
7574 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8178 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7575 if (remain < 1) 8179 if (remain < 1)
7576 return null; 8180 return null;
7577 string temp = rules.Data[idx++].ToString(); 8181 string temp = rules.Data[idx++].ToString();
7578 8182
7579 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8183 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7580 8184
7581 break; 8185 break;
7582 8186
@@ -7648,7 +8252,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7648 if (part.ParentGroup.RootPart == part) 8252 if (part.ParentGroup.RootPart == part)
7649 { 8253 {
7650 SceneObjectGroup parent = part.ParentGroup; 8254 SceneObjectGroup parent = part.ParentGroup;
7651 parent.UpdateGroupPosition(currentPosition); 8255 Util.FireAndForget(delegate(object x) {
8256 parent.UpdateGroupPosition(currentPosition);
8257 });
7652 } 8258 }
7653 else 8259 else
7654 { 8260 {
@@ -7693,10 +8299,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7693 8299
7694 public LSL_String llXorBase64Strings(string str1, string str2) 8300 public LSL_String llXorBase64Strings(string str1, string str2)
7695 { 8301 {
7696 m_host.AddScriptLPS(1); 8302 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7697 Deprecated("llXorBase64Strings"); 8303
7698 ScriptSleep(300); 8304 ScriptSleep(300);
7699 return String.Empty; 8305 m_host.AddScriptLPS(1);
8306
8307 if (str1 == String.Empty)
8308 return String.Empty;
8309 if (str2 == String.Empty)
8310 return str1;
8311
8312 int len = str2.Length;
8313 if ((len % 4) != 0) // LL is EVIL!!!!
8314 {
8315 while (str2.EndsWith("="))
8316 str2 = str2.Substring(0, str2.Length - 1);
8317
8318 len = str2.Length;
8319 int mod = len % 4;
8320
8321 if (mod == 1)
8322 str2 = str2.Substring(0, str2.Length - 1);
8323 else if (mod == 2)
8324 str2 += "==";
8325 else if (mod == 3)
8326 str2 += "=";
8327 }
8328
8329 byte[] data1;
8330 byte[] data2;
8331 try
8332 {
8333 data1 = Convert.FromBase64String(str1);
8334 data2 = Convert.FromBase64String(str2);
8335 }
8336 catch (Exception)
8337 {
8338 return new LSL_String(String.Empty);
8339 }
8340
8341 // For cases where the decoded length of s2 is greater
8342 // than the decoded length of s1, simply perform a normal
8343 // decode and XOR
8344 //
8345 if (data2.Length >= data1.Length)
8346 {
8347 for (int pos = 0 ; pos < data1.Length ; pos++ )
8348 data1[pos] ^= data2[pos];
8349
8350 return Convert.ToBase64String(data1);
8351 }
8352
8353 // Remove padding
8354 while (str1.EndsWith("="))
8355 str1 = str1.Substring(0, str1.Length - 1);
8356 while (str2.EndsWith("="))
8357 str2 = str2.Substring(0, str2.Length - 1);
8358
8359 byte[] d1 = new byte[str1.Length];
8360 byte[] d2 = new byte[str2.Length];
8361
8362 for (int i = 0 ; i < str1.Length ; i++)
8363 {
8364 int idx = b64.IndexOf(str1.Substring(i, 1));
8365 if (idx == -1)
8366 idx = 0;
8367 d1[i] = (byte)idx;
8368 }
8369
8370 for (int i = 0 ; i < str2.Length ; i++)
8371 {
8372 int idx = b64.IndexOf(str2.Substring(i, 1));
8373 if (idx == -1)
8374 idx = 0;
8375 d2[i] = (byte)idx;
8376 }
8377
8378 string output = String.Empty;
8379
8380 for (int pos = 0 ; pos < d1.Length ; pos++)
8381 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8382
8383 while (output.Length % 3 > 0)
8384 output += "=";
8385
8386 return output;
7700 } 8387 }
7701 8388
7702 public void llRemoteDataSetRegion() 8389 public void llRemoteDataSetRegion()
@@ -7820,13 +8507,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7820 public LSL_Integer llGetNumberOfPrims() 8507 public LSL_Integer llGetNumberOfPrims()
7821 { 8508 {
7822 m_host.AddScriptLPS(1); 8509 m_host.AddScriptLPS(1);
7823 int avatarCount = 0; 8510 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7824 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8511
7825 {
7826 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7827 avatarCount++;
7828 });
7829
7830 return m_host.ParentGroup.PrimCount + avatarCount; 8512 return m_host.ParentGroup.PrimCount + avatarCount;
7831 } 8513 }
7832 8514
@@ -7842,55 +8524,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7842 m_host.AddScriptLPS(1); 8524 m_host.AddScriptLPS(1);
7843 UUID objID = UUID.Zero; 8525 UUID objID = UUID.Zero;
7844 LSL_List result = new LSL_List(); 8526 LSL_List result = new LSL_List();
8527
8528 // If the ID is not valid, return null result
7845 if (!UUID.TryParse(obj, out objID)) 8529 if (!UUID.TryParse(obj, out objID))
7846 { 8530 {
7847 result.Add(new LSL_Vector()); 8531 result.Add(new LSL_Vector());
7848 result.Add(new LSL_Vector()); 8532 result.Add(new LSL_Vector());
7849 return result; 8533 return result;
7850 } 8534 }
8535
8536 // Check if this is an attached prim. If so, replace
8537 // the UUID with the avatar UUID and report it's bounding box
8538 SceneObjectPart part = World.GetSceneObjectPart(objID);
8539 if (part != null && part.ParentGroup.IsAttachment)
8540 objID = part.ParentGroup.AttachedAvatar;
8541
8542 // Find out if this is an avatar ID. If so, return it's box
7851 ScenePresence presence = World.GetScenePresence(objID); 8543 ScenePresence presence = World.GetScenePresence(objID);
7852 if (presence != null) 8544 if (presence != null)
7853 { 8545 {
7854 if (presence.ParentID == 0) // not sat on an object 8546 // As per LSL Wiki, there is no difference between sitting
8547 // and standing avatar since server 1.36
8548 LSL_Vector lower;
8549 LSL_Vector upper;
8550 if (presence.Animator.Animations.DefaultAnimation.AnimID
8551 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7855 { 8552 {
7856 LSL_Vector lower; 8553 // This is for ground sitting avatars
7857 LSL_Vector upper; 8554 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7858 if (presence.Animator.Animations.DefaultAnimation.AnimID 8555 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7859 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8556 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 } 8557 }
7877 else 8558 else
7878 { 8559 {
7879 // sitting on an object so we need the bounding box of that 8560 // This is for standing/flying avatars
7880 // which should include the avatar so set the UUID to the 8561 float height = presence.Appearance.AvatarHeight / 2.0f;
7881 // UUID of the object the avatar is sat on and allow it to fall through 8562 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7882 // to processing an object 8563 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7883 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7884 objID = p.UUID;
7885 } 8564 }
8565
8566 // Adjust to the documented error offsets (see LSL Wiki)
8567 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8568 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8569
8570 if (lower.x > upper.x)
8571 lower.x = upper.x;
8572 if (lower.y > upper.y)
8573 lower.y = upper.y;
8574 if (lower.z > upper.z)
8575 lower.z = upper.z;
8576
8577 result.Add(lower);
8578 result.Add(upper);
8579 return result;
7886 } 8580 }
7887 SceneObjectPart part = World.GetSceneObjectPart(objID); 8581
8582 part = World.GetSceneObjectPart(objID);
7888 // Currently only works for single prims without a sitting avatar 8583 // Currently only works for single prims without a sitting avatar
7889 if (part != null) 8584 if (part != null)
7890 { 8585 {
7891 Vector3 halfSize = part.Scale / 2.0f; 8586 float minX;
7892 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8587 float maxX;
7893 LSL_Vector upper = new LSL_Vector(halfSize); 8588 float minY;
8589 float maxY;
8590 float minZ;
8591 float maxZ;
8592
8593 // This BBox is in sim coordinates, with the offset being
8594 // a contained point.
8595 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8596 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8597
8598 minX -= offsets[0].X;
8599 maxX -= offsets[0].X;
8600 minY -= offsets[0].Y;
8601 maxY -= offsets[0].Y;
8602 minZ -= offsets[0].Z;
8603 maxZ -= offsets[0].Z;
8604
8605 LSL_Vector lower;
8606 LSL_Vector upper;
8607
8608 // Adjust to the documented error offsets (see LSL Wiki)
8609 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8610 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8611
8612 if (lower.x > upper.x)
8613 lower.x = upper.x;
8614 if (lower.y > upper.y)
8615 lower.y = upper.y;
8616 if (lower.z > upper.z)
8617 lower.z = upper.z;
8618
7894 result.Add(lower); 8619 result.Add(lower);
7895 result.Add(upper); 8620 result.Add(upper);
7896 return result; 8621 return result;
@@ -7904,7 +8629,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7904 8629
7905 public LSL_Vector llGetGeometricCenter() 8630 public LSL_Vector llGetGeometricCenter()
7906 { 8631 {
7907 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8632 Vector3 tmp = m_host.GetGeometricCenter();
8633 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7908 } 8634 }
7909 8635
7910 public LSL_List llGetPrimitiveParams(LSL_List rules) 8636 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7932,24 +8658,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7932 { 8658 {
7933 m_host.AddScriptLPS(1); 8659 m_host.AddScriptLPS(1);
7934 8660
7935 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8661 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8662 // keep other options as before
7936 8663
8664 List<SceneObjectPart> parts;
8665 List<ScenePresence> avatars;
8666
7937 LSL_List res = new LSL_List(); 8667 LSL_List res = new LSL_List();
7938 LSL_List remaining = null; 8668 LSL_List remaining = null;
7939 8669
7940 foreach (SceneObjectPart part in parts) 8670 while (rules.Length > 0)
7941 { 8671 {
7942 remaining = GetPrimParams(part, rules, ref res);
7943 }
7944
7945 while (remaining != null && remaining.Length > 2)
7946 {
7947 linknumber = remaining.GetLSLIntegerItem(0);
7948 rules = remaining.GetSublist(1, -1);
7949 parts = GetLinkParts(linknumber); 8672 parts = GetLinkParts(linknumber);
8673 avatars = GetLinkAvatars(linknumber);
7950 8674
8675 remaining = null;
7951 foreach (SceneObjectPart part in parts) 8676 foreach (SceneObjectPart part in parts)
8677 {
7952 remaining = GetPrimParams(part, rules, ref res); 8678 remaining = GetPrimParams(part, rules, ref res);
8679 }
8680 foreach (ScenePresence avatar in avatars)
8681 {
8682 remaining = GetPrimParams(avatar, rules, ref res);
8683 }
8684
8685 if (remaining != null && remaining.Length > 0)
8686 {
8687 linknumber = remaining.GetLSLIntegerItem(0);
8688 rules = remaining.GetSublist(1, -1);
8689 }
7953 } 8690 }
7954 8691
7955 return res; 8692 return res;
@@ -7994,13 +8731,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7994 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8731 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7995 part.AbsolutePosition.Y, 8732 part.AbsolutePosition.Y,
7996 part.AbsolutePosition.Z); 8733 part.AbsolutePosition.Z);
7997 // For some reason, the part.AbsolutePosition.* values do not change if the
7998 // linkset is rotated; they always reflect the child prim's world position
7999 // as though the linkset is unrotated. This is incompatible behavior with SL's
8000 // implementation, so will break scripts imported from there (not to mention it
8001 // makes it more difficult to determine a child prim's actual inworld position).
8002 if (part.ParentID != 0)
8003 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8004 res.Add(v); 8734 res.Add(v);
8005 break; 8735 break;
8006 8736
@@ -8172,30 +8902,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8172 if (remain < 1) 8902 if (remain < 1)
8173 return null; 8903 return null;
8174 8904
8175 face=(int)rules.GetLSLIntegerItem(idx++); 8905 face = (int)rules.GetLSLIntegerItem(idx++);
8176 8906
8177 tex = part.Shape.Textures; 8907 tex = part.Shape.Textures;
8908 int shiny;
8178 if (face == ScriptBaseClass.ALL_SIDES) 8909 if (face == ScriptBaseClass.ALL_SIDES)
8179 { 8910 {
8180 for (face = 0; face < GetNumberOfSides(part); face++) 8911 for (face = 0; face < GetNumberOfSides(part); face++)
8181 { 8912 {
8182 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8913 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8183 // Convert Shininess to PRIM_SHINY_* 8914 if (shinyness == Shininess.High)
8184 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8915 {
8185 // PRIM_BUMP_* 8916 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8186 res.Add(new LSL_Integer((int)texface.Bump)); 8917 }
8918 else if (shinyness == Shininess.Medium)
8919 {
8920 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8921 }
8922 else if (shinyness == Shininess.Low)
8923 {
8924 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8925 }
8926 else
8927 {
8928 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8929 }
8930 res.Add(new LSL_Integer(shiny));
8931 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8187 } 8932 }
8188 } 8933 }
8189 else 8934 else
8190 { 8935 {
8191 if (face >= 0 && face < GetNumberOfSides(part)) 8936 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8937 if (shinyness == Shininess.High)
8192 { 8938 {
8193 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8939 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8194 // Convert Shininess to PRIM_SHINY_*
8195 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8196 // PRIM_BUMP_*
8197 res.Add(new LSL_Integer((int)texface.Bump));
8198 } 8940 }
8941 else if (shinyness == Shininess.Medium)
8942 {
8943 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8944 }
8945 else if (shinyness == Shininess.Low)
8946 {
8947 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8948 }
8949 else
8950 {
8951 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8952 }
8953 res.Add(new LSL_Integer(shiny));
8954 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8199 } 8955 }
8200 break; 8956 break;
8201 8957
@@ -8203,24 +8959,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8203 if (remain < 1) 8959 if (remain < 1)
8204 return null; 8960 return null;
8205 8961
8206 face=(int)rules.GetLSLIntegerItem(idx++); 8962 face = (int)rules.GetLSLIntegerItem(idx++);
8207 8963
8208 tex = part.Shape.Textures; 8964 tex = part.Shape.Textures;
8965 int fullbright;
8209 if (face == ScriptBaseClass.ALL_SIDES) 8966 if (face == ScriptBaseClass.ALL_SIDES)
8210 { 8967 {
8211 for (face = 0; face < GetNumberOfSides(part); face++) 8968 for (face = 0; face < GetNumberOfSides(part); face++)
8212 { 8969 {
8213 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8970 if (tex.GetFace((uint)face).Fullbright == true)
8214 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8971 {
8972 fullbright = ScriptBaseClass.TRUE;
8973 }
8974 else
8975 {
8976 fullbright = ScriptBaseClass.FALSE;
8977 }
8978 res.Add(new LSL_Integer(fullbright));
8215 } 8979 }
8216 } 8980 }
8217 else 8981 else
8218 { 8982 {
8219 if (face >= 0 && face < GetNumberOfSides(part)) 8983 if (tex.GetFace((uint)face).Fullbright == true)
8220 { 8984 {
8221 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8985 fullbright = ScriptBaseClass.TRUE;
8222 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8986 }
8987 else
8988 {
8989 fullbright = ScriptBaseClass.FALSE;
8223 } 8990 }
8991 res.Add(new LSL_Integer(fullbright));
8224 } 8992 }
8225 break; 8993 break;
8226 8994
@@ -8242,27 +9010,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8242 break; 9010 break;
8243 9011
8244 case (int)ScriptBaseClass.PRIM_TEXGEN: 9012 case (int)ScriptBaseClass.PRIM_TEXGEN:
9013 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8245 if (remain < 1) 9014 if (remain < 1)
8246 return null; 9015 return null;
8247 9016
8248 face=(int)rules.GetLSLIntegerItem(idx++); 9017 face = (int)rules.GetLSLIntegerItem(idx++);
8249 9018
8250 tex = part.Shape.Textures; 9019 tex = part.Shape.Textures;
8251 if (face == ScriptBaseClass.ALL_SIDES) 9020 if (face == ScriptBaseClass.ALL_SIDES)
8252 { 9021 {
8253 for (face = 0; face < GetNumberOfSides(part); face++) 9022 for (face = 0; face < GetNumberOfSides(part); face++)
8254 { 9023 {
8255 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9024 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8256 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9025 {
8257 res.Add(new LSL_Integer((uint)texgen >> 1)); 9026 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9027 }
9028 else
9029 {
9030 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9031 }
8258 } 9032 }
8259 } 9033 }
8260 else 9034 else
8261 { 9035 {
8262 if (face >= 0 && face < GetNumberOfSides(part)) 9036 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8263 { 9037 {
8264 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9038 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8265 res.Add(new LSL_Integer((uint)texgen >> 1)); 9039 }
9040 else
9041 {
9042 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8266 } 9043 }
8267 } 9044 }
8268 break; 9045 break;
@@ -8286,24 +9063,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8286 if (remain < 1) 9063 if (remain < 1)
8287 return null; 9064 return null;
8288 9065
8289 face=(int)rules.GetLSLIntegerItem(idx++); 9066 face = (int)rules.GetLSLIntegerItem(idx++);
8290 9067
8291 tex = part.Shape.Textures; 9068 tex = part.Shape.Textures;
9069 float primglow;
8292 if (face == ScriptBaseClass.ALL_SIDES) 9070 if (face == ScriptBaseClass.ALL_SIDES)
8293 { 9071 {
8294 for (face = 0; face < GetNumberOfSides(part); face++) 9072 for (face = 0; face < GetNumberOfSides(part); face++)
8295 { 9073 {
8296 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9074 primglow = tex.GetFace((uint)face).Glow;
8297 res.Add(new LSL_Float(texface.Glow)); 9075 res.Add(new LSL_Float(primglow));
8298 } 9076 }
8299 } 9077 }
8300 else 9078 else
8301 { 9079 {
8302 if (face >= 0 && face < GetNumberOfSides(part)) 9080 primglow = tex.GetFace((uint)face).Glow;
8303 { 9081 res.Add(new LSL_Float(primglow));
8304 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8305 res.Add(new LSL_Float(texface.Glow));
8306 }
8307 } 9082 }
8308 break; 9083 break;
8309 9084
@@ -8315,15 +9090,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8315 textColor.B)); 9090 textColor.B));
8316 res.Add(new LSL_Float(textColor.A)); 9091 res.Add(new LSL_Float(textColor.A));
8317 break; 9092 break;
9093
8318 case (int)ScriptBaseClass.PRIM_NAME: 9094 case (int)ScriptBaseClass.PRIM_NAME:
8319 res.Add(new LSL_String(part.Name)); 9095 res.Add(new LSL_String(part.Name));
8320 break; 9096 break;
9097
8321 case (int)ScriptBaseClass.PRIM_DESC: 9098 case (int)ScriptBaseClass.PRIM_DESC:
8322 res.Add(new LSL_String(part.Description)); 9099 res.Add(new LSL_String(part.Description));
8323 break; 9100 break;
9101
8324 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9102 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8325 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9103 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8326 break; 9104 break;
9105
8327 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9106 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8328 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9107 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8329 break; 9108 break;
@@ -8934,8 +9713,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8934 // The function returns an ordered list 9713 // The function returns an ordered list
8935 // representing the tokens found in the supplied 9714 // representing the tokens found in the supplied
8936 // sources string. If two successive tokenizers 9715 // sources string. If two successive tokenizers
8937 // are encountered, then a NULL entry is added 9716 // are encountered, then a null-string entry is
8938 // to the list. 9717 // added to the list.
8939 // 9718 //
8940 // It is a precondition that the source and 9719 // It is a precondition that the source and
8941 // toekizer lisst are non-null. If they are null, 9720 // toekizer lisst are non-null. If they are null,
@@ -8943,7 +9722,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8943 // while their lengths are being determined. 9722 // while their lengths are being determined.
8944 // 9723 //
8945 // A small amount of working memoryis required 9724 // A small amount of working memoryis required
8946 // of approximately 8*#tokenizers. 9725 // of approximately 8*#tokenizers + 8*srcstrlen.
8947 // 9726 //
8948 // There are many ways in which this function 9727 // There are many ways in which this function
8949 // can be implemented, this implementation is 9728 // can be implemented, this implementation is
@@ -8959,155 +9738,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8959 // and eliminates redundant tokenizers as soon 9738 // and eliminates redundant tokenizers as soon
8960 // as is possible. 9739 // as is possible.
8961 // 9740 //
8962 // The implementation tries to avoid any copying 9741 // The implementation tries to minimize temporary
8963 // of arrays or other objects. 9742 // garbage generation.
8964 // </remarks> 9743 // </remarks>
8965 9744
8966 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9745 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8967 { 9746 {
8968 int beginning = 0; 9747 return ParseString2List(src, separators, spacers, true);
8969 int srclen = src.Length; 9748 }
8970 int seplen = separators.Length;
8971 object[] separray = separators.Data;
8972 int spclen = spacers.Length;
8973 object[] spcarray = spacers.Data;
8974 int mlen = seplen+spclen;
8975
8976 int[] offset = new int[mlen+1];
8977 bool[] active = new bool[mlen];
8978
8979 int best;
8980 int j;
8981
8982 // Initial capacity reduces resize cost
8983 9749
8984 LSL_List tokens = new LSL_List(); 9750 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9751 {
9752 int srclen = src.Length;
9753 int seplen = separators.Length;
9754 object[] separray = separators.Data;
9755 int spclen = spacers.Length;
9756 object[] spcarray = spacers.Data;
9757 int dellen = 0;
9758 string[] delarray = new string[seplen+spclen];
8985 9759
8986 // All entries are initially valid 9760 int outlen = 0;
9761 string[] outarray = new string[srclen*2+1];
8987 9762
8988 for (int i = 0; i < mlen; i++) 9763 int i, j;
8989 active[i] = true; 9764 string d;
8990 9765
8991 offset[mlen] = srclen; 9766 m_host.AddScriptLPS(1);
8992 9767
8993 while (beginning < srclen) 9768 /*
9769 * Convert separator and spacer lists to C# strings.
9770 * Also filter out null strings so we don't hang.
9771 */
9772 for (i = 0; i < seplen; i ++)
8994 { 9773 {
9774 d = separray[i].ToString();
9775 if (d.Length > 0)
9776 {
9777 delarray[dellen++] = d;
9778 }
9779 }
9780 seplen = dellen;
8995 9781
8996 best = mlen; // as bad as it gets 9782 for (i = 0; i < spclen; i ++)
9783 {
9784 d = spcarray[i].ToString();
9785 if (d.Length > 0)
9786 {
9787 delarray[dellen++] = d;
9788 }
9789 }
8997 9790
8998 // Scan for separators 9791 /*
9792 * Scan through source string from beginning to end.
9793 */
9794 for (i = 0;;)
9795 {
8999 9796
9000 for (j = 0; j < seplen; j++) 9797 /*
9798 * Find earliest delimeter in src starting at i (if any).
9799 */
9800 int earliestDel = -1;
9801 int earliestSrc = srclen;
9802 string earliestStr = null;
9803 for (j = 0; j < dellen; j ++)
9001 { 9804 {
9002 if (separray[j].ToString() == String.Empty) 9805 d = delarray[j];
9003 active[j] = false; 9806 if (d != null)
9004
9005 if (active[j])
9006 { 9807 {
9007 // scan all of the markers 9808 int index = src.IndexOf(d, i);
9008 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9809 if (index < 0)
9009 { 9810 {
9010 // not present at all 9811 delarray[j] = null; // delim nowhere in src, don't check it anymore
9011 active[j] = false;
9012 } 9812 }
9013 else 9813 else if (index < earliestSrc)
9014 { 9814 {
9015 // present and correct 9815 earliestSrc = index; // where delimeter starts in source string
9016 if (offset[j] < offset[best]) 9816 earliestDel = j; // where delimeter is in delarray[]
9017 { 9817 earliestStr = d; // the delimeter string from delarray[]
9018 // closest so far 9818 if (index == i) break; // can't do any better than found at beg of string
9019 best = j;
9020 if (offset[best] == beginning)
9021 break;
9022 }
9023 } 9819 }
9024 } 9820 }
9025 } 9821 }
9026 9822
9027 // Scan for spacers 9823 /*
9028 9824 * Output source string starting at i through start of earliest delimeter.
9029 if (offset[best] != beginning) 9825 */
9826 if (keepNulls || (earliestSrc > i))
9030 { 9827 {
9031 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9828 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9032 {
9033 if (spcarray[j-seplen].ToString() == String.Empty)
9034 active[j] = false;
9035
9036 if (active[j])
9037 {
9038 // scan all of the markers
9039 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9040 {
9041 // not present at all
9042 active[j] = false;
9043 }
9044 else
9045 {
9046 // present and correct
9047 if (offset[j] < offset[best])
9048 {
9049 // closest so far
9050 best = j;
9051 }
9052 }
9053 }
9054 }
9055 } 9829 }
9056 9830
9057 // This is the normal exit from the scanning loop 9831 /*
9832 * If no delimeter found at or after i, we're done scanning.
9833 */
9834 if (earliestDel < 0) break;
9058 9835
9059 if (best == mlen) 9836 /*
9837 * If delimeter was a spacer, output the spacer.
9838 */
9839 if (earliestDel >= seplen)
9060 { 9840 {
9061 // no markers were found on this pass 9841 outarray[outlen++] = earliestStr;
9062 // so we're pretty much done
9063 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9064 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9065 break;
9066 } 9842 }
9067 9843
9068 // Otherwise we just add the newly delimited token 9844 /*
9069 // and recalculate where the search should continue. 9845 * Look at rest of src string following delimeter.
9070 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9846 */
9071 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9847 i = earliestSrc + earliestStr.Length;
9072
9073 if (best < seplen)
9074 {
9075 beginning = offset[best] + (separray[best].ToString()).Length;
9076 }
9077 else
9078 {
9079 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9080 string str = spcarray[best - seplen].ToString();
9081 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9082 tokens.Add(new LSL_String(str));
9083 }
9084 } 9848 }
9085 9849
9086 // This an awkward an not very intuitive boundary case. If the 9850 /*
9087 // last substring is a tokenizer, then there is an implied trailing 9851 * Make up an exact-sized output array suitable for an LSL_List object.
9088 // null list entry. Hopefully the single comparison will not be too 9852 */
9089 // arduous. Alternatively the 'break' could be replced with a return 9853 object[] outlist = new object[outlen];
9090 // but that's shabby programming. 9854 for (i = 0; i < outlen; i ++)
9091
9092 if ((beginning == srclen) && (keepNulls))
9093 { 9855 {
9094 if (srclen != 0) 9856 outlist[i] = new LSL_String(outarray[i]);
9095 tokens.Add(new LSL_String(""));
9096 } 9857 }
9097 9858 return new LSL_List(outlist);
9098 return tokens;
9099 }
9100
9101 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9102 {
9103 m_host.AddScriptLPS(1);
9104 return this.ParseString(src, separators, spacers, false);
9105 }
9106
9107 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9108 {
9109 m_host.AddScriptLPS(1);
9110 return this.ParseString(src, separators, spacers, true);
9111 } 9859 }
9112 9860
9113 public LSL_Integer llGetObjectPermMask(int mask) 9861 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9202,6 +9950,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9202 case 4: 9950 case 4:
9203 return (int)item.NextPermissions; 9951 return (int)item.NextPermissions;
9204 } 9952 }
9953 m_host.TaskInventory.LockItemsForRead(false);
9205 9954
9206 return -1; 9955 return -1;
9207 } 9956 }
@@ -9392,9 +10141,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9392 { 10141 {
9393 try 10142 try
9394 { 10143 {
10144 /*
9395 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10145 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9396 if (obj != null) 10146 if (obj != null)
9397 return (double)obj.GetMass(); 10147 return (double)obj.GetMass();
10148 */
10149 // return total object mass
10150 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10151 if (obj != null)
10152 return obj.GetMass();
10153
9398 // the object is null so the key is for an avatar 10154 // the object is null so the key is for an avatar
9399 ScenePresence avatar = World.GetScenePresence(key); 10155 ScenePresence avatar = World.GetScenePresence(key);
9400 if (avatar != null) 10156 if (avatar != null)
@@ -9414,7 +10170,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9414 } 10170 }
9415 10171
9416 /// <summary> 10172 /// <summary>
9417 /// illListReplaceList removes the sub-list defined by the inclusive indices 10173 /// llListReplaceList removes the sub-list defined by the inclusive indices
9418 /// start and end and inserts the src list in its place. The inclusive 10174 /// start and end and inserts the src list in its place. The inclusive
9419 /// nature of the indices means that at least one element must be deleted 10175 /// nature of the indices means that at least one element must be deleted
9420 /// if the indices are within the bounds of the existing list. I.e. 2,2 10176 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9471,16 +10227,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9471 // based upon end. Note that if end exceeds the upper 10227 // based upon end. Note that if end exceeds the upper
9472 // bound in this case, the entire destination list 10228 // bound in this case, the entire destination list
9473 // is removed. 10229 // is removed.
9474 else 10230 else if (start == 0)
9475 { 10231 {
9476 if (end + 1 < dest.Length) 10232 if (end + 1 < dest.Length)
9477 {
9478 return src + dest.GetSublist(end + 1, -1); 10233 return src + dest.GetSublist(end + 1, -1);
9479 }
9480 else 10234 else
9481 {
9482 return src; 10235 return src;
9483 } 10236 }
10237 else // Start < 0
10238 {
10239 if (end + 1 < dest.Length)
10240 return dest.GetSublist(end + 1, -1);
10241 else
10242 return new LSL_List();
9484 } 10243 }
9485 } 10244 }
9486 // Finally, if start > end, we strip away a prefix and 10245 // Finally, if start > end, we strip away a prefix and
@@ -9531,17 +10290,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9531 int width = 0; 10290 int width = 0;
9532 int height = 0; 10291 int height = 0;
9533 10292
9534 ParcelMediaCommandEnum? commandToSend = null; 10293 uint commandToSend = 0;
9535 float time = 0.0f; // default is from start 10294 float time = 0.0f; // default is from start
9536 10295
9537 ScenePresence presence = null; 10296 ScenePresence presence = null;
9538 10297
9539 for (int i = 0; i < commandList.Data.Length; i++) 10298 for (int i = 0; i < commandList.Data.Length; i++)
9540 { 10299 {
9541 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10300 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9542 switch (command) 10301 switch (command)
9543 { 10302 {
9544 case ParcelMediaCommandEnum.Agent: 10303 case (uint)ParcelMediaCommandEnum.Agent:
9545 // we send only to one agent 10304 // we send only to one agent
9546 if ((i + 1) < commandList.Length) 10305 if ((i + 1) < commandList.Length)
9547 { 10306 {
@@ -9558,25 +10317,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9558 } 10317 }
9559 break; 10318 break;
9560 10319
9561 case ParcelMediaCommandEnum.Loop: 10320 case (uint)ParcelMediaCommandEnum.Loop:
9562 loop = 1; 10321 loop = 1;
9563 commandToSend = command; 10322 commandToSend = command;
9564 update = true; //need to send the media update packet to set looping 10323 update = true; //need to send the media update packet to set looping
9565 break; 10324 break;
9566 10325
9567 case ParcelMediaCommandEnum.Play: 10326 case (uint)ParcelMediaCommandEnum.Play:
9568 loop = 0; 10327 loop = 0;
9569 commandToSend = command; 10328 commandToSend = command;
9570 update = true; //need to send the media update packet to make sure it doesn't loop 10329 update = true; //need to send the media update packet to make sure it doesn't loop
9571 break; 10330 break;
9572 10331
9573 case ParcelMediaCommandEnum.Pause: 10332 case (uint)ParcelMediaCommandEnum.Pause:
9574 case ParcelMediaCommandEnum.Stop: 10333 case (uint)ParcelMediaCommandEnum.Stop:
9575 case ParcelMediaCommandEnum.Unload: 10334 case (uint)ParcelMediaCommandEnum.Unload:
9576 commandToSend = command; 10335 commandToSend = command;
9577 break; 10336 break;
9578 10337
9579 case ParcelMediaCommandEnum.Url: 10338 case (uint)ParcelMediaCommandEnum.Url:
9580 if ((i + 1) < commandList.Length) 10339 if ((i + 1) < commandList.Length)
9581 { 10340 {
9582 if (commandList.Data[i + 1] is LSL_String) 10341 if (commandList.Data[i + 1] is LSL_String)
@@ -9589,7 +10348,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9589 } 10348 }
9590 break; 10349 break;
9591 10350
9592 case ParcelMediaCommandEnum.Texture: 10351 case (uint)ParcelMediaCommandEnum.Texture:
9593 if ((i + 1) < commandList.Length) 10352 if ((i + 1) < commandList.Length)
9594 { 10353 {
9595 if (commandList.Data[i + 1] is LSL_String) 10354 if (commandList.Data[i + 1] is LSL_String)
@@ -9602,7 +10361,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9602 } 10361 }
9603 break; 10362 break;
9604 10363
9605 case ParcelMediaCommandEnum.Time: 10364 case (uint)ParcelMediaCommandEnum.Time:
9606 if ((i + 1) < commandList.Length) 10365 if ((i + 1) < commandList.Length)
9607 { 10366 {
9608 if (commandList.Data[i + 1] is LSL_Float) 10367 if (commandList.Data[i + 1] is LSL_Float)
@@ -9614,7 +10373,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9614 } 10373 }
9615 break; 10374 break;
9616 10375
9617 case ParcelMediaCommandEnum.AutoAlign: 10376 case (uint)ParcelMediaCommandEnum.AutoAlign:
9618 if ((i + 1) < commandList.Length) 10377 if ((i + 1) < commandList.Length)
9619 { 10378 {
9620 if (commandList.Data[i + 1] is LSL_Integer) 10379 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9628,7 +10387,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9628 } 10387 }
9629 break; 10388 break;
9630 10389
9631 case ParcelMediaCommandEnum.Type: 10390 case (uint)ParcelMediaCommandEnum.Type:
9632 if ((i + 1) < commandList.Length) 10391 if ((i + 1) < commandList.Length)
9633 { 10392 {
9634 if (commandList.Data[i + 1] is LSL_String) 10393 if (commandList.Data[i + 1] is LSL_String)
@@ -9641,7 +10400,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9641 } 10400 }
9642 break; 10401 break;
9643 10402
9644 case ParcelMediaCommandEnum.Desc: 10403 case (uint)ParcelMediaCommandEnum.Desc:
9645 if ((i + 1) < commandList.Length) 10404 if ((i + 1) < commandList.Length)
9646 { 10405 {
9647 if (commandList.Data[i + 1] is LSL_String) 10406 if (commandList.Data[i + 1] is LSL_String)
@@ -9654,7 +10413,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9654 } 10413 }
9655 break; 10414 break;
9656 10415
9657 case ParcelMediaCommandEnum.Size: 10416 case (uint)ParcelMediaCommandEnum.Size:
9658 if ((i + 2) < commandList.Length) 10417 if ((i + 2) < commandList.Length)
9659 { 10418 {
9660 if (commandList.Data[i + 1] is LSL_Integer) 10419 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9724,7 +10483,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9724 } 10483 }
9725 } 10484 }
9726 10485
9727 if (commandToSend != null) 10486 if (commandToSend != 0)
9728 { 10487 {
9729 // the commandList contained a start/stop/... command, too 10488 // the commandList contained a start/stop/... command, too
9730 if (presence == null) 10489 if (presence == null)
@@ -9761,7 +10520,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9761 10520
9762 if (aList.Data[i] != null) 10521 if (aList.Data[i] != null)
9763 { 10522 {
9764 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10523 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9765 { 10524 {
9766 case ParcelMediaCommandEnum.Url: 10525 case ParcelMediaCommandEnum.Url:
9767 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10526 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9818,15 +10577,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9818 10577
9819 if (quick_pay_buttons.Data.Length < 4) 10578 if (quick_pay_buttons.Data.Length < 4)
9820 { 10579 {
9821 LSLError("List must have at least 4 elements"); 10580 int x;
9822 return; 10581 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10582 {
10583 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10584 }
9823 } 10585 }
9824 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10586 int[] nPrice = new int[5];
9825 10587 nPrice[0] = price;
9826 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10588 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9827 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10589 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9828 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10590 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9829 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10591 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10592 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9830 m_host.ParentGroup.HasGroupChanged = true; 10593 m_host.ParentGroup.HasGroupChanged = true;
9831 } 10594 }
9832 10595
@@ -9843,7 +10606,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9843 return new LSL_Vector(); 10606 return new LSL_Vector();
9844 } 10607 }
9845 10608
9846 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10609// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10610 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9847 if (presence != null) 10611 if (presence != null)
9848 { 10612 {
9849 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10613 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9865,7 +10629,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9865 return new LSL_Rotation(); 10629 return new LSL_Rotation();
9866 } 10630 }
9867 10631
9868 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10632// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10633 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9869 if (presence != null) 10634 if (presence != null)
9870 { 10635 {
9871 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10636 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9925,14 +10690,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9925 { 10690 {
9926 m_host.AddScriptLPS(1); 10691 m_host.AddScriptLPS(1);
9927 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10692 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9928 if (detectedParams == null) return; // only works on the first detected avatar 10693 if (detectedParams == null)
9929 10694 {
10695 if (m_host.ParentGroup.IsAttachment == true)
10696 {
10697 detectedParams = new DetectParams();
10698 detectedParams.Key = m_host.OwnerID;
10699 }
10700 else
10701 {
10702 return;
10703 }
10704 }
10705
9930 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10706 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9931 if (avatar != null) 10707 if (avatar != null)
9932 { 10708 {
9933 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10709 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9934 simname, pos, lookAt); 10710 simname, pos, lookAt);
9935 } 10711 }
10712
9936 ScriptSleep(1000); 10713 ScriptSleep(1000);
9937 } 10714 }
9938 10715
@@ -10056,12 +10833,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10056 10833
10057 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10834 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10058 object[] data = rules.Data; 10835 object[] data = rules.Data;
10059 for (int i = 0; i < data.Length; ++i) { 10836 for (int i = 0; i < data.Length; ++i)
10837 {
10060 int type = Convert.ToInt32(data[i++].ToString()); 10838 int type = Convert.ToInt32(data[i++].ToString());
10061 if (i >= data.Length) break; // odd number of entries => ignore the last 10839 if (i >= data.Length) break; // odd number of entries => ignore the last
10062 10840
10063 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10841 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10064 switch (type) { 10842 switch (type)
10843 {
10065 case ScriptBaseClass.CAMERA_FOCUS: 10844 case ScriptBaseClass.CAMERA_FOCUS:
10066 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10845 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10067 case ScriptBaseClass.CAMERA_POSITION: 10846 case ScriptBaseClass.CAMERA_POSITION:
@@ -10167,19 +10946,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10167 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10946 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10168 { 10947 {
10169 m_host.AddScriptLPS(1); 10948 m_host.AddScriptLPS(1);
10170 string ret = String.Empty; 10949
10171 string src1 = llBase64ToString(str1); 10950 if (str1 == String.Empty)
10172 string src2 = llBase64ToString(str2); 10951 return String.Empty;
10173 int c = 0; 10952 if (str2 == String.Empty)
10174 for (int i = 0; i < src1.Length; i++) 10953 return str1;
10954
10955 int len = str2.Length;
10956 if ((len % 4) != 0) // LL is EVIL!!!!
10175 { 10957 {
10176 ret += (char) (src1[i] ^ src2[c]); 10958 while (str2.EndsWith("="))
10959 str2 = str2.Substring(0, str2.Length - 1);
10960
10961 len = str2.Length;
10962 int mod = len % 4;
10963
10964 if (mod == 1)
10965 str2 = str2.Substring(0, str2.Length - 1);
10966 else if (mod == 2)
10967 str2 += "==";
10968 else if (mod == 3)
10969 str2 += "=";
10970 }
10177 10971
10178 c++; 10972 byte[] data1;
10179 if (c >= src2.Length) 10973 byte[] data2;
10180 c = 0; 10974 try
10975 {
10976 data1 = Convert.FromBase64String(str1);
10977 data2 = Convert.FromBase64String(str2);
10181 } 10978 }
10182 return llStringToBase64(ret); 10979 catch (Exception)
10980 {
10981 return new LSL_String(String.Empty);
10982 }
10983
10984 byte[] d2 = new Byte[data1.Length];
10985 int pos = 0;
10986
10987 if (data1.Length <= data2.Length)
10988 {
10989 Array.Copy(data2, 0, d2, 0, data1.Length);
10990 }
10991 else
10992 {
10993 while (pos < data1.Length)
10994 {
10995 len = data1.Length - pos;
10996 if (len > data2.Length)
10997 len = data2.Length;
10998
10999 Array.Copy(data2, 0, d2, pos, len);
11000 pos += len;
11001 }
11002 }
11003
11004 for (pos = 0 ; pos < data1.Length ; pos++ )
11005 data1[pos] ^= d2[pos];
11006
11007 return Convert.ToBase64String(data1);
10183 } 11008 }
10184 11009
10185 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11010 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10232,16 +11057,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10232 if (userAgent != null) 11057 if (userAgent != null)
10233 httpHeaders["User-Agent"] = userAgent; 11058 httpHeaders["User-Agent"] = userAgent;
10234 11059
11060 // See if the URL contains any header hacks
11061 string[] urlParts = url.Split(new char[] {'\n'});
11062 if (urlParts.Length > 1)
11063 {
11064 // Iterate the passed headers and parse them
11065 for (int i = 1 ; i < urlParts.Length ; i++ )
11066 {
11067 // The rest of those would be added to the body in SL.
11068 // Let's not do that.
11069 if (urlParts[i] == String.Empty)
11070 break;
11071
11072 // See if this could be a valid header
11073 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11074 if (headerParts.Length != 2)
11075 continue;
11076
11077 string headerName = headerParts[0].Trim();
11078 string headerValue = headerParts[1].Trim();
11079
11080 // Filter out headers that could be used to abuse
11081 // another system or cloak the request
11082 if (headerName.ToLower() == "x-secondlife-shard" ||
11083 headerName.ToLower() == "x-secondlife-object-name" ||
11084 headerName.ToLower() == "x-secondlife-object-key" ||
11085 headerName.ToLower() == "x-secondlife-region" ||
11086 headerName.ToLower() == "x-secondlife-local-position" ||
11087 headerName.ToLower() == "x-secondlife-local-velocity" ||
11088 headerName.ToLower() == "x-secondlife-local-rotation" ||
11089 headerName.ToLower() == "x-secondlife-owner-name" ||
11090 headerName.ToLower() == "x-secondlife-owner-key" ||
11091 headerName.ToLower() == "connection" ||
11092 headerName.ToLower() == "content-length" ||
11093 headerName.ToLower() == "from" ||
11094 headerName.ToLower() == "host" ||
11095 headerName.ToLower() == "proxy-authorization" ||
11096 headerName.ToLower() == "referer" ||
11097 headerName.ToLower() == "trailer" ||
11098 headerName.ToLower() == "transfer-encoding" ||
11099 headerName.ToLower() == "via" ||
11100 headerName.ToLower() == "authorization")
11101 continue;
11102
11103 httpHeaders[headerName] = headerValue;
11104 }
11105
11106 // Finally, strip any protocol specifier from the URL
11107 url = urlParts[0].Trim();
11108 int idx = url.IndexOf(" HTTP/");
11109 if (idx != -1)
11110 url = url.Substring(0, idx);
11111 }
11112
10235 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11113 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10236 Regex r = new Regex(authregex); 11114 Regex r = new Regex(authregex);
10237 int[] gnums = r.GetGroupNumbers(); 11115 int[] gnums = r.GetGroupNumbers();
10238 Match m = r.Match(url); 11116 Match m = r.Match(url);
10239 if (m.Success) { 11117 if (m.Success)
10240 for (int i = 1; i < gnums.Length; i++) { 11118 {
11119 for (int i = 1; i < gnums.Length; i++)
11120 {
10241 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11121 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10242 //CaptureCollection cc = g.Captures; 11122 //CaptureCollection cc = g.Captures;
10243 } 11123 }
10244 if (m.Groups.Count == 5) { 11124 if (m.Groups.Count == 5)
11125 {
10245 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11126 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10246 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11127 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10247 } 11128 }
@@ -10444,6 +11325,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10444 11325
10445 LSL_List ret = new LSL_List(); 11326 LSL_List ret = new LSL_List();
10446 UUID key = new UUID(); 11327 UUID key = new UUID();
11328
11329
10447 if (UUID.TryParse(id, out key)) 11330 if (UUID.TryParse(id, out key))
10448 { 11331 {
10449 ScenePresence av = World.GetScenePresence(key); 11332 ScenePresence av = World.GetScenePresence(key);
@@ -10461,13 +11344,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10461 ret.Add(new LSL_String("")); 11344 ret.Add(new LSL_String(""));
10462 break; 11345 break;
10463 case ScriptBaseClass.OBJECT_POS: 11346 case ScriptBaseClass.OBJECT_POS:
10464 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11347 Vector3 avpos;
11348
11349 if (av.ParentID != 0 && av.ParentPart != null)
11350 {
11351 avpos = av.OffsetPosition;
11352
11353 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11354 avpos -= sitOffset;
11355
11356 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11357 }
11358 else
11359 avpos = av.AbsolutePosition;
11360
11361 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10465 break; 11362 break;
10466 case ScriptBaseClass.OBJECT_ROT: 11363 case ScriptBaseClass.OBJECT_ROT:
10467 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11364 Quaternion avrot = av.Rotation;
11365 if (av.ParentID != 0 && av.ParentPart != null)
11366 {
11367 avrot = av.ParentPart.GetWorldRotation() * avrot;
11368 }
11369 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10468 break; 11370 break;
10469 case ScriptBaseClass.OBJECT_VELOCITY: 11371 case ScriptBaseClass.OBJECT_VELOCITY:
10470 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11372 Vector3 avvel = av.Velocity;
11373 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10471 break; 11374 break;
10472 case ScriptBaseClass.OBJECT_OWNER: 11375 case ScriptBaseClass.OBJECT_OWNER:
10473 ret.Add(new LSL_String(id)); 11376 ret.Add(new LSL_String(id));
@@ -10523,11 +11426,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10523 case ScriptBaseClass.OBJECT_NAME: 11426 case ScriptBaseClass.OBJECT_NAME:
10524 ret.Add(new LSL_String(obj.Name)); 11427 ret.Add(new LSL_String(obj.Name));
10525 break; 11428 break;
10526 case ScriptBaseClass.OBJECT_DESC: 11429 case ScriptBaseClass.OBJECT_DESC:
10527 ret.Add(new LSL_String(obj.Description)); 11430 ret.Add(new LSL_String(obj.Description));
10528 break; 11431 break;
10529 case ScriptBaseClass.OBJECT_POS: 11432 case ScriptBaseClass.OBJECT_POS:
10530 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11433 Vector3 opos = obj.AbsolutePosition;
11434 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10531 break; 11435 break;
10532 case ScriptBaseClass.OBJECT_ROT: 11436 case ScriptBaseClass.OBJECT_ROT:
10533 { 11437 {
@@ -10577,9 +11481,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10577 // The value returned in SL for normal prims is prim count 11481 // The value returned in SL for normal prims is prim count
10578 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11482 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10579 break; 11483 break;
10580 // The following 3 costs I have intentionaly coded to return zero. They are part of 11484
10581 // "Land Impact" calculations. These calculations are probably not applicable 11485 // costs below may need to be diferent for root parts, need to check
10582 // to OpenSim and are not yet complete in SL
10583 case ScriptBaseClass.OBJECT_SERVER_COST: 11486 case ScriptBaseClass.OBJECT_SERVER_COST:
10584 // The linden calculation is here 11487 // The linden calculation is here
10585 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11488 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10587,16 +11490,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10587 ret.Add(new LSL_Float(0)); 11490 ret.Add(new LSL_Float(0));
10588 break; 11491 break;
10589 case ScriptBaseClass.OBJECT_STREAMING_COST: 11492 case ScriptBaseClass.OBJECT_STREAMING_COST:
10590 // The linden calculation is here 11493 // The value returned in SL for normal prims is prim count * 0.06
10591 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11494 ret.Add(new LSL_Float(obj.StreamingCost));
10592 // The value returned in SL for normal prims looks like the prim count * 0.06
10593 ret.Add(new LSL_Float(0));
10594 break; 11495 break;
10595 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11496 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10596 // The linden calculation is here 11497 // The value returned in SL for normal prims is prim count
10597 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11498 ret.Add(new LSL_Float(obj.PhysicsCost));
10598 // The value returned in SL for normal prims looks like the prim count
10599 ret.Add(new LSL_Float(0));
10600 break; 11499 break;
10601 default: 11500 default:
10602 // Invalid or unhandled constant. 11501 // Invalid or unhandled constant.
@@ -10806,15 +11705,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10806 return result; 11705 return result;
10807 } 11706 }
10808 11707
10809 public void print(string str) 11708 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10810 { 11709 {
10811 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11710 List<SceneObjectPart> parts = GetLinkParts(link);
10812 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11711 if (parts.Count < 1)
10813 if (ossl != null) 11712 return 0;
10814 { 11713
10815 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11714 return GetNumberOfSides(parts[0]);
10816 m_log.Info("LSL print():" + str);
10817 }
10818 } 11715 }
10819 11716
10820 private string Name2Username(string name) 11717 private string Name2Username(string name)
@@ -10859,7 +11756,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10859 11756
10860 return rq.ToString(); 11757 return rq.ToString();
10861 } 11758 }
10862 11759/*
11760 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11761 {
11762 m_SayShoutCount = 0;
11763 }
11764*/
10863 private struct Tri 11765 private struct Tri
10864 { 11766 {
10865 public Vector3 p1; 11767 public Vector3 p1;
@@ -10999,9 +11901,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10999 11901
11000 ContactResult result = new ContactResult (); 11902 ContactResult result = new ContactResult ();
11001 result.ConsumerID = group.LocalId; 11903 result.ConsumerID = group.LocalId;
11002 result.Depth = intersection.distance; 11904// result.Depth = intersection.distance;
11003 result.Normal = intersection.normal; 11905 result.Normal = intersection.normal;
11004 result.Pos = intersection.ipoint; 11906 result.Pos = intersection.ipoint;
11907 result.Depth = Vector3.Mag(rayStart - result.Pos);
11005 11908
11006 contacts.Add(result); 11909 contacts.Add(result);
11007 }); 11910 });
@@ -11134,6 +12037,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11134 12037
11135 return contacts[0]; 12038 return contacts[0];
11136 } 12039 }
12040/*
12041 // not done:
12042 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12043 {
12044 ContactResult[] contacts = null;
12045 World.ForEachSOG(delegate(SceneObjectGroup group)
12046 {
12047 if (m_host.ParentGroup == group)
12048 return;
12049
12050 if (group.IsAttachment)
12051 return;
12052
12053 if(group.RootPart.PhysActor != null)
12054 return;
12055
12056 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12057 });
12058 return contacts;
12059 }
12060*/
11137 12061
11138 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12062 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11139 { 12063 {
@@ -11175,32 +12099,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11175 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12099 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11176 12100
11177 12101
11178 if (checkTerrain) 12102 if (World.SuportsRayCastFiltered())
11179 { 12103 {
11180 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12104 if (dist == 0)
11181 if (groundContact != null) 12105 return list;
11182 results.Add((ContactResult)groundContact);
11183 }
11184 12106
11185 if (checkAgents) 12107 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11186 { 12108 if (checkTerrain)
11187 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12109 rayfilter |= RayFilterFlags.land;
11188 foreach (ContactResult r in agentHits) 12110// if (checkAgents)
11189 results.Add(r); 12111// rayfilter |= RayFilterFlags.agent;
11190 } 12112 if (checkPhysical)
12113 rayfilter |= RayFilterFlags.physical;
12114 if (checkNonPhysical)
12115 rayfilter |= RayFilterFlags.nonphysical;
12116 if (detectPhantom)
12117 rayfilter |= RayFilterFlags.LSLPhanton;
12118
12119 Vector3 direction = dir * ( 1/dist);
12120
12121 if(rayfilter == 0)
12122 {
12123 list.Add(new LSL_Integer(0));
12124 return list;
12125 }
12126
12127 // get some more contacts to sort ???
12128 int physcount = 4 * count;
12129 if (physcount > 20)
12130 physcount = 20;
11191 12131
11192 if (checkPhysical || checkNonPhysical || detectPhantom) 12132 object physresults;
12133 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12134
12135 if (physresults == null)
12136 {
12137 list.Add(new LSL_Integer(-3)); // timeout error
12138 return list;
12139 }
12140
12141 results = (List<ContactResult>)physresults;
12142
12143 // for now physics doesn't detect sitted avatars so do it outside physics
12144 if (checkAgents)
12145 {
12146 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12147 foreach (ContactResult r in agentHits)
12148 results.Add(r);
12149 }
12150
12151 // TODO: Replace this with a better solution. ObjectIntersection can only
12152 // detect nonphysical phantoms. They are detected by virtue of being
12153 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12154 // physicsl phantoms as done by the physics scene
12155 // We don't want anything else but phantoms here.
12156 if (detectPhantom)
12157 {
12158 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12159 foreach (ContactResult r in objectHits)
12160 results.Add(r);
12161 }
12162 }
12163 else
11193 { 12164 {
11194 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12165 if (checkTerrain)
11195 foreach (ContactResult r in objectHits) 12166 {
11196 results.Add(r); 12167 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12168 if (groundContact != null)
12169 results.Add((ContactResult)groundContact);
12170 }
12171
12172 if (checkAgents)
12173 {
12174 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12175 foreach (ContactResult r in agentHits)
12176 results.Add(r);
12177 }
12178
12179 if (checkPhysical || checkNonPhysical || detectPhantom)
12180 {
12181 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12182 foreach (ContactResult r in objectHits)
12183 results.Add(r);
12184 }
11197 } 12185 }
11198 12186
11199 results.Sort(delegate(ContactResult a, ContactResult b) 12187 results.Sort(delegate(ContactResult a, ContactResult b)
11200 { 12188 {
11201 return a.Depth.CompareTo(b.Depth); 12189 return a.Depth.CompareTo(b.Depth);
11202 }); 12190 });
11203 12191
11204 int values = 0; 12192 int values = 0;
11205 SceneObjectGroup thisgrp = m_host.ParentGroup; 12193 SceneObjectGroup thisgrp = m_host.ParentGroup;
11206 12194
@@ -11293,7 +12281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11293 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12281 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11294 if (!isAccount) return 0; 12282 if (!isAccount) return 0;
11295 if (estate.HasAccess(id)) return 1; 12283 if (estate.HasAccess(id)) return 1;
11296 if (estate.IsBanned(id)) 12284 if (estate.IsBanned(id, World.GetUserFlags(id)))
11297 estate.RemoveBan(id); 12285 estate.RemoveBan(id);
11298 estate.AddEstateUser(id); 12286 estate.AddEstateUser(id);
11299 break; 12287 break;
@@ -11312,14 +12300,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11312 break; 12300 break;
11313 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12301 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11314 if (!isAccount) return 0; 12302 if (!isAccount) return 0;
11315 if (estate.IsBanned(id)) return 1; 12303 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11316 EstateBan ban = new EstateBan(); 12304 EstateBan ban = new EstateBan();
11317 ban.EstateID = estate.EstateID; 12305 ban.EstateID = estate.EstateID;
11318 ban.BannedUserID = id; 12306 ban.BannedUserID = id;
11319 estate.AddBan(ban); 12307 estate.AddBan(ban);
11320 break; 12308 break;
11321 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12309 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11322 if (!isAccount || !estate.IsBanned(id)) return 0; 12310 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11323 estate.RemoveBan(id); 12311 estate.RemoveBan(id);
11324 break; 12312 break;
11325 default: return 0; 12313 default: return 0;
@@ -11348,7 +12336,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11348 return 16384; 12336 return 16384;
11349 } 12337 }
11350 12338
11351 public LSL_Integer llGetUsedMemory() 12339 public virtual LSL_Integer llGetUsedMemory()
11352 { 12340 {
11353 m_host.AddScriptLPS(1); 12341 m_host.AddScriptLPS(1);
11354 // The value returned for LSO scripts in SL 12342 // The value returned for LSO scripts in SL
@@ -11376,7 +12364,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11376 public void llSetSoundQueueing(int queue) 12364 public void llSetSoundQueueing(int queue)
11377 { 12365 {
11378 m_host.AddScriptLPS(1); 12366 m_host.AddScriptLPS(1);
11379 NotImplemented("llSetSoundQueueing");
11380 } 12367 }
11381 12368
11382 public void llCollisionSprite(string impact_sprite) 12369 public void llCollisionSprite(string impact_sprite)
@@ -11388,10 +12375,711 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11388 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12375 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11389 { 12376 {
11390 m_host.AddScriptLPS(1); 12377 m_host.AddScriptLPS(1);
11391 NotImplemented("llGodLikeRezObject"); 12378
12379 if (!World.Permissions.IsGod(m_host.OwnerID))
12380 NotImplemented("llGodLikeRezObject");
12381
12382 AssetBase rezAsset = World.AssetService.Get(inventory);
12383 if (rezAsset == null)
12384 {
12385 llSay(0, "Asset not found");
12386 return;
12387 }
12388
12389 SceneObjectGroup group = null;
12390
12391 try
12392 {
12393 string xmlData = Utils.BytesToString(rezAsset.Data);
12394 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12395 }
12396 catch
12397 {
12398 llSay(0, "Asset not found");
12399 return;
12400 }
12401
12402 if (group == null)
12403 {
12404 llSay(0, "Asset not found");
12405 return;
12406 }
12407
12408 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12409 group.RootPart.AttachOffset = group.AbsolutePosition;
12410
12411 group.ResetIDs();
12412
12413 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12414 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12415 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12416 group.ScheduleGroupForFullUpdate();
12417
12418 // objects rezzed with this method are die_at_edge by default.
12419 group.RootPart.SetDieAtEdge(true);
12420
12421 group.ResumeScripts();
12422
12423 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12424 "object_rez", new Object[] {
12425 new LSL_String(
12426 group.RootPart.UUID.ToString()) },
12427 new DetectParams[0]));
12428 }
12429
12430 public LSL_String llTransferLindenDollars(string destination, int amount)
12431 {
12432 UUID txn = UUID.Random();
12433
12434 Util.FireAndForget(delegate(object x)
12435 {
12436 int replycode = 0;
12437 string replydata = destination + "," + amount.ToString();
12438
12439 try
12440 {
12441 TaskInventoryItem item = m_item;
12442 if (item == null)
12443 {
12444 replydata = "SERVICE_ERROR";
12445 return;
12446 }
12447
12448 m_host.AddScriptLPS(1);
12449
12450 if (item.PermsGranter == UUID.Zero)
12451 {
12452 replydata = "MISSING_PERMISSION_DEBIT";
12453 return;
12454 }
12455
12456 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12457 {
12458 replydata = "MISSING_PERMISSION_DEBIT";
12459 return;
12460 }
12461
12462 UUID toID = new UUID();
12463
12464 if (!UUID.TryParse(destination, out toID))
12465 {
12466 replydata = "INVALID_AGENT";
12467 return;
12468 }
12469
12470 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12471
12472 if (money == null)
12473 {
12474 replydata = "TRANSFERS_DISABLED";
12475 return;
12476 }
12477
12478 bool result = money.ObjectGiveMoney(
12479 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12480
12481 if (result)
12482 {
12483 replycode = 1;
12484 return;
12485 }
12486
12487 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12488 }
12489 finally
12490 {
12491 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12492 "transaction_result", new Object[] {
12493 new LSL_String(txn.ToString()),
12494 new LSL_Integer(replycode),
12495 new LSL_String(replydata) },
12496 new DetectParams[0]));
12497 }
12498 });
12499
12500 return txn.ToString();
11392 } 12501 }
11393 12502
11394 #endregion 12503 #endregion
12504
12505 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12506 {
12507 SceneObjectGroup group = m_host.ParentGroup;
12508
12509 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12510 return;
12511 if (group.IsAttachment)
12512 return;
12513
12514 if (frames.Data.Length > 0) // We are getting a new motion
12515 {
12516 if (group.RootPart.KeyframeMotion != null)
12517 group.RootPart.KeyframeMotion.Stop();
12518 group.RootPart.KeyframeMotion = null;
12519
12520 int idx = 0;
12521
12522 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12523 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12524
12525 while (idx < options.Data.Length)
12526 {
12527 int option = (int)options.GetLSLIntegerItem(idx++);
12528 int remain = options.Data.Length - idx;
12529
12530 switch (option)
12531 {
12532 case ScriptBaseClass.KFM_MODE:
12533 if (remain < 1)
12534 break;
12535 int modeval = (int)options.GetLSLIntegerItem(idx++);
12536 switch(modeval)
12537 {
12538 case ScriptBaseClass.KFM_FORWARD:
12539 mode = KeyframeMotion.PlayMode.Forward;
12540 break;
12541 case ScriptBaseClass.KFM_REVERSE:
12542 mode = KeyframeMotion.PlayMode.Reverse;
12543 break;
12544 case ScriptBaseClass.KFM_LOOP:
12545 mode = KeyframeMotion.PlayMode.Loop;
12546 break;
12547 case ScriptBaseClass.KFM_PING_PONG:
12548 mode = KeyframeMotion.PlayMode.PingPong;
12549 break;
12550 }
12551 break;
12552 case ScriptBaseClass.KFM_DATA:
12553 if (remain < 1)
12554 break;
12555 int dataval = (int)options.GetLSLIntegerItem(idx++);
12556 data = (KeyframeMotion.DataFormat)dataval;
12557 break;
12558 }
12559 }
12560
12561 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12562
12563 idx = 0;
12564
12565 int elemLength = 2;
12566 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12567 elemLength = 3;
12568
12569 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12570 while (idx < frames.Data.Length)
12571 {
12572 int remain = frames.Data.Length - idx;
12573
12574 if (remain < elemLength)
12575 break;
12576
12577 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12578 frame.Position = null;
12579 frame.Rotation = null;
12580
12581 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12582 {
12583 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12584 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12585 }
12586 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12587 {
12588 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12589 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12590 }
12591
12592 float tempf = (float)frames.GetLSLFloatItem(idx++);
12593 frame.TimeMS = (int)(tempf * 1000.0f);
12594
12595 keyframes.Add(frame);
12596 }
12597
12598 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12599 group.RootPart.KeyframeMotion.Start();
12600 }
12601 else
12602 {
12603 if (group.RootPart.KeyframeMotion == null)
12604 return;
12605
12606 if (options.Data.Length == 0)
12607 {
12608 group.RootPart.KeyframeMotion.Stop();
12609 return;
12610 }
12611
12612 int code = (int)options.GetLSLIntegerItem(0);
12613
12614 int idx = 0;
12615
12616 while (idx < options.Data.Length)
12617 {
12618 int option = (int)options.GetLSLIntegerItem(idx++);
12619 int remain = options.Data.Length - idx;
12620
12621 switch (option)
12622 {
12623 case ScriptBaseClass.KFM_COMMAND:
12624 int cmd = (int)options.GetLSLIntegerItem(idx++);
12625 switch (cmd)
12626 {
12627 case ScriptBaseClass.KFM_CMD_PLAY:
12628 group.RootPart.KeyframeMotion.Start();
12629 break;
12630 case ScriptBaseClass.KFM_CMD_STOP:
12631 group.RootPart.KeyframeMotion.Stop();
12632 break;
12633 case ScriptBaseClass.KFM_CMD_PAUSE:
12634 group.RootPart.KeyframeMotion.Pause();
12635 break;
12636 }
12637 break;
12638 }
12639 }
12640 }
12641 }
12642
12643 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules)
12644 {
12645 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12646
12647 int idx = 0;
12648
12649 bool positionChanged = false;
12650 Vector3 finalPos = Vector3.Zero;
12651
12652 try
12653 {
12654 while (idx < rules.Length)
12655 {
12656 int code = rules.GetLSLIntegerItem(idx++);
12657
12658 int remain = rules.Length - idx;
12659
12660 switch (code)
12661 {
12662 case (int)ScriptBaseClass.PRIM_POSITION:
12663 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12664 {
12665 if (remain < 1)
12666 return null;
12667
12668 LSL_Vector v;
12669 v = rules.GetVector3Item(idx++);
12670
12671 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12672 if (part == null)
12673 break;
12674
12675 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12676 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12677 if (part.LinkNum > 1)
12678 {
12679 localRot = GetPartLocalRot(part);
12680 localPos = GetPartLocalPos(part);
12681 }
12682
12683 v -= localPos;
12684 v /= localRot;
12685
12686 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12687
12688 v = v + 2 * sitOffset;
12689
12690 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12691 av.SendAvatarDataToAllAgents();
12692
12693 }
12694 break;
12695
12696 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12697 case (int)ScriptBaseClass.PRIM_ROTATION:
12698 {
12699 if (remain < 1)
12700 return null;
12701
12702 LSL_Rotation r;
12703 r = rules.GetQuaternionItem(idx++);
12704
12705 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12706 if (part == null)
12707 break;
12708
12709 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12710 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12711
12712 if (part.LinkNum > 1)
12713 localRot = GetPartLocalRot(part);
12714
12715 r = r * llGetRootRotation() / localRot;
12716 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12717 av.SendAvatarDataToAllAgents();
12718 }
12719 break;
12720
12721 // parse rest doing nothing but number of parameters error check
12722 case (int)ScriptBaseClass.PRIM_SIZE:
12723 case (int)ScriptBaseClass.PRIM_MATERIAL:
12724 case (int)ScriptBaseClass.PRIM_PHANTOM:
12725 case (int)ScriptBaseClass.PRIM_PHYSICS:
12726 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12727 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12728 case (int)ScriptBaseClass.PRIM_NAME:
12729 case (int)ScriptBaseClass.PRIM_DESC:
12730 if (remain < 1)
12731 return null;
12732 idx++;
12733 break;
12734
12735 case (int)ScriptBaseClass.PRIM_GLOW:
12736 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12737 case (int)ScriptBaseClass.PRIM_TEXGEN:
12738 if (remain < 2)
12739 return null;
12740 idx += 2;
12741 break;
12742
12743 case (int)ScriptBaseClass.PRIM_TYPE:
12744 if (remain < 3)
12745 return null;
12746 code = (int)rules.GetLSLIntegerItem(idx++);
12747 remain = rules.Length - idx;
12748 switch (code)
12749 {
12750 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12751 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12752 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12753 if (remain < 6)
12754 return null;
12755 idx += 6;
12756 break;
12757
12758 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12759 if (remain < 5)
12760 return null;
12761 idx += 5;
12762 break;
12763
12764 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12765 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12766 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12767 if (remain < 11)
12768 return null;
12769 idx += 11;
12770 break;
12771
12772 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12773 if (remain < 2)
12774 return null;
12775 idx += 2;
12776 break;
12777 }
12778 break;
12779
12780 case (int)ScriptBaseClass.PRIM_COLOR:
12781 case (int)ScriptBaseClass.PRIM_TEXT:
12782 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12783 case (int)ScriptBaseClass.PRIM_OMEGA:
12784 if (remain < 3)
12785 return null;
12786 idx += 3;
12787 break;
12788
12789 case (int)ScriptBaseClass.PRIM_TEXTURE:
12790 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12791 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12792 if (remain < 5)
12793 return null;
12794 idx += 5;
12795 break;
12796
12797 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12798 if (remain < 7)
12799 return null;
12800
12801 idx += 7;
12802 break;
12803
12804 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12805 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12806 return null;
12807
12808 return rules.GetSublist(idx, -1);
12809 }
12810 }
12811 }
12812
12813 finally
12814 {
12815 if (positionChanged)
12816 {
12817 av.OffsetPosition = finalPos;
12818// av.SendAvatarDataToAllAgents();
12819 av.SendTerseUpdateToAllClients();
12820 positionChanged = false;
12821 }
12822 }
12823 return null;
12824 }
12825
12826 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12827 {
12828 // avatars case
12829 // replies as SL wiki
12830
12831// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12832 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12833
12834 int idx = 0;
12835 while (idx < rules.Length)
12836 {
12837 int code = (int)rules.GetLSLIntegerItem(idx++);
12838 int remain = rules.Length - idx;
12839
12840 switch (code)
12841 {
12842 case (int)ScriptBaseClass.PRIM_MATERIAL:
12843 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12844 break;
12845
12846 case (int)ScriptBaseClass.PRIM_PHYSICS:
12847 res.Add(new LSL_Integer(0));
12848 break;
12849
12850 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12851 res.Add(new LSL_Integer(0));
12852 break;
12853
12854 case (int)ScriptBaseClass.PRIM_PHANTOM:
12855 res.Add(new LSL_Integer(0));
12856 break;
12857
12858 case (int)ScriptBaseClass.PRIM_POSITION:
12859
12860 Vector3 pos = avatar.OffsetPosition;
12861
12862 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12863 pos -= sitOffset;
12864
12865 if( sitPart != null)
12866 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12867
12868 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12869 break;
12870
12871 case (int)ScriptBaseClass.PRIM_SIZE:
12872 // as in llGetAgentSize above
12873 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12874 break;
12875
12876 case (int)ScriptBaseClass.PRIM_ROTATION:
12877 Quaternion rot = avatar.Rotation;
12878 if (sitPart != null)
12879 {
12880 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12881 }
12882
12883 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12884 break;
12885
12886 case (int)ScriptBaseClass.PRIM_TYPE:
12887 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12888 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12889 res.Add(new LSL_Vector(0f,1.0f,0f));
12890 res.Add(new LSL_Float(0.0f));
12891 res.Add(new LSL_Vector(0, 0, 0));
12892 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12893 res.Add(new LSL_Vector(0, 0, 0));
12894 break;
12895
12896 case (int)ScriptBaseClass.PRIM_TEXTURE:
12897 if (remain < 1)
12898 return null;
12899
12900 int face = (int)rules.GetLSLIntegerItem(idx++);
12901 if (face == ScriptBaseClass.ALL_SIDES)
12902 {
12903 for (face = 0; face < 21; face++)
12904 {
12905 res.Add(new LSL_String(""));
12906 res.Add(new LSL_Vector(0,0,0));
12907 res.Add(new LSL_Vector(0,0,0));
12908 res.Add(new LSL_Float(0.0));
12909 }
12910 }
12911 else
12912 {
12913 if (face >= 0 && face < 21)
12914 {
12915 res.Add(new LSL_String(""));
12916 res.Add(new LSL_Vector(0,0,0));
12917 res.Add(new LSL_Vector(0,0,0));
12918 res.Add(new LSL_Float(0.0));
12919 }
12920 }
12921 break;
12922
12923 case (int)ScriptBaseClass.PRIM_COLOR:
12924 if (remain < 1)
12925 return null;
12926
12927 face = (int)rules.GetLSLIntegerItem(idx++);
12928
12929 if (face == ScriptBaseClass.ALL_SIDES)
12930 {
12931 for (face = 0; face < 21; face++)
12932 {
12933 res.Add(new LSL_Vector(0,0,0));
12934 res.Add(new LSL_Float(0));
12935 }
12936 }
12937 else
12938 {
12939 res.Add(new LSL_Vector(0,0,0));
12940 res.Add(new LSL_Float(0));
12941 }
12942 break;
12943
12944 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12945 if (remain < 1)
12946 return null;
12947 face = (int)rules.GetLSLIntegerItem(idx++);
12948
12949 if (face == ScriptBaseClass.ALL_SIDES)
12950 {
12951 for (face = 0; face < 21; face++)
12952 {
12953 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12954 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12955 }
12956 }
12957 else
12958 {
12959 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12960 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12961 }
12962 break;
12963
12964 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12965 if (remain < 1)
12966 return null;
12967 face = (int)rules.GetLSLIntegerItem(idx++);
12968
12969 if (face == ScriptBaseClass.ALL_SIDES)
12970 {
12971 for (face = 0; face < 21; face++)
12972 {
12973 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12974 }
12975 }
12976 else
12977 {
12978 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12979 }
12980 break;
12981
12982 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12983 res.Add(new LSL_Integer(0));
12984 res.Add(new LSL_Integer(0));// softness
12985 res.Add(new LSL_Float(0.0f)); // gravity
12986 res.Add(new LSL_Float(0.0f)); // friction
12987 res.Add(new LSL_Float(0.0f)); // wind
12988 res.Add(new LSL_Float(0.0f)); // tension
12989 res.Add(new LSL_Vector(0f,0f,0f));
12990 break;
12991
12992 case (int)ScriptBaseClass.PRIM_TEXGEN:
12993 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
12994 if (remain < 1)
12995 return null;
12996 face = (int)rules.GetLSLIntegerItem(idx++);
12997
12998 if (face == ScriptBaseClass.ALL_SIDES)
12999 {
13000 for (face = 0; face < 21; face++)
13001 {
13002 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13003 }
13004 }
13005 else
13006 {
13007 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13008 }
13009 break;
13010
13011 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13012 res.Add(new LSL_Integer(0));
13013 res.Add(new LSL_Vector(0f,0f,0f));
13014 res.Add(new LSL_Float(0f)); // intensity
13015 res.Add(new LSL_Float(0f)); // radius
13016 res.Add(new LSL_Float(0f)); // falloff
13017 break;
13018
13019 case (int)ScriptBaseClass.PRIM_GLOW:
13020 if (remain < 1)
13021 return null;
13022 face = (int)rules.GetLSLIntegerItem(idx++);
13023
13024 if (face == ScriptBaseClass.ALL_SIDES)
13025 {
13026 for (face = 0; face < 21; face++)
13027 {
13028 res.Add(new LSL_Float(0f));
13029 }
13030 }
13031 else
13032 {
13033 res.Add(new LSL_Float(0f));
13034 }
13035 break;
13036
13037 case (int)ScriptBaseClass.PRIM_TEXT:
13038 res.Add(new LSL_String(""));
13039 res.Add(new LSL_Vector(0f,0f,0f));
13040 res.Add(new LSL_Float(1.0f));
13041 break;
13042
13043 case (int)ScriptBaseClass.PRIM_NAME:
13044 res.Add(new LSL_String(avatar.Name));
13045 break;
13046
13047 case (int)ScriptBaseClass.PRIM_DESC:
13048 res.Add(new LSL_String(""));
13049 break;
13050
13051 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13052 Quaternion lrot = avatar.Rotation;
13053
13054 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13055 {
13056 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13057 }
13058 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13059 break;
13060
13061 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13062 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13063 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13064 lpos -= lsitOffset;
13065
13066 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13067 {
13068 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13069 }
13070 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13071 break;
13072
13073 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13074 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13075 return null;
13076
13077 return rules.GetSublist(idx, -1);
13078 }
13079 }
13080
13081 return null;
13082 }
11395 } 13083 }
11396 13084
11397 public class NotecardCache 13085 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 1afa4fb..5bc78d6 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)
@@ -2291,7 +2302,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2291 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2302 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2292 m_host.AddScriptLPS(1); 2303 m_host.AddScriptLPS(1);
2293 2304
2294 return NpcCreate(firstname, lastname, position, notecard, false, false); 2305 return NpcCreate(firstname, lastname, position, notecard, true, false);
2295 } 2306 }
2296 2307
2297 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2308 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2302,24 +2313,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2302 return NpcCreate( 2313 return NpcCreate(
2303 firstname, lastname, position, notecard, 2314 firstname, lastname, position, notecard,
2304 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2315 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2305 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2316 false);
2317// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2306 } 2318 }
2307 2319
2308 private LSL_Key NpcCreate( 2320 private LSL_Key NpcCreate(
2309 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2321 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2310 { 2322 {
2323 if (!owned)
2324 OSSLError("Unowned NPCs are unsupported");
2325
2326 string groupTitle = String.Empty;
2327
2328 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2329 return new LSL_Key(UUID.Zero.ToString());
2330
2331 if (firstname != String.Empty || lastname != String.Empty)
2332 {
2333 if (firstname != "Shown outfit:")
2334 groupTitle = "- NPC -";
2335 }
2336
2311 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2337 INPCModule module = World.RequestModuleInterface<INPCModule>();
2312 if (module != null) 2338 if (module != null)
2313 { 2339 {
2314 AvatarAppearance appearance = null; 2340 AvatarAppearance appearance = null;
2315 2341
2316 UUID id; 2342// UUID id;
2317 if (UUID.TryParse(notecard, out id)) 2343// if (UUID.TryParse(notecard, out id))
2318 { 2344// {
2319 ScenePresence clonePresence = World.GetScenePresence(id); 2345// ScenePresence clonePresence = World.GetScenePresence(id);
2320 if (clonePresence != null) 2346// if (clonePresence != null)
2321 appearance = clonePresence.Appearance; 2347// appearance = clonePresence.Appearance;
2322 } 2348// }
2323 2349
2324 if (appearance == null) 2350 if (appearance == null)
2325 { 2351 {
@@ -2347,6 +2373,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2347 World, 2373 World,
2348 appearance); 2374 appearance);
2349 2375
2376 ScenePresence sp;
2377 if (World.TryGetScenePresence(x, out sp))
2378 {
2379 sp.Grouptitle = groupTitle;
2380 sp.SendAvatarDataToAllAgents();
2381 }
2350 return new LSL_Key(x.ToString()); 2382 return new LSL_Key(x.ToString());
2351 } 2383 }
2352 2384
@@ -2646,16 +2678,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2646 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2678 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2647 m_host.AddScriptLPS(1); 2679 m_host.AddScriptLPS(1);
2648 2680
2649 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2681 ManualResetEvent ev = new ManualResetEvent(false);
2650 if (module != null)
2651 {
2652 UUID npcId = new UUID(npc.m_string);
2653 2682
2654 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2683 Util.FireAndForget(delegate(object x) {
2655 return; 2684 try
2685 {
2686 INPCModule module = World.RequestModuleInterface<INPCModule>();
2687 if (module != null)
2688 {
2689 UUID npcId = new UUID(npc.m_string);
2656 2690
2657 module.DeleteNPC(npcId, World); 2691 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2658 } 2692 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2693 {
2694 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2695 return;
2696 }
2697
2698 module.DeleteNPC(npcId, World);
2699 }
2700 }
2701 finally
2702 {
2703 ev.Set();
2704 }
2705 });
2706 ev.WaitOne();
2659 } 2707 }
2660 2708
2661 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2709 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3359,4 +3407,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3359 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString()); 3407 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString());
3360 } 3408 }
3361 } 3409 }
3362} \ No newline at end of file 3410}
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 cd58614..e08328f 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);
433 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
428 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 434 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
429 } 435 }
430} 436}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 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 {