aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs23
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs117
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3277
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs113
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs29
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs56
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs45
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs172
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs37
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs371
19 files changed, 3354 insertions, 1090 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 47a9cdc..6879ebb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -305,6 +305,29 @@ 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 if (xmlrpc != null)
321 {
322 xmlrpc.DeleteChannels(itemID);
323 xmlrpc.CancelSRDRequests(itemID);
324 }
325
326 // Remove Sensors
327 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
328
329 }
330
308 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 331 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
309 { 332 {
310 List<Object> data = new List<Object>(); 333 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..d03955b
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,117 @@
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.Threading;
30using System.Reflection;
31using System.Collections;
32using System.Collections.Generic;
33using System.Runtime.Remoting.Lifetime;
34using OpenMetaverse;
35using Nini.Config;
36using OpenSim;
37using OpenSim.Framework;
38using OpenSim.Region.CoreModules.World.LightShare;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.ScriptEngine.Shared;
42using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
43using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
44using OpenSim.Region.ScriptEngine.Interfaces;
45using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
46using OpenSim.Services.Interfaces;
47
48using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
49using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
50using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
51using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
52using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
53using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
54using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
55
56namespace OpenSim.Region.ScriptEngine.Shared.Api
57{
58 [Serializable]
59 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
60 {
61 internal IScriptEngine m_ScriptEngine;
62 internal SceneObjectPart m_host;
63 internal TaskInventoryItem m_item;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_item = item;
71
72 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
73 m_CMFunctionsEnabled = true;
74 }
75
76 public override Object InitializeLifetimeService()
77 {
78 ILease lease = (ILease)base.InitializeLifetimeService();
79
80 if (lease.CurrentState == LeaseState.Initial)
81 {
82 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
83 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
84 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
85 }
86 return lease;
87 }
88
89 public Scene World
90 {
91 get { return m_ScriptEngine.World; }
92 }
93
94 public string cmDetectedCountry(int number)
95 {
96 m_host.AddScriptLPS(1);
97 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
98 if (detectedParams == null)
99 return String.Empty;
100 return detectedParams.Country;
101 }
102
103 public string cmGetAgentCountry(LSL_Key key)
104 {
105 if (!World.Permissions.IsGod(m_host.OwnerID))
106 return String.Empty;
107
108 UUID uuid;
109
110 if (!UUID.TryParse(key, out uuid))
111 return String.Empty;
112
113 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
114 return account.UserCountry;
115 }
116 }
117}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index db5add1..5cbb9c7 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,14 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -66,6 +69,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
66using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 69using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
67using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 70using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
68using System.Reflection; 71using System.Reflection;
72using Timer = System.Timers.Timer;
69 73
70namespace OpenSim.Region.ScriptEngine.Shared.Api 74namespace OpenSim.Region.ScriptEngine.Shared.Api
71{ 75{
@@ -112,17 +116,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
112 protected int m_notecardLineReadCharsMax = 255; 116 protected int m_notecardLineReadCharsMax = 255;
113 protected int m_scriptConsoleChannel = 0; 117 protected int m_scriptConsoleChannel = 0;
114 protected bool m_scriptConsoleChannelEnabled = false; 118 protected bool m_scriptConsoleChannelEnabled = false;
119 protected bool m_debuggerSafe = false;
115 protected IUrlModule m_UrlModule = null; 120 protected IUrlModule m_UrlModule = null;
116 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 121 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
117 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 122 new Dictionary<UUID, UserInfoCacheEntry>();
123 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
118 protected ISoundModule m_SoundModule = null; 124 protected ISoundModule m_SoundModule = null;
119 125
126// protected Timer m_ShoutSayTimer;
127 protected int m_SayShoutCount = 0;
128 DateTime m_lastSayShoutCheck;
129
130 private Dictionary<string, string> MovementAnimationsForLSL =
131 new Dictionary<string, string> {
132 {"FLY", "Flying"},
133 {"FLYSLOW", "FlyingSlow"},
134 {"HOVER_UP", "Hovering Up"},
135 {"HOVER_DOWN", "Hovering Down"},
136 {"HOVER", "Hovering"},
137 {"LAND", "Landing"},
138 {"FALLDOWN", "Falling Down"},
139 {"PREJUMP", "PreJumping"},
140 {"JUMP", "Jumping"},
141 {"STANDUP", "Standing Up"},
142 {"SOFT_LAND", "Soft Landing"},
143 {"STAND", "Standing"},
144 {"CROUCHWALK", "CrouchWalking"},
145 {"RUN", "Running"},
146 {"WALK", "Walking"},
147 {"CROUCH", "Crouching"},
148 {"TURNLEFT", "Turning Left"},
149 {"TURNRIGHT", "Turning Right"}
150 };
151
120 public void Initialize( 152 public void Initialize(
121 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) 153 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle)
122 { 154 {
155 m_lastSayShoutCheck = DateTime.UtcNow;
156
123 m_ScriptEngine = scriptEngine; 157 m_ScriptEngine = scriptEngine;
124 m_host = host; 158 m_host = host;
125 m_item = item; 159 m_item = item;
160 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
126 m_coopSleepHandle = coopSleepHandle; 161 m_coopSleepHandle = coopSleepHandle;
127 162
128 LoadConfig(); 163 LoadConfig();
@@ -201,6 +236,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
201 get { return m_ScriptEngine.World; } 236 get { return m_ScriptEngine.World; }
202 } 237 }
203 238
239 [DebuggerNonUserCode]
204 public void state(string newState) 240 public void state(string newState)
205 { 241 {
206 m_ScriptEngine.SetState(m_item.ItemID, newState); 242 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -210,6 +246,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
210 /// Reset the named script. The script must be present 246 /// Reset the named script. The script must be present
211 /// in the same prim. 247 /// in the same prim.
212 /// </summary> 248 /// </summary>
249 [DebuggerNonUserCode]
213 public void llResetScript() 250 public void llResetScript()
214 { 251 {
215 m_host.AddScriptLPS(1); 252 m_host.AddScriptLPS(1);
@@ -272,6 +309,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
272 } 309 }
273 } 310 }
274 311
312 public List<ScenePresence> GetLinkAvatars(int linkType)
313 {
314 List<ScenePresence> ret = new List<ScenePresence>();
315 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
316 return ret;
317
318 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
319
320 switch (linkType)
321 {
322 case ScriptBaseClass.LINK_SET:
323 return avs;
324
325 case ScriptBaseClass.LINK_ROOT:
326 return ret;
327
328 case ScriptBaseClass.LINK_ALL_OTHERS:
329 return avs;
330
331 case ScriptBaseClass.LINK_ALL_CHILDREN:
332 return avs;
333
334 case ScriptBaseClass.LINK_THIS:
335 return ret;
336
337 default:
338 if (linkType < 0)
339 return ret;
340
341 int partCount = m_host.ParentGroup.GetPartCount();
342
343 if (linkType <= partCount)
344 {
345 return ret;
346 }
347 else
348 {
349 linkType = linkType - partCount;
350 if (linkType > avs.Count)
351 {
352 return ret;
353 }
354 else
355 {
356 ret.Add(avs[linkType-1]);
357 return ret;
358 }
359 }
360 }
361 }
362
275 public List<SceneObjectPart> GetLinkParts(int linkType) 363 public List<SceneObjectPart> GetLinkParts(int linkType)
276 { 364 {
277 return GetLinkParts(m_host, linkType); 365 return GetLinkParts(m_host, linkType);
@@ -280,6 +368,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
280 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 368 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
281 { 369 {
282 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 370 List<SceneObjectPart> ret = new List<SceneObjectPart>();
371 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
372 return ret;
283 ret.Add(part); 373 ret.Add(part);
284 374
285 switch (linkType) 375 switch (linkType)
@@ -506,31 +596,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
506 596
507 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 597 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
508 598
509 /// <summary> 599 // Utility function for llRot2Euler
510 /// Convert an LSL rotation to a Euler vector. 600
511 /// </summary> 601 // normalize an angle between -PI and PI (-180 to +180 degrees)
512 /// <remarks> 602 protected double NormalizeAngle(double angle)
513 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
514 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
515 /// </remarks>
516 /// <param name="r"></param>
517 /// <returns></returns>
518 public LSL_Vector llRot2Euler(LSL_Rotation r)
519 { 603 {
520 m_host.AddScriptLPS(1); 604 if (angle > -Math.PI && angle < Math.PI)
605 return angle;
606
607 int numPis = (int)(Math.PI / angle);
608 double remainder = angle - Math.PI * numPis;
609 if (numPis % 2 == 1)
610 return Math.PI - angle;
611 return remainder;
612 }
521 613
522 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 614 public LSL_Vector llRot2Euler(LSL_Rotation q1)
523 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 615 {
524 if (m == 0.0) return new LSL_Vector(); 616 m_host.AddScriptLPS(1);
525 double x = Math.Atan2(-v.y, v.z); 617 LSL_Vector eul = new LSL_Vector();
526 double sin = v.x / m;
527 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
528 double y = Math.Asin(sin);
529 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
530 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)));
531 double z = Math.Atan2(v.y, v.x);
532 618
533 return new LSL_Vector(x, y, z); 619 double sqw = q1.s*q1.s;
620 double sqx = q1.x*q1.x;
621 double sqy = q1.z*q1.z;
622 double sqz = q1.y*q1.y;
623 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
624 double test = q1.x*q1.z + q1.y*q1.s;
625 if (test > 0.4999*unit) { // singularity at north pole
626 eul.z = 2 * Math.Atan2(q1.x,q1.s);
627 eul.y = Math.PI/2;
628 eul.x = 0;
629 return eul;
630 }
631 if (test < -0.4999*unit) { // singularity at south pole
632 eul.z = -2 * Math.Atan2(q1.x,q1.s);
633 eul.y = -Math.PI/2;
634 eul.x = 0;
635 return eul;
636 }
637 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
638 eul.y = Math.Asin(2*test/unit);
639 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
640 return eul;
534 } 641 }
535 642
536 /* From wiki: 643 /* From wiki:
@@ -583,18 +690,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
583 m_host.AddScriptLPS(1); 690 m_host.AddScriptLPS(1);
584 691
585 double x,y,z,s; 692 double x,y,z,s;
586 693 v.x *= 0.5;
587 double c1 = Math.Cos(v.x * 0.5); 694 v.y *= 0.5;
588 double c2 = Math.Cos(v.y * 0.5); 695 v.z *= 0.5;
589 double c3 = Math.Cos(v.z * 0.5); 696 double c1 = Math.Cos(v.x);
590 double s1 = Math.Sin(v.x * 0.5); 697 double c2 = Math.Cos(v.y);
591 double s2 = Math.Sin(v.y * 0.5); 698 double c1c2 = c1 * c2;
592 double s3 = Math.Sin(v.z * 0.5); 699 double s1 = Math.Sin(v.x);
593 700 double s2 = Math.Sin(v.y);
594 x = s1 * c2 * c3 + c1 * s2 * s3; 701 double s1s2 = s1 * s2;
595 y = c1 * s2 * c3 - s1 * c2 * s3; 702 double c1s2 = c1 * s2;
596 z = s1 * s2 * c3 + c1 * c2 * s3; 703 double s1c2 = s1 * c2;
597 s = c1 * c2 * c3 - s1 * s2 * s3; 704 double c3 = Math.Cos(v.z);
705 double s3 = Math.Sin(v.z);
706
707 x = s1c2 * c3 + c1s2 * s3;
708 y = c1s2 * c3 - s1c2 * s3;
709 z = s1s2 * c3 + c1c2 * s3;
710 s = c1c2 * c3 - s1s2 * s3;
598 711
599 return new LSL_Rotation(x, y, z, s); 712 return new LSL_Rotation(x, y, z, s);
600 } 713 }
@@ -732,77 +845,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
732 { 845 {
733 //A and B should both be normalized 846 //A and B should both be normalized
734 m_host.AddScriptLPS(1); 847 m_host.AddScriptLPS(1);
735 LSL_Rotation rotBetween; 848 /* This method is more accurate than the SL one, and thus causes problems
736 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 849 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
737 // continue calculation. 850
738 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 851 double dotProduct = LSL_Vector.Dot(a, b);
852 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
853 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
854 double angle = Math.Acos(dotProduct / magProduct);
855 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
856 double s = Math.Sin(angle / 2);
857
858 double x = axis.x * s;
859 double y = axis.y * s;
860 double z = axis.z * s;
861 double w = Math.Cos(angle / 2);
862
863 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
864 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
865
866 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
867 */
868
869 // This method mimics the 180 errors found in SL
870 // See www.euclideanspace.com... angleBetween
871 LSL_Vector vec_a = a;
872 LSL_Vector vec_b = b;
873
874 // Eliminate zero length
875 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
876 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
877 if (vec_a_mag < 0.00001 ||
878 vec_b_mag < 0.00001)
739 { 879 {
740 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 880 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
741 } 881 }
742 else 882
883 // Normalize
884 vec_a = llVecNorm(vec_a);
885 vec_b = llVecNorm(vec_b);
886
887 // Calculate axis and rotation angle
888 LSL_Vector axis = vec_a % vec_b;
889 LSL_Float cos_theta = vec_a * vec_b;
890
891 // Check if parallel
892 if (cos_theta > 0.99999)
743 { 893 {
744 a = LSL_Vector.Norm(a); 894 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
745 b = LSL_Vector.Norm(b); 895 }
746 double dotProduct = LSL_Vector.Dot(a, b); 896
747 // There are two degenerate cases possible. These are for vectors 180 or 897 // Check if anti-parallel
748 // 0 degrees apart. These have to be detected and handled individually. 898 else if (cos_theta < -0.99999)
749 // 899 {
750 // Check for vectors 180 degrees apart. 900 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
751 // A dot product of -1 would mean the angle between vectors is 180 degrees. 901 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
752 if (dotProduct < -0.9999999f) 902 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
753 { 903 }
754 // First assume X axis is orthogonal to the vectors. 904 else // other rotation
755 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 905 {
756 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 906 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
757 // Check for near zero vector. A very small non-zero number here will create 907 axis = llVecNorm(axis);
758 // a rotation in an undesired direction. 908 double x, y, z, s, t;
759 if (LSL_Vector.Mag(orthoVector) > 0.0001) 909 s = Math.Cos(theta);
760 { 910 t = Math.Sin(theta);
761 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 911 x = axis.x * t;
762 } 912 y = axis.y * t;
763 // If the magnitude of the vector was near zero, then assume the X axis is not 913 z = axis.z * t;
764 // orthogonal and use the Z axis instead. 914 return new LSL_Rotation(x,y,z,s);
765 else
766 {
767 // Set 180 z rotation.
768 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
769 }
770 }
771 // Check for parallel vectors.
772 // A dot product of 1 would mean the angle between vectors is 0 degrees.
773 else if (dotProduct > 0.9999999f)
774 {
775 // Set zero rotation.
776 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
777 }
778 else
779 {
780 // All special checks have been performed so get the axis of rotation.
781 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
782 // Quarternion s value is the length of the unit vector + dot product.
783 double qs = 1.0 + dotProduct;
784 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
785 // Normalize the rotation.
786 double mag = LSL_Rotation.Mag(rotBetween);
787 // We shouldn't have to worry about a divide by zero here. The qs value will be
788 // non-zero because we already know if we're here, then the dotProduct is not -1 so
789 // qs will not be zero. Also, we've already handled the input vectors being zero so the
790 // crossProduct vector should also not be zero.
791 rotBetween.x = rotBetween.x / mag;
792 rotBetween.y = rotBetween.y / mag;
793 rotBetween.z = rotBetween.z / mag;
794 rotBetween.s = rotBetween.s / mag;
795 // Check for undefined values and set zero rotation if any found. This code might not actually be required
796 // any longer since zero vectors are checked for at the top.
797 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
798 {
799 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
800 }
801 }
802 } 915 }
803 return rotBetween;
804 } 916 }
805 917
806 public void llWhisper(int channelID, string text) 918 public void llWhisper(int channelID, string text)
807 { 919 {
808 m_host.AddScriptLPS(1); 920 m_host.AddScriptLPS(1);
@@ -818,10 +930,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
818 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 930 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
819 } 931 }
820 932
933 private void CheckSayShoutTime()
934 {
935 DateTime now = DateTime.UtcNow;
936 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
937 {
938 m_lastSayShoutCheck = now;
939 m_SayShoutCount = 0;
940 }
941 else
942 m_SayShoutCount++;
943 }
944
821 public void llSay(int channelID, string text) 945 public void llSay(int channelID, string text)
822 { 946 {
823 m_host.AddScriptLPS(1); 947 m_host.AddScriptLPS(1);
824 948
949 if (channelID == 0)
950// m_SayShoutCount++;
951 CheckSayShoutTime();
952
953 if (m_SayShoutCount >= 11)
954 ScriptSleep(2000);
955
825 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 956 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
826 { 957 {
827 Console.WriteLine(text); 958 Console.WriteLine(text);
@@ -844,6 +975,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
844 { 975 {
845 m_host.AddScriptLPS(1); 976 m_host.AddScriptLPS(1);
846 977
978 if (channelID == 0)
979// m_SayShoutCount++;
980 CheckSayShoutTime();
981
982 if (m_SayShoutCount >= 11)
983 ScriptSleep(2000);
984
847 if (text.Length > 1023) 985 if (text.Length > 1023)
848 text = text.Substring(0, 1023); 986 text = text.Substring(0, 1023);
849 987
@@ -875,22 +1013,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
875 1013
876 public void llRegionSayTo(string target, int channel, string msg) 1014 public void llRegionSayTo(string target, int channel, string msg)
877 { 1015 {
1016 string error = String.Empty;
1017
878 if (msg.Length > 1023) 1018 if (msg.Length > 1023)
879 msg = msg.Substring(0, 1023); 1019 msg = msg.Substring(0, 1023);
880 1020
881 m_host.AddScriptLPS(1); 1021 m_host.AddScriptLPS(1);
882 1022
883 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
884 {
885 return;
886 }
887
888 UUID TargetID; 1023 UUID TargetID;
889 UUID.TryParse(target, out TargetID); 1024 UUID.TryParse(target, out TargetID);
890 1025
891 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1026 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
892 if (wComm != null) 1027 if (wComm != null)
893 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1028 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1029 LSLError(error);
894 } 1030 }
895 1031
896 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1032 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1146,10 +1282,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1146 return detectedParams.TouchUV; 1282 return detectedParams.TouchUV;
1147 } 1283 }
1148 1284
1285 [DebuggerNonUserCode]
1149 public virtual void llDie() 1286 public virtual void llDie()
1150 { 1287 {
1151 m_host.AddScriptLPS(1); 1288 m_host.AddScriptLPS(1);
1152 throw new SelfDeleteException(); 1289 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1153 } 1290 }
1154 1291
1155 public LSL_Float llGround(LSL_Vector offset) 1292 public LSL_Float llGround(LSL_Vector offset)
@@ -1220,6 +1357,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1220 1357
1221 public void llSetStatus(int status, int value) 1358 public void llSetStatus(int status, int value)
1222 { 1359 {
1360 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1361 return;
1223 m_host.AddScriptLPS(1); 1362 m_host.AddScriptLPS(1);
1224 1363
1225 int statusrotationaxis = 0; 1364 int statusrotationaxis = 0;
@@ -1243,6 +1382,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1243 if (!allow) 1382 if (!allow)
1244 return; 1383 return;
1245 1384
1385 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1386 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1387 return;
1388
1246 m_host.ScriptSetPhysicsStatus(true); 1389 m_host.ScriptSetPhysicsStatus(true);
1247 } 1390 }
1248 else 1391 else
@@ -1443,6 +1586,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1443 { 1586 {
1444 m_host.AddScriptLPS(1); 1587 m_host.AddScriptLPS(1);
1445 1588
1589 SetColor(m_host, color, face);
1590 }
1591
1592 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1593 {
1594 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1595 return;
1596
1597 Primitive.TextureEntry tex = part.Shape.Textures;
1598 Color4 texcolor;
1599 if (face >= 0 && face < GetNumberOfSides(part))
1600 {
1601 texcolor = tex.CreateFace((uint)face).RGBA;
1602 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1603 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1604 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1605 tex.FaceTextures[face].RGBA = texcolor;
1606 part.UpdateTextureEntry(tex.GetBytes());
1607 return;
1608 }
1609 else if (face == ScriptBaseClass.ALL_SIDES)
1610 {
1611 for (uint i = 0; i < GetNumberOfSides(part); i++)
1612 {
1613 if (tex.FaceTextures[i] != null)
1614 {
1615 texcolor = tex.FaceTextures[i].RGBA;
1616 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1617 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1618 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1619 tex.FaceTextures[i].RGBA = texcolor;
1620 }
1621 texcolor = tex.DefaultTexture.RGBA;
1622 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1623 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1624 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1625 tex.DefaultTexture.RGBA = texcolor;
1626 }
1627 part.UpdateTextureEntry(tex.GetBytes());
1628 return;
1629 }
1630
1446 if (face == ScriptBaseClass.ALL_SIDES) 1631 if (face == ScriptBaseClass.ALL_SIDES)
1447 face = SceneObjectPart.ALL_SIDES; 1632 face = SceneObjectPart.ALL_SIDES;
1448 1633
@@ -1451,6 +1636,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1451 1636
1452 public void SetTexGen(SceneObjectPart part, int face,int style) 1637 public void SetTexGen(SceneObjectPart part, int face,int style)
1453 { 1638 {
1639 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1640 return;
1641
1454 Primitive.TextureEntry tex = part.Shape.Textures; 1642 Primitive.TextureEntry tex = part.Shape.Textures;
1455 MappingType textype; 1643 MappingType textype;
1456 textype = MappingType.Default; 1644 textype = MappingType.Default;
@@ -1481,6 +1669,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1481 1669
1482 public void SetGlow(SceneObjectPart part, int face, float glow) 1670 public void SetGlow(SceneObjectPart part, int face, float glow)
1483 { 1671 {
1672 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1673 return;
1674
1484 Primitive.TextureEntry tex = part.Shape.Textures; 1675 Primitive.TextureEntry tex = part.Shape.Textures;
1485 if (face >= 0 && face < GetNumberOfSides(part)) 1676 if (face >= 0 && face < GetNumberOfSides(part))
1486 { 1677 {
@@ -1506,6 +1697,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1506 1697
1507 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1698 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1508 { 1699 {
1700 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1701 return;
1509 1702
1510 Shininess sval = new Shininess(); 1703 Shininess sval = new Shininess();
1511 1704
@@ -1556,6 +1749,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1556 1749
1557 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1750 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1558 { 1751 {
1752 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1753 return;
1754
1559 Primitive.TextureEntry tex = part.Shape.Textures; 1755 Primitive.TextureEntry tex = part.Shape.Textures;
1560 if (face >= 0 && face < GetNumberOfSides(part)) 1756 if (face >= 0 && face < GetNumberOfSides(part))
1561 { 1757 {
@@ -1616,13 +1812,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1616 m_host.AddScriptLPS(1); 1812 m_host.AddScriptLPS(1);
1617 1813
1618 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1814 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1619 1815 if (parts.Count > 0)
1620 foreach (SceneObjectPart part in parts) 1816 {
1621 SetAlpha(part, alpha, face); 1817 try
1818 {
1819 foreach (SceneObjectPart part in parts)
1820 SetAlpha(part, alpha, face);
1821 }
1822 finally
1823 {
1824 }
1825 }
1622 } 1826 }
1623 1827
1624 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1828 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1625 { 1829 {
1830 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1831 return;
1832
1626 Primitive.TextureEntry tex = part.Shape.Textures; 1833 Primitive.TextureEntry tex = part.Shape.Textures;
1627 Color4 texcolor; 1834 Color4 texcolor;
1628 if (face >= 0 && face < GetNumberOfSides(part)) 1835 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1675,7 +1882,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1675 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1882 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1676 float wind, float tension, LSL_Vector Force) 1883 float wind, float tension, LSL_Vector Force)
1677 { 1884 {
1678 if (part == null) 1885 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1679 return; 1886 return;
1680 1887
1681 if (flexi) 1888 if (flexi)
@@ -1709,7 +1916,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1709 /// <param name="falloff"></param> 1916 /// <param name="falloff"></param>
1710 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1917 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1711 { 1918 {
1712 if (part == null) 1919 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1713 return; 1920 return;
1714 1921
1715 if (light) 1922 if (light)
@@ -1742,11 +1949,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1742 Primitive.TextureEntry tex = part.Shape.Textures; 1949 Primitive.TextureEntry tex = part.Shape.Textures;
1743 Color4 texcolor; 1950 Color4 texcolor;
1744 LSL_Vector rgb = new LSL_Vector(); 1951 LSL_Vector rgb = new LSL_Vector();
1952 int nsides = GetNumberOfSides(part);
1953
1745 if (face == ScriptBaseClass.ALL_SIDES) 1954 if (face == ScriptBaseClass.ALL_SIDES)
1746 { 1955 {
1747 int i; 1956 int i;
1748 1957 for (i = 0; i < nsides; i++)
1749 for (i = 0 ; i < GetNumberOfSides(part); i++)
1750 { 1958 {
1751 texcolor = tex.GetFace((uint)i).RGBA; 1959 texcolor = tex.GetFace((uint)i).RGBA;
1752 rgb.x += texcolor.R; 1960 rgb.x += texcolor.R;
@@ -1754,14 +1962,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1754 rgb.z += texcolor.B; 1962 rgb.z += texcolor.B;
1755 } 1963 }
1756 1964
1757 rgb.x /= (float)GetNumberOfSides(part); 1965 float invnsides = 1.0f / (float)nsides;
1758 rgb.y /= (float)GetNumberOfSides(part); 1966
1759 rgb.z /= (float)GetNumberOfSides(part); 1967 rgb.x *= invnsides;
1968 rgb.y *= invnsides;
1969 rgb.z *= invnsides;
1760 1970
1761 return rgb; 1971 return rgb;
1762 } 1972 }
1763 1973 if (face >= 0 && face < nsides)
1764 if (face >= 0 && face < GetNumberOfSides(part))
1765 { 1974 {
1766 texcolor = tex.GetFace((uint)face).RGBA; 1975 texcolor = tex.GetFace((uint)face).RGBA;
1767 rgb.x = texcolor.R; 1976 rgb.x = texcolor.R;
@@ -1788,15 +1997,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1788 m_host.AddScriptLPS(1); 1997 m_host.AddScriptLPS(1);
1789 1998
1790 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1999 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1791 2000 if (parts.Count > 0)
1792 foreach (SceneObjectPart part in parts) 2001 {
1793 SetTexture(part, texture, face); 2002 try
1794 2003 {
2004 foreach (SceneObjectPart part in parts)
2005 SetTexture(part, texture, face);
2006 }
2007 finally
2008 {
2009 }
2010 }
1795 ScriptSleep(200); 2011 ScriptSleep(200);
1796 } 2012 }
1797 2013
1798 protected void SetTexture(SceneObjectPart part, string texture, int face) 2014 protected void SetTexture(SceneObjectPart part, string texture, int face)
1799 { 2015 {
2016 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2017 return;
2018
1800 UUID textureID = new UUID(); 2019 UUID textureID = new UUID();
1801 2020
1802 textureID = InventoryKey(texture, (int)AssetType.Texture); 2021 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1841,6 +2060,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1841 2060
1842 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2061 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1843 { 2062 {
2063 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2064 return;
2065
1844 Primitive.TextureEntry tex = part.Shape.Textures; 2066 Primitive.TextureEntry tex = part.Shape.Textures;
1845 if (face >= 0 && face < GetNumberOfSides(part)) 2067 if (face >= 0 && face < GetNumberOfSides(part))
1846 { 2068 {
@@ -1877,6 +2099,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1877 2099
1878 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2100 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1879 { 2101 {
2102 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2103 return;
2104
1880 Primitive.TextureEntry tex = part.Shape.Textures; 2105 Primitive.TextureEntry tex = part.Shape.Textures;
1881 if (face >= 0 && face < GetNumberOfSides(part)) 2106 if (face >= 0 && face < GetNumberOfSides(part))
1882 { 2107 {
@@ -1913,6 +2138,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1913 2138
1914 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2139 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1915 { 2140 {
2141 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2142 return;
2143
1916 Primitive.TextureEntry tex = part.Shape.Textures; 2144 Primitive.TextureEntry tex = part.Shape.Textures;
1917 if (face >= 0 && face < GetNumberOfSides(part)) 2145 if (face >= 0 && face < GetNumberOfSides(part))
1918 { 2146 {
@@ -2054,7 +2282,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2054 return end; 2282 return end;
2055 } 2283 }
2056 2284
2057 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2285 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2058 { 2286 {
2059 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2287 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2060 return fromPos; 2288 return fromPos;
@@ -2070,9 +2298,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2070 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2298 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2071 targetPos.z = ground; 2299 targetPos.z = ground;
2072 } 2300 }
2073 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2301 if (adjust)
2302 return SetPosAdjust(fromPos, targetPos);
2074 2303
2075 return real_vec; 2304 return targetPos;
2076 } 2305 }
2077 2306
2078 /// <summary> 2307 /// <summary>
@@ -2083,24 +2312,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2083 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2312 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2084 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2313 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2085 { 2314 {
2086 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2315 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2316 return;
2317
2087 LSL_Vector currentPos = GetPartLocalPos(part); 2318 LSL_Vector currentPos = GetPartLocalPos(part);
2319 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2088 2320
2089 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2090 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2091 2321
2092 if (part.ParentGroup.RootPart == part) 2322 if (part.ParentGroup.RootPart == part)
2093 { 2323 {
2094 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2095 targetPos.z = ground;
2096 SceneObjectGroup parent = part.ParentGroup; 2324 SceneObjectGroup parent = part.ParentGroup;
2097 parent.UpdateGroupPosition(!adjust ? targetPos : 2325 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2098 SetPosAdjust(currentPos, targetPos)); 2326 return;
2327 Util.FireAndForget(delegate(object x) {
2328 parent.UpdateGroupPosition((Vector3)toPos);
2329 });
2099 } 2330 }
2100 else 2331 else
2101 { 2332 {
2102 part.OffsetPosition = !adjust ? targetPos : 2333 part.OffsetPosition = (Vector3)toPos;
2103 SetPosAdjust(currentPos, targetPos);
2104 SceneObjectGroup parent = part.ParentGroup; 2334 SceneObjectGroup parent = part.ParentGroup;
2105 parent.HasGroupChanged = true; 2335 parent.HasGroupChanged = true;
2106 parent.ScheduleGroupForTerseUpdate(); 2336 parent.ScheduleGroupForTerseUpdate();
@@ -2132,13 +2362,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2132 else 2362 else
2133 { 2363 {
2134 if (part.ParentGroup.IsAttachment) 2364 if (part.ParentGroup.IsAttachment)
2135 {
2136 pos = part.AttachedPos; 2365 pos = part.AttachedPos;
2137 }
2138 else 2366 else
2139 {
2140 pos = part.AbsolutePosition; 2367 pos = part.AbsolutePosition;
2141 }
2142 } 2368 }
2143 2369
2144// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2370// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2150,8 +2376,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2150 { 2376 {
2151 m_host.AddScriptLPS(1); 2377 m_host.AddScriptLPS(1);
2152 2378
2379
2380 // Teravus: if (m_host.ParentID == 0) is bug code because the ParentID for the Avatar will cause this to be nonzero for root prim attachments
2381 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2382 // to fix the scripted rotations we also have to check to see if the root part localid is the same as the host's localid.
2383 // RootPart != null should shortcircuit
2384
2153 // try to let this work as in SL... 2385 // try to let this work as in SL...
2154 if (m_host.ParentID == 0) 2386 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2155 { 2387 {
2156 // special case: If we are root, rotate complete SOG to new rotation 2388 // special case: If we are root, rotate complete SOG to new rotation
2157 SetRot(m_host, rot); 2389 SetRot(m_host, rot);
@@ -2178,25 +2410,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2178 2410
2179 protected void SetRot(SceneObjectPart part, Quaternion rot) 2411 protected void SetRot(SceneObjectPart part, Quaternion rot)
2180 { 2412 {
2181 part.UpdateRotation(rot); 2413 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2182 // Update rotation does not move the object in the physics scene if it's a linkset. 2414 return;
2183 2415
2184//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2416 bool isroot = (part == part.ParentGroup.RootPart);
2185// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2417 bool isphys;
2186 2418
2187 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2188 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2189 // It's perfectly okay when the object is not an active physical body though.
2190 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2191 // but only if the object is not physial and active. This is important for rotating doors.
2192 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2193 // scene
2194 PhysicsActor pa = part.PhysActor; 2419 PhysicsActor pa = part.PhysActor;
2195 2420
2196 if (pa != null && !pa.IsPhysical) 2421 // keep using physactor ideia of isphysical
2422 // it should be SOP ideia of that
2423 // not much of a issue with ubitODE
2424 if (pa != null && pa.IsPhysical)
2425 isphys = true;
2426 else
2427 isphys = false;
2428
2429 // SL doesn't let scripts rotate root of physical linksets
2430 if (isroot && isphys)
2431 return;
2432
2433 part.UpdateRotation(rot);
2434
2435 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2436 // so do a nasty update of parts positions if is a root part rotation
2437 if (isroot && pa != null) // with if above implies non physical root part
2197 { 2438 {
2198 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2439 part.ParentGroup.ResetChildPrimPhysicsPositions();
2199 } 2440 }
2441 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2442 {
2443 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2444 if (sittingavas.Count > 0)
2445 {
2446 foreach (ScenePresence av in sittingavas)
2447 {
2448 if (isroot || part.LocalId == av.ParentID)
2449 av.SendTerseUpdateToAllClients();
2450 }
2451 }
2452 }
2200 } 2453 }
2201 2454
2202 /// <summary> 2455 /// <summary>
@@ -2213,6 +2466,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2213 2466
2214 m_host.AddScriptLPS(1); 2467 m_host.AddScriptLPS(1);
2215 Quaternion q = m_host.GetWorldRotation(); 2468 Quaternion q = m_host.GetWorldRotation();
2469
2470 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2471 {
2472 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2473 if (avatar != null)
2474 {
2475 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2476 q = avatar.CameraRotation * q; // Mouselook
2477 else
2478 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2479 }
2480 }
2481
2216 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2482 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2217 } 2483 }
2218 2484
@@ -2238,14 +2504,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2238 q = part.ParentGroup.GroupRotation; // just the group rotation 2504 q = part.ParentGroup.GroupRotation; // just the group rotation
2239 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2505 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2240 } 2506 }
2507
2241 q = part.GetWorldRotation(); 2508 q = part.GetWorldRotation();
2509 if (part.ParentGroup.AttachmentPoint != 0)
2510 {
2511 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2512 if (avatar != null)
2513 {
2514 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2515 q = avatar.CameraRotation * q; // Mouselook
2516 else
2517 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2518 }
2519 }
2520
2242 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2521 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2243 } 2522 }
2244 2523
2245 public LSL_Rotation llGetLocalRot() 2524 public LSL_Rotation llGetLocalRot()
2246 { 2525 {
2526 return GetPartLocalRot(m_host);
2527 }
2528
2529 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2530 {
2247 m_host.AddScriptLPS(1); 2531 m_host.AddScriptLPS(1);
2248 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2532 Quaternion rot = part.RotationOffset;
2533 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2249 } 2534 }
2250 2535
2251 public void llSetForce(LSL_Vector force, int local) 2536 public void llSetForce(LSL_Vector force, int local)
@@ -2325,16 +2610,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2325 m_host.ApplyImpulse(v, local != 0); 2610 m_host.ApplyImpulse(v, local != 0);
2326 } 2611 }
2327 2612
2613
2328 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2614 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2329 { 2615 {
2330 m_host.AddScriptLPS(1); 2616 m_host.AddScriptLPS(1);
2331 m_host.ApplyAngularImpulse(force, local != 0); 2617 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2332 } 2618 }
2333 2619
2334 public void llSetTorque(LSL_Vector torque, int local) 2620 public void llSetTorque(LSL_Vector torque, int local)
2335 { 2621 {
2336 m_host.AddScriptLPS(1); 2622 m_host.AddScriptLPS(1);
2337 m_host.SetAngularImpulse(torque, local != 0); 2623 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2338 } 2624 }
2339 2625
2340 public LSL_Vector llGetTorque() 2626 public LSL_Vector llGetTorque()
@@ -2351,20 +2637,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2351 llSetTorque(torque, local); 2637 llSetTorque(torque, local);
2352 } 2638 }
2353 2639
2640 public void llSetVelocity(LSL_Vector vel, int local)
2641 {
2642 m_host.AddScriptLPS(1);
2643 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2644 }
2645
2354 public LSL_Vector llGetVel() 2646 public LSL_Vector llGetVel()
2355 { 2647 {
2356 m_host.AddScriptLPS(1); 2648 m_host.AddScriptLPS(1);
2357 2649
2358 Vector3 vel; 2650 Vector3 vel = Vector3.Zero;
2359 2651
2360 if (m_host.ParentGroup.IsAttachment) 2652 if (m_host.ParentGroup.IsAttachment)
2361 { 2653 {
2362 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2654 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2363 vel = avatar.Velocity; 2655 if (avatar != null)
2656 vel = avatar.Velocity;
2364 } 2657 }
2365 else 2658 else
2366 { 2659 {
2367 vel = m_host.Velocity; 2660 vel = m_host.ParentGroup.RootPart.Velocity;
2368 } 2661 }
2369 2662
2370 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2663 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2376,10 +2669,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2376 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2669 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2377 } 2670 }
2378 2671
2672 public void llSetAngularVelocity(LSL_Vector avel, int local)
2673 {
2674 m_host.AddScriptLPS(1);
2675 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2676 }
2677
2379 public LSL_Vector llGetOmega() 2678 public LSL_Vector llGetOmega()
2380 { 2679 {
2381 m_host.AddScriptLPS(1); 2680 m_host.AddScriptLPS(1);
2382 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2681 Vector3 avel = m_host.AngularVelocity;
2682 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2383 } 2683 }
2384 2684
2385 public LSL_Float llGetTimeOfDay() 2685 public LSL_Float llGetTimeOfDay()
@@ -2768,7 +3068,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2768 } 3068 }
2769 3069
2770 bool result = money.ObjectGiveMoney( 3070 bool result = money.ObjectGiveMoney(
2771 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3071 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2772 3072
2773 if (result) 3073 if (result)
2774 return 1; 3074 return 1;
@@ -2852,13 +3152,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2852 new_group.RootPart.UUID.ToString()) }, 3152 new_group.RootPart.UUID.ToString()) },
2853 new DetectParams[0])); 3153 new DetectParams[0]));
2854 3154
2855 float groupmass = new_group.GetMass(); 3155 // do recoil
3156 SceneObjectGroup hostgrp = m_host.ParentGroup;
3157 if (hostgrp == null)
3158 return;
3159
3160 if (hostgrp.IsAttachment) // don't recoil avatars
3161 return;
2856 3162
2857 PhysicsActor pa = new_group.RootPart.PhysActor; 3163 PhysicsActor pa = new_group.RootPart.PhysActor;
2858 3164
2859 //Recoil. 3165 //Recoil.
2860 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3166 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2861 { 3167 {
3168 float groupmass = new_group.GetMass();
2862 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3169 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2863 if (recoil != Vector3.Zero) 3170 if (recoil != Vector3.Zero)
2864 { 3171 {
@@ -2866,6 +3173,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2866 } 3173 }
2867 } 3174 }
2868 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3175 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3176 return;
3177
2869 }); 3178 });
2870 3179
2871 //ScriptSleep((int)((groupmass * velmag) / 10)); 3180 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2880,35 +3189,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2880 public void llLookAt(LSL_Vector target, double strength, double damping) 3189 public void llLookAt(LSL_Vector target, double strength, double damping)
2881 { 3190 {
2882 m_host.AddScriptLPS(1); 3191 m_host.AddScriptLPS(1);
2883 // Determine where we are looking from
2884 LSL_Vector from = llGetPos();
2885 3192
2886 // Work out the normalised vector from the source to the target 3193 // Get the normalized vector to the target
2887 LSL_Vector delta = llVecNorm(target - from); 3194 LSL_Vector d1 = llVecNorm(target - llGetPos());
2888 LSL_Vector angle = new LSL_Vector(0,0,0);
2889 3195
2890 // Calculate the yaw 3196 // Get the bearing (yaw)
2891 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3197 LSL_Vector a1 = new LSL_Vector(0,0,0);
2892 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3198 a1.z = llAtan2(d1.y, d1.x);
2893 3199
2894 // Calculate pitch 3200 // Get the elevation (pitch)
2895 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3201 LSL_Vector a2 = new LSL_Vector(0,0,0);
3202 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2896 3203
2897 // we need to convert from a vector describing 3204 LSL_Rotation r1 = llEuler2Rot(a1);
2898 // the angles of rotation in radians into rotation value 3205 LSL_Rotation r2 = llEuler2Rot(a2);
2899 LSL_Rotation rot = llEuler2Rot(angle); 3206 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2900
2901 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2902 // set the rotation of the object, copy that behavior
2903 PhysicsActor pa = m_host.PhysActor;
2904 3207
2905 if (strength == 0 || pa == null || !pa.IsPhysical) 3208 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2906 { 3209 {
2907 llSetRot(rot); 3210 // Do nothing if either value is 0 (this has been checked in SL)
3211 if (strength <= 0.0 || damping <= 0.0)
3212 return;
3213
3214 llSetRot(r3 * r2 * r1);
2908 } 3215 }
2909 else 3216 else
2910 { 3217 {
2911 m_host.StartLookAt(rot, (float)strength, (float)damping); 3218 if (strength == 0)
3219 {
3220 llSetRot(r3 * r2 * r1);
3221 return;
3222 }
3223
3224 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2912 } 3225 }
2913 } 3226 }
2914 3227
@@ -2955,17 +3268,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2955 } 3268 }
2956 else 3269 else
2957 { 3270 {
2958 if (m_host.IsRoot) 3271 // new SL always returns object mass
2959 { 3272// if (m_host.IsRoot)
3273// {
2960 return m_host.ParentGroup.GetMass(); 3274 return m_host.ParentGroup.GetMass();
2961 } 3275// }
2962 else 3276// else
2963 { 3277// {
2964 return m_host.GetMass(); 3278// return m_host.GetMass();
2965 } 3279// }
2966 } 3280 }
2967 } 3281 }
2968 3282
3283
3284 public LSL_Float llGetMassMKS()
3285 {
3286 return 100f * llGetMass();
3287 }
3288
2969 public void llCollisionFilter(string name, string id, int accept) 3289 public void llCollisionFilter(string name, string id, int accept)
2970 { 3290 {
2971 m_host.AddScriptLPS(1); 3291 m_host.AddScriptLPS(1);
@@ -3013,8 +3333,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3013 { 3333 {
3014 // Unregister controls from Presence 3334 // Unregister controls from Presence
3015 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3335 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3016 // Remove Take Control permission.
3017 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3018 } 3336 }
3019 } 3337 }
3020 } 3338 }
@@ -3042,7 +3360,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3042 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3360 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3043 3361
3044 if (attachmentsModule != null) 3362 if (attachmentsModule != null)
3045 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3363 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3046 else 3364 else
3047 return false; 3365 return false;
3048 } 3366 }
@@ -3072,9 +3390,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3072 { 3390 {
3073 m_host.AddScriptLPS(1); 3391 m_host.AddScriptLPS(1);
3074 3392
3075// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3076// return;
3077
3078 if (m_item.PermsGranter != m_host.OwnerID) 3393 if (m_item.PermsGranter != m_host.OwnerID)
3079 return; 3394 return;
3080 3395
@@ -3117,6 +3432,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3117 3432
3118 public void llInstantMessage(string user, string message) 3433 public void llInstantMessage(string user, string message)
3119 { 3434 {
3435 UUID result;
3436 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3437 {
3438 ShoutError("An invalid key was passed to llInstantMessage");
3439 ScriptSleep(2000);
3440 return;
3441 }
3442
3443
3120 m_host.AddScriptLPS(1); 3444 m_host.AddScriptLPS(1);
3121 3445
3122 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3446 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3131,14 +3455,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3131 UUID friendTransactionID = UUID.Random(); 3455 UUID friendTransactionID = UUID.Random();
3132 3456
3133 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3457 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3134 3458
3135 GridInstantMessage msg = new GridInstantMessage(); 3459 GridInstantMessage msg = new GridInstantMessage();
3136 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3460 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3137 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3461 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3138 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3462 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3139// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3463// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3140// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3464// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3141 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3465// DateTime dt = DateTime.UtcNow;
3466//
3467// // Ticks from UtcNow, but make it look like local. Evil, huh?
3468// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3469//
3470// try
3471// {
3472// // Convert that to the PST timezone
3473// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3474// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3475// }
3476// catch
3477// {
3478// // No logging here, as it could be VERY spammy
3479// }
3480//
3481// // And make it look local again to fool the unix time util
3482// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3483
3484 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3485
3142 //if (client != null) 3486 //if (client != null)
3143 //{ 3487 //{
3144 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3488 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3152,12 +3496,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3152 msg.message = message.Substring(0, 1024); 3496 msg.message = message.Substring(0, 1024);
3153 else 3497 else
3154 msg.message = message; 3498 msg.message = message;
3155 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3499 msg.dialog = (byte)19; // MessageFromObject
3156 msg.fromGroup = false;// fromGroup; 3500 msg.fromGroup = false;// fromGroup;
3157 msg.offline = (byte)0; //offline; 3501 msg.offline = (byte)0; //offline;
3158 msg.ParentEstateID = 0; //ParentEstateID; 3502 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3159 msg.Position = new Vector3(m_host.AbsolutePosition); 3503 msg.Position = new Vector3(m_host.AbsolutePosition);
3160 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3504 msg.RegionID = World.RegionInfo.RegionID.Guid;
3161 msg.binaryBucket 3505 msg.binaryBucket
3162 = Util.StringToBytes256( 3506 = Util.StringToBytes256(
3163 "{0}/{1}/{2}/{3}", 3507 "{0}/{1}/{2}/{3}",
@@ -3185,7 +3529,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3185 } 3529 }
3186 3530
3187 emailModule.SendEmail(m_host.UUID, address, subject, message); 3531 emailModule.SendEmail(m_host.UUID, address, subject, message);
3188 llSleep(EMAIL_PAUSE_TIME); 3532 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3189 } 3533 }
3190 3534
3191 public void llGetNextEmail(string address, string subject) 3535 public void llGetNextEmail(string address, string subject)
@@ -3431,7 +3775,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3431 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3775 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3432 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3776 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3433 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3777 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3778 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3434 ScriptBaseClass.PERMISSION_ATTACH; 3779 ScriptBaseClass.PERMISSION_ATTACH;
3780
3435 } 3781 }
3436 else 3782 else
3437 { 3783 {
@@ -3448,15 +3794,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3448 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3794 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3449 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3795 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3450 } 3796 }
3797 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3798 {
3799 implicitPerms = perm;
3800 }
3451 } 3801 }
3452 3802
3453 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3803 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3454 { 3804 {
3455 lock (m_host.TaskInventory) 3805 m_host.TaskInventory.LockItemsForWrite(true);
3456 { 3806 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3457 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3807 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3458 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3808 m_host.TaskInventory.LockItemsForWrite(false);
3459 }
3460 3809
3461 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3810 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3462 "run_time_permissions", new Object[] { 3811 "run_time_permissions", new Object[] {
@@ -3499,11 +3848,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3499 3848
3500 if (!m_waitingForScriptAnswer) 3849 if (!m_waitingForScriptAnswer)
3501 { 3850 {
3502 lock (m_host.TaskInventory) 3851 m_host.TaskInventory.LockItemsForWrite(true);
3503 { 3852 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3504 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3853 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3505 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3854 m_host.TaskInventory.LockItemsForWrite(false);
3506 }
3507 3855
3508 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3856 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3509 m_waitingForScriptAnswer=true; 3857 m_waitingForScriptAnswer=true;
@@ -3532,14 +3880,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3532 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3880 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3533 llReleaseControls(); 3881 llReleaseControls();
3534 3882
3535 lock (m_host.TaskInventory) 3883 m_host.TaskInventory.LockItemsForWrite(true);
3536 { 3884 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3537 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3885 m_host.TaskInventory.LockItemsForWrite(false);
3538 } 3886
3539 3887 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3540 m_ScriptEngine.PostScriptEvent( 3888 "run_time_permissions", new Object[] {
3541 m_item.ItemID, 3889 new LSL_Integer(answer) },
3542 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3890 new DetectParams[0]));
3543 } 3891 }
3544 3892
3545 public LSL_String llGetPermissionsKey() 3893 public LSL_String llGetPermissionsKey()
@@ -3578,14 +3926,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3578 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3926 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3579 { 3927 {
3580 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3928 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3581 3929 if (parts.Count > 0)
3582 foreach (SceneObjectPart part in parts) 3930 {
3583 part.SetFaceColorAlpha(face, color, null); 3931 try
3932 {
3933 foreach (SceneObjectPart part in parts)
3934 part.SetFaceColorAlpha(face, color, null);
3935 }
3936 finally
3937 {
3938 }
3939 }
3584 } 3940 }
3585 3941
3586 public void llCreateLink(string target, int parent) 3942 public void llCreateLink(string target, int parent)
3587 { 3943 {
3588 m_host.AddScriptLPS(1); 3944 m_host.AddScriptLPS(1);
3945
3589 UUID targetID; 3946 UUID targetID;
3590 3947
3591 if (!UUID.TryParse(target, out targetID)) 3948 if (!UUID.TryParse(target, out targetID))
@@ -3691,10 +4048,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3691 // Restructuring Multiple Prims. 4048 // Restructuring Multiple Prims.
3692 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4049 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3693 parts.Remove(parentPrim.RootPart); 4050 parts.Remove(parentPrim.RootPart);
3694 foreach (SceneObjectPart part in parts) 4051 if (parts.Count > 0)
3695 { 4052 {
3696 parentPrim.DelinkFromGroup(part.LocalId, true); 4053 try
4054 {
4055 foreach (SceneObjectPart part in parts)
4056 {
4057 parentPrim.DelinkFromGroup(part.LocalId, true);
4058 }
4059 }
4060 finally
4061 {
4062 }
3697 } 4063 }
4064
3698 parentPrim.HasGroupChanged = true; 4065 parentPrim.HasGroupChanged = true;
3699 parentPrim.ScheduleGroupForFullUpdate(); 4066 parentPrim.ScheduleGroupForFullUpdate();
3700 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4067 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3703,12 +4070,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3703 { 4070 {
3704 SceneObjectPart newRoot = parts[0]; 4071 SceneObjectPart newRoot = parts[0];
3705 parts.Remove(newRoot); 4072 parts.Remove(newRoot);
3706 foreach (SceneObjectPart part in parts) 4073
4074 try
3707 { 4075 {
3708 // Required for linking 4076 foreach (SceneObjectPart part in parts)
3709 part.ClearUpdateSchedule(); 4077 {
3710 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4078 part.ClearUpdateSchedule();
4079 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4080 }
3711 } 4081 }
4082 finally
4083 {
4084 }
4085
4086
3712 newRoot.ParentGroup.HasGroupChanged = true; 4087 newRoot.ParentGroup.HasGroupChanged = true;
3713 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4088 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3714 } 4089 }
@@ -3728,6 +4103,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3728 public void llBreakAllLinks() 4103 public void llBreakAllLinks()
3729 { 4104 {
3730 m_host.AddScriptLPS(1); 4105 m_host.AddScriptLPS(1);
4106
4107 TaskInventoryItem item = m_item;
4108
4109 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4110 && !m_automaticLinkPermission)
4111 {
4112 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4113 return;
4114 }
4115
3731 SceneObjectGroup parentPrim = m_host.ParentGroup; 4116 SceneObjectGroup parentPrim = m_host.ParentGroup;
3732 if (parentPrim.AttachmentPoint != 0) 4117 if (parentPrim.AttachmentPoint != 0)
3733 return; // Fail silently if attached 4118 return; // Fail silently if attached
@@ -3747,47 +4132,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3747 public LSL_String llGetLinkKey(int linknum) 4132 public LSL_String llGetLinkKey(int linknum)
3748 { 4133 {
3749 m_host.AddScriptLPS(1); 4134 m_host.AddScriptLPS(1);
3750 4135 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3751 if (linknum < 0) 4136 if (part != null)
3752 {
3753 if (linknum == ScriptBaseClass.LINK_THIS)
3754 return m_host.UUID.ToString();
3755 else
3756 return ScriptBaseClass.NULL_KEY;
3757 }
3758
3759 int actualPrimCount = m_host.ParentGroup.PrimCount;
3760 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
3761 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
3762
3763 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
3764 // prim that has any avatars sat upon it (in which case the root prim is link 1).
3765 if (linknum == 0)
3766 {
3767 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
3768 return m_host.UUID.ToString();
3769
3770 return ScriptBaseClass.NULL_KEY;
3771 }
3772 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
3773 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
3774 else if (linknum == 1 && actualPrimCount == 1)
3775 {
3776 if (sittingAvatarIds.Count > 0)
3777 return m_host.ParentGroup.RootPart.UUID.ToString();
3778 else
3779 return ScriptBaseClass.NULL_KEY;
3780 }
3781 else if (linknum <= adjustedPrimCount)
3782 { 4137 {
3783 if (linknum <= actualPrimCount) 4138 return part.UUID.ToString();
3784 return m_host.ParentGroup.GetLinkNumPart(linknum).UUID.ToString();
3785 else
3786 return sittingAvatarIds[linknum - actualPrimCount - 1].ToString();
3787 } 4139 }
3788 else 4140 else
3789 { 4141 {
3790 return ScriptBaseClass.NULL_KEY; 4142 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4143 {
4144 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4145
4146 if (linknum < 0)
4147 return UUID.Zero.ToString();
4148
4149 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4150 if (avatars.Count > linknum)
4151 {
4152 return avatars[linknum].UUID.ToString();
4153 }
4154 }
4155 return UUID.Zero.ToString();
3791 } 4156 }
3792 } 4157 }
3793 4158
@@ -3890,17 +4255,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3890 m_host.AddScriptLPS(1); 4255 m_host.AddScriptLPS(1);
3891 int count = 0; 4256 int count = 0;
3892 4257
3893 lock (m_host.TaskInventory) 4258 m_host.TaskInventory.LockItemsForRead(true);
4259 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3894 { 4260 {
3895 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4261 if (inv.Value.Type == type || type == -1)
3896 { 4262 {
3897 if (inv.Value.Type == type || type == -1) 4263 count = count + 1;
3898 {
3899 count = count + 1;
3900 }
3901 } 4264 }
3902 } 4265 }
3903 4266
4267 m_host.TaskInventory.LockItemsForRead(false);
3904 return count; 4268 return count;
3905 } 4269 }
3906 4270
@@ -3909,16 +4273,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3909 m_host.AddScriptLPS(1); 4273 m_host.AddScriptLPS(1);
3910 ArrayList keys = new ArrayList(); 4274 ArrayList keys = new ArrayList();
3911 4275
3912 lock (m_host.TaskInventory) 4276 m_host.TaskInventory.LockItemsForRead(true);
4277 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3913 { 4278 {
3914 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4279 if (inv.Value.Type == type || type == -1)
3915 { 4280 {
3916 if (inv.Value.Type == type || type == -1) 4281 keys.Add(inv.Value.Name);
3917 {
3918 keys.Add(inv.Value.Name);
3919 }
3920 } 4282 }
3921 } 4283 }
4284 m_host.TaskInventory.LockItemsForRead(false);
3922 4285
3923 if (keys.Count == 0) 4286 if (keys.Count == 0)
3924 { 4287 {
@@ -3956,7 +4319,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3956 if (item == null) 4319 if (item == null)
3957 { 4320 {
3958 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4321 llSay(0, String.Format("Could not find object '{0}'", inventory));
3959 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4322 return;
4323// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3960 } 4324 }
3961 4325
3962 UUID objId = item.ItemID; 4326 UUID objId = item.ItemID;
@@ -3984,33 +4348,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3984 return; 4348 return;
3985 } 4349 }
3986 } 4350 }
4351
3987 // destination is an avatar 4352 // destination is an avatar
3988 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4353 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3989 4354
3990 if (agentItem == null) 4355 if (agentItem == null)
3991 return; 4356 return;
3992 4357
3993 if (m_TransferModule != null) 4358 byte[] bucket = new byte[1];
3994 { 4359 bucket[0] = (byte)item.Type;
3995 byte[] bucket = new byte[1]; 4360 //byte[] objBytes = agentItem.ID.GetBytes();
3996 bucket[0] = (byte)item.Type; 4361 //Array.Copy(objBytes, 0, bucket, 1, 16);
3997 4362
3998 GridInstantMessage msg = new GridInstantMessage(World, 4363 GridInstantMessage msg = new GridInstantMessage(World,
3999 m_host.OwnerID, m_host.Name, destId, 4364 m_host.OwnerID, m_host.Name, destId,
4000 (byte)InstantMessageDialog.TaskInventoryOffered, 4365 (byte)InstantMessageDialog.TaskInventoryOffered,
4001 false, item.Name+". "+m_host.Name+" is located at "+ 4366 false, item.Name+". "+m_host.Name+" is located at "+
4002 World.RegionInfo.RegionName+" "+ 4367 World.RegionInfo.RegionName+" "+
4003 m_host.AbsolutePosition.ToString(), 4368 m_host.AbsolutePosition.ToString(),
4004 agentItem.ID, true, m_host.AbsolutePosition, 4369 agentItem.ID, true, m_host.AbsolutePosition,
4005 bucket, true); 4370 bucket, true);
4006 4371
4007 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4372 ScenePresence sp;
4008 }
4009 4373
4374 if (World.TryGetScenePresence(destId, out sp))
4375 {
4376 sp.ControllingClient.SendInstantMessage(msg);
4377 }
4378 else
4379 {
4380 if (m_TransferModule != null)
4381 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4382 }
4383
4384 //This delay should only occur when giving inventory to avatars.
4010 ScriptSleep(3000); 4385 ScriptSleep(3000);
4011 } 4386 }
4012 } 4387 }
4013 4388
4389 [DebuggerNonUserCode]
4014 public void llRemoveInventory(string name) 4390 public void llRemoveInventory(string name)
4015 { 4391 {
4016 m_host.AddScriptLPS(1); 4392 m_host.AddScriptLPS(1);
@@ -4065,109 +4441,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4065 { 4441 {
4066 m_host.AddScriptLPS(1); 4442 m_host.AddScriptLPS(1);
4067 4443
4068 UUID uuid = (UUID)id; 4444 UUID uuid;
4069 PresenceInfo pinfo = null; 4445 if (UUID.TryParse(id, out uuid))
4070 UserAccount account;
4071
4072 UserInfoCacheEntry ce;
4073 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4074 { 4446 {
4075 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4447 PresenceInfo pinfo = null;
4076 if (account == null) 4448 UserAccount account;
4449
4450 UserInfoCacheEntry ce;
4451 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4077 { 4452 {
4078 m_userInfoCache[uuid] = null; // Cache negative 4453 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4079 return UUID.Zero.ToString(); 4454 if (account == null)
4080 } 4455 {
4456 m_userInfoCache[uuid] = null; // Cache negative
4457 return UUID.Zero.ToString();
4458 }
4081 4459
4082 4460
4083 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4461 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4084 if (pinfos != null && pinfos.Length > 0) 4462 if (pinfos != null && pinfos.Length > 0)
4085 {
4086 foreach (PresenceInfo p in pinfos)
4087 { 4463 {
4088 if (p.RegionID != UUID.Zero) 4464 foreach (PresenceInfo p in pinfos)
4089 { 4465 {
4090 pinfo = p; 4466 if (p.RegionID != UUID.Zero)
4467 {
4468 pinfo = p;
4469 }
4091 } 4470 }
4092 } 4471 }
4093 }
4094 4472
4095 ce = new UserInfoCacheEntry(); 4473 ce = new UserInfoCacheEntry();
4096 ce.time = Util.EnvironmentTickCount(); 4474 ce.time = Util.EnvironmentTickCount();
4097 ce.account = account; 4475 ce.account = account;
4098 ce.pinfo = pinfo; 4476 ce.pinfo = pinfo;
4099 } 4477 m_userInfoCache[uuid] = ce;
4100 else 4478 }
4101 { 4479 else
4102 if (ce == null) 4480 {
4103 return UUID.Zero.ToString(); 4481 if (ce == null)
4482 return UUID.Zero.ToString();
4104 4483
4105 account = ce.account; 4484 account = ce.account;
4106 pinfo = ce.pinfo; 4485 pinfo = ce.pinfo;
4107 } 4486 }
4108 4487
4109 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4488 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4110 {
4111 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4112 if (pinfos != null && pinfos.Length > 0)
4113 { 4489 {
4114 foreach (PresenceInfo p in pinfos) 4490 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4491 if (pinfos != null && pinfos.Length > 0)
4115 { 4492 {
4116 if (p.RegionID != UUID.Zero) 4493 foreach (PresenceInfo p in pinfos)
4117 { 4494 {
4118 pinfo = p; 4495 if (p.RegionID != UUID.Zero)
4496 {
4497 pinfo = p;
4498 }
4119 } 4499 }
4120 } 4500 }
4121 } 4501 else
4122 else 4502 pinfo = null;
4123 pinfo = null;
4124 4503
4125 ce.time = Util.EnvironmentTickCount(); 4504 ce.time = Util.EnvironmentTickCount();
4126 ce.pinfo = pinfo; 4505 ce.pinfo = pinfo;
4127 } 4506 }
4128 4507
4129 string reply = String.Empty; 4508 string reply = String.Empty;
4130 4509
4131 switch (data) 4510 switch (data)
4132 { 4511 {
4133 case 1: // DATA_ONLINE (0|1) 4512 case 1: // DATA_ONLINE (0|1)
4134 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4513 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4135 reply = "1"; 4514 reply = "1";
4136 else 4515 else
4137 reply = "0"; 4516 reply = "0";
4138 break; 4517 break;
4139 case 2: // DATA_NAME (First Last) 4518 case 2: // DATA_NAME (First Last)
4140 reply = account.FirstName + " " + account.LastName; 4519 reply = account.FirstName + " " + account.LastName;
4141 break; 4520 break;
4142 case 3: // DATA_BORN (YYYY-MM-DD) 4521 case 3: // DATA_BORN (YYYY-MM-DD)
4143 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4522 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4144 born = born.AddSeconds(account.Created); 4523 born = born.AddSeconds(account.Created);
4145 reply = born.ToString("yyyy-MM-dd"); 4524 reply = born.ToString("yyyy-MM-dd");
4146 break; 4525 break;
4147 case 4: // DATA_RATING (0,0,0,0,0,0) 4526 case 4: // DATA_RATING (0,0,0,0,0,0)
4148 reply = "0,0,0,0,0,0"; 4527 reply = "0,0,0,0,0,0";
4149 break; 4528 break;
4150 case 7: // DATA_USERLEVEL (integer) 4529 case 8: // DATA_PAYINFO (0|1|2|3)
4151 reply = account.UserLevel.ToString(); 4530 reply = "0";
4152 break; 4531 break;
4153 case 8: // DATA_PAYINFO (0|1|2|3) 4532 default:
4154 reply = "0"; 4533 return UUID.Zero.ToString(); // Raise no event
4155 break; 4534 }
4156 default:
4157 return UUID.Zero.ToString(); // Raise no event
4158 }
4159 4535
4160 UUID rq = UUID.Random(); 4536 UUID rq = UUID.Random();
4161 4537
4162 UUID tid = AsyncCommands. 4538 UUID tid = AsyncCommands.
4163 DataserverPlugin.RegisterRequest(m_host.LocalId, 4539 DataserverPlugin.RegisterRequest(m_host.LocalId,
4164 m_item.ItemID, rq.ToString()); 4540 m_item.ItemID, rq.ToString());
4165 4541
4166 AsyncCommands. 4542 AsyncCommands.
4167 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4543 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4168 4544
4169 ScriptSleep(100); 4545 ScriptSleep(100);
4170 return tid.ToString(); 4546 return tid.ToString();
4547 }
4548 else
4549 {
4550 ShoutError("Invalid UUID passed to llRequestAgentData.");
4551 }
4552 return "";
4171 } 4553 }
4172 4554
4173 public LSL_String llRequestInventoryData(string name) 4555 public LSL_String llRequestInventoryData(string name)
@@ -4224,13 +4606,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4224 if (UUID.TryParse(agent, out agentId)) 4606 if (UUID.TryParse(agent, out agentId))
4225 { 4607 {
4226 ScenePresence presence = World.GetScenePresence(agentId); 4608 ScenePresence presence = World.GetScenePresence(agentId);
4227 if (presence != null) 4609 if (presence != null && presence.PresenceType != PresenceType.Npc)
4228 { 4610 {
4611 // agent must not be a god
4612 if (presence.UserLevel >= 200) return;
4613
4229 // agent must be over the owners land 4614 // agent must be over the owners land
4230 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4615 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4231 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4616 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4232 { 4617 {
4233 World.TeleportClientHome(agentId, presence.ControllingClient); 4618 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4619 {
4620 // They can't be teleported home for some reason
4621 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4622 if (regionInfo != null)
4623 {
4624 World.RequestTeleportLocation(
4625 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4626 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4627 }
4628 }
4234 } 4629 }
4235 } 4630 }
4236 } 4631 }
@@ -4337,7 +4732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4337 UUID av = new UUID(); 4732 UUID av = new UUID();
4338 if (!UUID.TryParse(agent,out av)) 4733 if (!UUID.TryParse(agent,out av))
4339 { 4734 {
4340 LSLError("First parameter to llDialog needs to be a key"); 4735 //LSLError("First parameter to llDialog needs to be a key");
4341 return; 4736 return;
4342 } 4737 }
4343 4738
@@ -4369,10 +4764,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4369 public void llCollisionSound(string impact_sound, double impact_volume) 4764 public void llCollisionSound(string impact_sound, double impact_volume)
4370 { 4765 {
4371 m_host.AddScriptLPS(1); 4766 m_host.AddScriptLPS(1);
4372 4767
4768 if(impact_sound == "")
4769 {
4770 m_host.CollisionSoundVolume = (float)impact_volume;
4771 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4772 m_host.CollisionSoundType = 0;
4773 return;
4774 }
4373 // TODO: Parameter check logic required. 4775 // TODO: Parameter check logic required.
4374 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4776 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound);
4375 m_host.CollisionSoundVolume = (float)impact_volume; 4777 m_host.CollisionSoundVolume = (float)impact_volume;
4778 m_host.CollisionSoundType = 1;
4376 } 4779 }
4377 4780
4378 public LSL_String llGetAnimation(string id) 4781 public LSL_String llGetAnimation(string id)
@@ -4386,14 +4789,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4386 4789
4387 if (m_host.RegionHandle == presence.RegionHandle) 4790 if (m_host.RegionHandle == presence.RegionHandle)
4388 { 4791 {
4389 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4390
4391 if (presence != null) 4792 if (presence != null)
4392 { 4793 {
4393 AnimationSet currentAnims = presence.Animator.Animations; 4794 if (presence.SitGround)
4394 string currentAnimationState = String.Empty; 4795 return "Sitting on Ground";
4395 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4796 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4396 return currentAnimationState; 4797 return "Sitting";
4798
4799 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4800 string lslMovementAnimation;
4801
4802 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4803 return lslMovementAnimation;
4397 } 4804 }
4398 } 4805 }
4399 4806
@@ -4540,7 +4947,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4540 { 4947 {
4541 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4948 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4542 float distance_term = distance * distance * distance; // Script Energy 4949 float distance_term = distance * distance * distance; // Script Energy
4543 float pusher_mass = m_host.GetMass(); 4950 // use total object mass and not part
4951 float pusher_mass = m_host.ParentGroup.GetMass();
4544 4952
4545 float PUSH_ATTENUATION_DISTANCE = 17f; 4953 float PUSH_ATTENUATION_DISTANCE = 17f;
4546 float PUSH_ATTENUATION_SCALE = 5f; 4954 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4790,6 +5198,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4790 { 5198 {
4791 return item.AssetID.ToString(); 5199 return item.AssetID.ToString();
4792 } 5200 }
5201 m_host.TaskInventory.LockItemsForRead(false);
4793 5202
4794 return UUID.Zero.ToString(); 5203 return UUID.Zero.ToString();
4795 } 5204 }
@@ -4923,7 +5332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4923 public LSL_Vector llGetCenterOfMass() 5332 public LSL_Vector llGetCenterOfMass()
4924 { 5333 {
4925 m_host.AddScriptLPS(1); 5334 m_host.AddScriptLPS(1);
4926 Vector3 center = m_host.GetGeometricCenter(); 5335 Vector3 center = m_host.GetCenterOfMass();
4927 return new LSL_Vector(center.X,center.Y,center.Z); 5336 return new LSL_Vector(center.X,center.Y,center.Z);
4928 } 5337 }
4929 5338
@@ -4942,14 +5351,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4942 { 5351 {
4943 m_host.AddScriptLPS(1); 5352 m_host.AddScriptLPS(1);
4944 5353
4945 if (src == null) 5354 return src.Length;
4946 {
4947 return 0;
4948 }
4949 else
4950 {
4951 return src.Length;
4952 }
4953 } 5355 }
4954 5356
4955 public LSL_Integer llList2Integer(LSL_List src, int index) 5357 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5020,7 +5422,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5020 else if (src.Data[index] is LSL_Float) 5422 else if (src.Data[index] is LSL_Float)
5021 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5423 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5022 else if (src.Data[index] is LSL_String) 5424 else if (src.Data[index] is LSL_String)
5023 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5425 {
5426 string str = ((LSL_String) src.Data[index]).m_string;
5427 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5428 if (m != Match.Empty)
5429 {
5430 str = m.Value;
5431 double d = 0.0;
5432 if (!Double.TryParse(str, out d))
5433 return 0.0;
5434
5435 return d;
5436 }
5437 return 0.0;
5438 }
5024 return Convert.ToDouble(src.Data[index]); 5439 return Convert.ToDouble(src.Data[index]);
5025 } 5440 }
5026 catch (FormatException) 5441 catch (FormatException)
@@ -5062,7 +5477,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5062 // for completion and should LSL_Key ever be implemented 5477 // for completion and should LSL_Key ever be implemented
5063 // as it's own struct 5478 // as it's own struct
5064 else if (!(src.Data[index] is LSL_String || 5479 else if (!(src.Data[index] is LSL_String ||
5065 src.Data[index] is LSL_Key)) 5480 src.Data[index] is LSL_Key ||
5481 src.Data[index] is String))
5066 { 5482 {
5067 return ""; 5483 return "";
5068 } 5484 }
@@ -5320,7 +5736,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5320 } 5736 }
5321 } 5737 }
5322 } 5738 }
5323 else { 5739 else
5740 {
5324 object[] array = new object[src.Length]; 5741 object[] array = new object[src.Length];
5325 Array.Copy(src.Data, 0, array, 0, src.Length); 5742 Array.Copy(src.Data, 0, array, 0, src.Length);
5326 result = new LSL_List(array); 5743 result = new LSL_List(array);
@@ -5427,7 +5844,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5427 public LSL_Integer llGetRegionAgentCount() 5844 public LSL_Integer llGetRegionAgentCount()
5428 { 5845 {
5429 m_host.AddScriptLPS(1); 5846 m_host.AddScriptLPS(1);
5430 return new LSL_Integer(World.GetRootAgentCount()); 5847
5848 int count = 0;
5849 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5850 count++;
5851 });
5852
5853 return new LSL_Integer(count);
5431 } 5854 }
5432 5855
5433 public LSL_Vector llGetRegionCorner() 5856 public LSL_Vector llGetRegionCorner()
@@ -5668,6 +6091,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5668 flags |= ScriptBaseClass.AGENT_AWAY; 6091 flags |= ScriptBaseClass.AGENT_AWAY;
5669 } 6092 }
5670 6093
6094 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6095 UUID[] anims = agent.Animator.GetAnimationArray();
6096 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6097 {
6098 flags |= ScriptBaseClass.AGENT_BUSY;
6099 }
6100
5671 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6101 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5672 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6102 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5673 { 6103 {
@@ -5715,6 +6145,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5715 flags |= ScriptBaseClass.AGENT_SITTING; 6145 flags |= ScriptBaseClass.AGENT_SITTING;
5716 } 6146 }
5717 6147
6148 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6149 {
6150 flags |= ScriptBaseClass.AGENT_MALE;
6151 }
6152
5718 return flags; 6153 return flags;
5719 } 6154 }
5720 6155
@@ -5862,9 +6297,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5862 6297
5863 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6298 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5864 6299
5865 foreach (SceneObjectPart part in parts) 6300 try
6301 {
6302 foreach (SceneObjectPart part in parts)
6303 {
6304 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6305 }
6306 }
6307 finally
5866 { 6308 {
5867 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5868 } 6309 }
5869 } 6310 }
5870 6311
@@ -5918,13 +6359,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5918 6359
5919 if (m_host.OwnerID == land.LandData.OwnerID) 6360 if (m_host.OwnerID == land.LandData.OwnerID)
5920 { 6361 {
5921 World.TeleportClientHome(agentID, presence.ControllingClient); 6362 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6363 presence.TeleportWithMomentum(pos, null);
6364 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5922 } 6365 }
5923 } 6366 }
5924 } 6367 }
5925 ScriptSleep(5000); 6368 ScriptSleep(5000);
5926 } 6369 }
5927 6370
6371 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6372 {
6373 return ParseString2List(str, separators, in_spacers, false);
6374 }
6375
5928 public LSL_Integer llOverMyLand(string id) 6376 public LSL_Integer llOverMyLand(string id)
5929 { 6377 {
5930 m_host.AddScriptLPS(1); 6378 m_host.AddScriptLPS(1);
@@ -5978,25 +6426,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5978 } 6426 }
5979 else 6427 else
5980 { 6428 {
5981 agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); 6429// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6430 Vector3 s = avatar.Appearance.AvatarSize;
6431 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5982 } 6432 }
5983 return agentSize; 6433 return agentSize;
5984 } 6434 }
5985 6435
5986 public LSL_Integer llSameGroup(string agent) 6436 public LSL_Integer llSameGroup(string id)
5987 { 6437 {
5988 m_host.AddScriptLPS(1); 6438 m_host.AddScriptLPS(1);
5989 UUID agentId = new UUID(); 6439 UUID uuid = new UUID();
5990 if (!UUID.TryParse(agent, out agentId)) 6440 if (!UUID.TryParse(id, out uuid))
5991 return new LSL_Integer(0);
5992 ScenePresence presence = World.GetScenePresence(agentId);
5993 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5994 return new LSL_Integer(0); 6441 return new LSL_Integer(0);
5995 IClientAPI client = presence.ControllingClient; 6442
5996 if (m_host.GroupID == client.ActiveGroupId) 6443 // Check if it's a group key
6444 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5997 return new LSL_Integer(1); 6445 return new LSL_Integer(1);
5998 else 6446
6447 // We got passed a UUID.Zero
6448 if (uuid == UUID.Zero)
5999 return new LSL_Integer(0); 6449 return new LSL_Integer(0);
6450
6451 // Handle the case where id names an avatar
6452 ScenePresence presence = World.GetScenePresence(uuid);
6453 if (presence != null)
6454 {
6455 if (presence.IsChildAgent)
6456 return new LSL_Integer(0);
6457
6458 IClientAPI client = presence.ControllingClient;
6459 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6460 return new LSL_Integer(1);
6461
6462 return new LSL_Integer(0);
6463 }
6464
6465 // Handle object case
6466 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6467 if (part != null)
6468 {
6469 // This will handle both deed and non-deed and also the no
6470 // group case
6471 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6472 return new LSL_Integer(1);
6473
6474 return new LSL_Integer(0);
6475 }
6476
6477 return new LSL_Integer(0);
6000 } 6478 }
6001 6479
6002 public void llUnSit(string id) 6480 public void llUnSit(string id)
@@ -6121,7 +6599,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6121 return m_host.ParentGroup.AttachmentPoint; 6599 return m_host.ParentGroup.AttachmentPoint;
6122 } 6600 }
6123 6601
6124 public LSL_Integer llGetFreeMemory() 6602 public virtual LSL_Integer llGetFreeMemory()
6125 { 6603 {
6126 m_host.AddScriptLPS(1); 6604 m_host.AddScriptLPS(1);
6127 // Make scripts designed for LSO happy 6605 // Make scripts designed for LSO happy
@@ -6553,6 +7031,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6553 7031
6554 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7032 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6555 { 7033 {
7034 // LSL quaternions can normalize to 0, normal Quaternions can't.
7035 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7036 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7037
6556 part.SitTargetPosition = offset; 7038 part.SitTargetPosition = offset;
6557 part.SitTargetOrientation = rot; 7039 part.SitTargetOrientation = rot;
6558 part.ParentGroup.HasGroupChanged = true; 7040 part.ParentGroup.HasGroupChanged = true;
@@ -6738,13 +7220,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6738 UUID av = new UUID(); 7220 UUID av = new UUID();
6739 if (!UUID.TryParse(avatar,out av)) 7221 if (!UUID.TryParse(avatar,out av))
6740 { 7222 {
6741 LSLError("First parameter to llDialog needs to be a key"); 7223 //LSLError("First parameter to llDialog needs to be a key");
6742 return; 7224 return;
6743 } 7225 }
6744 if (buttons.Length < 1) 7226 if (buttons.Length < 1)
6745 { 7227 {
6746 LSLError("No less than 1 button can be shown"); 7228 buttons.Add("OK");
6747 return;
6748 } 7229 }
6749 if (buttons.Length > 12) 7230 if (buttons.Length > 12)
6750 { 7231 {
@@ -6761,7 +7242,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6761 } 7242 }
6762 if (buttons.Data[i].ToString().Length > 24) 7243 if (buttons.Data[i].ToString().Length > 24)
6763 { 7244 {
6764 LSLError("button label cannot be longer than 24 characters"); 7245 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6765 return; 7246 return;
6766 } 7247 }
6767 buts[i] = buttons.Data[i].ToString(); 7248 buts[i] = buttons.Data[i].ToString();
@@ -6828,9 +7309,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6828 return; 7309 return;
6829 } 7310 }
6830 7311
6831 // the rest of the permission checks are done in RezScript, so check the pin there as well 7312 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6832 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7313 if (dest != null)
7314 {
7315 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7316 {
7317 // the rest of the permission checks are done in RezScript, so check the pin there as well
7318 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6833 7319
7320 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7321 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7322 }
7323 }
6834 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7324 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6835 ScriptSleep(3000); 7325 ScriptSleep(3000);
6836 } 7326 }
@@ -6900,19 +7390,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6900 public LSL_String llMD5String(string src, int nonce) 7390 public LSL_String llMD5String(string src, int nonce)
6901 { 7391 {
6902 m_host.AddScriptLPS(1); 7392 m_host.AddScriptLPS(1);
6903 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7393 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6904 } 7394 }
6905 7395
6906 public LSL_String llSHA1String(string src) 7396 public LSL_String llSHA1String(string src)
6907 { 7397 {
6908 m_host.AddScriptLPS(1); 7398 m_host.AddScriptLPS(1);
6909 return Util.SHA1Hash(src).ToLower(); 7399 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6910 } 7400 }
6911 7401
6912 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7402 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6913 { 7403 {
6914 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7404 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6915 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7405 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7406 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7407 return shapeBlock;
6916 7408
6917 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7409 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6918 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7410 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -7017,6 +7509,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7017 // Prim type box, cylinder and prism. 7509 // Prim type box, cylinder and prism.
7018 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) 7510 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)
7019 { 7511 {
7512 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7513 return;
7514
7020 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7515 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7021 ObjectShapePacket.ObjectDataBlock shapeBlock; 7516 ObjectShapePacket.ObjectDataBlock shapeBlock;
7022 7517
@@ -7070,6 +7565,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7070 // Prim type sphere. 7565 // Prim type sphere.
7071 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7566 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7072 { 7567 {
7568 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7569 return;
7570
7073 ObjectShapePacket.ObjectDataBlock shapeBlock; 7571 ObjectShapePacket.ObjectDataBlock shapeBlock;
7074 7572
7075 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7573 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7111,6 +7609,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7111 // Prim type torus, tube and ring. 7609 // Prim type torus, tube and ring.
7112 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) 7610 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)
7113 { 7611 {
7612 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7613 return;
7614
7114 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7615 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7115 ObjectShapePacket.ObjectDataBlock shapeBlock; 7616 ObjectShapePacket.ObjectDataBlock shapeBlock;
7116 7617
@@ -7246,6 +7747,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7246 // Prim type sculpt. 7747 // Prim type sculpt.
7247 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7748 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7248 { 7749 {
7750 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7751 return;
7752
7249 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7753 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7250 UUID sculptId; 7754 UUID sculptId;
7251 7755
@@ -7270,7 +7774,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7270 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7774 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7271 { 7775 {
7272 // default 7776 // default
7273 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7777 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7274 } 7778 }
7275 7779
7276 part.Shape.SetSculptProperties((byte)type, sculptId); 7780 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7287,48 +7791,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7287 ScriptSleep(200); 7791 ScriptSleep(200);
7288 } 7792 }
7289 7793
7290 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7794 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7291 { 7795 {
7292 m_host.AddScriptLPS(1); 7796 m_host.AddScriptLPS(1);
7293 7797
7294 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7798 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7295 7799
7296 ScriptSleep(200); 7800 ScriptSleep(200);
7297 } 7801 }
7298 7802
7299 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7803 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7300 { 7804 {
7301 m_host.AddScriptLPS(1); 7805 List<object> parts = new List<object>();
7806 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7807 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7808 foreach (SceneObjectPart p in prims)
7809 parts.Add(p);
7810 foreach (ScenePresence p in avatars)
7811 parts.Add(p);
7302 7812
7303 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7813 LSL_List remaining = null;
7814 uint rulesParsed = 0;
7815
7816 if (parts.Count > 0)
7817 {
7818 foreach (object part in parts)
7819 {
7820 if (part is SceneObjectPart)
7821 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7822 else
7823 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7824 }
7825
7826 while ((object)remaining != null && remaining.Length > 2)
7827 {
7828 linknumber = remaining.GetLSLIntegerItem(0);
7829 rules = remaining.GetSublist(1, -1);
7830 parts.Clear();
7831 prims = GetLinkParts(linknumber);
7832 avatars = GetLinkAvatars(linknumber);
7833 foreach (SceneObjectPart p in prims)
7834 parts.Add(p);
7835 foreach (ScenePresence p in avatars)
7836 parts.Add(p);
7837
7838 remaining = null;
7839 foreach (object part in parts)
7840 {
7841 if (part is SceneObjectPart)
7842 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7843 else
7844 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7845 }
7846 }
7847 }
7304 } 7848 }
7305 7849
7306 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7850 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7851 float material_density, float material_friction,
7852 float material_restitution, float material_gravity_modifier)
7307 { 7853 {
7308 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7854 ExtraPhysicsData physdata = new ExtraPhysicsData();
7855 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7856 physdata.Density = part.Density;
7857 physdata.Friction = part.Friction;
7858 physdata.Bounce = part.Bounciness;
7859 physdata.GravitationModifier = part.GravityModifier;
7309 7860
7310 LSL_List remaining = null; 7861 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7311 uint rulesParsed = 0; 7862 physdata.Density = material_density;
7863 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7864 physdata.Friction = material_friction;
7865 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7866 physdata.Bounce = material_restitution;
7867 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7868 physdata.GravitationModifier = material_gravity_modifier;
7312 7869
7313 foreach (SceneObjectPart part in parts) 7870 part.UpdateExtraPhysics(physdata);
7314 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7871 }
7315 7872
7316 while (remaining != null && remaining.Length > 2) 7873 public void llSetPhysicsMaterial(int material_bits,
7317 { 7874 float material_gravity_modifier, float material_restitution,
7318 linknumber = remaining.GetLSLIntegerItem(0); 7875 float material_friction, float material_density)
7319 rules = remaining.GetSublist(1, -1); 7876 {
7320 parts = GetLinkParts(linknumber); 7877 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7878 }
7321 7879
7322 foreach (SceneObjectPart part in parts) 7880 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7323 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7881 {
7882 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7883 llSetLinkPrimitiveParamsFast(linknumber, rules);
7884 ScriptSleep(200);
7885 }
7886
7887 // vector up using libomv (c&p from sop )
7888 // vector up rotated by r
7889 private Vector3 Zrot(Quaternion r)
7890 {
7891 double x, y, z, m;
7892
7893 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7894 if (Math.Abs(1.0 - m) > 0.000001)
7895 {
7896 m = 1.0 / Math.Sqrt(m);
7897 r.X *= (float)m;
7898 r.Y *= (float)m;
7899 r.Z *= (float)m;
7900 r.W *= (float)m;
7324 } 7901 }
7902
7903 x = 2 * (r.X * r.Z + r.Y * r.W);
7904 y = 2 * (-r.X * r.W + r.Y * r.Z);
7905 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7906
7907 return new Vector3((float)x, (float)y, (float)z);
7325 } 7908 }
7326 7909
7327 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7910 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7328 { 7911 {
7912 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7913 return null;
7914
7329 int idx = 0; 7915 int idx = 0;
7330 int idxStart = 0; 7916 int idxStart = 0;
7331 7917
7918 SceneObjectGroup parentgrp = part.ParentGroup;
7919
7332 bool positionChanged = false; 7920 bool positionChanged = false;
7333 LSL_Vector currentPosition = GetPartLocalPos(part); 7921 LSL_Vector currentPosition = GetPartLocalPos(part);
7334 7922
@@ -7353,8 +7941,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7353 return null; 7941 return null;
7354 7942
7355 v=rules.GetVector3Item(idx++); 7943 v=rules.GetVector3Item(idx++);
7944 if (part.IsRoot && !part.ParentGroup.IsAttachment)
7945 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
7946 else
7947 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7356 positionChanged = true; 7948 positionChanged = true;
7357 currentPosition = GetSetPosTarget(part, v, currentPosition);
7358 7949
7359 break; 7950 break;
7360 case (int)ScriptBaseClass.PRIM_SIZE: 7951 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7371,7 +7962,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7371 7962
7372 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7963 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7373 // try to let this work as in SL... 7964 // try to let this work as in SL...
7374 if (part.ParentID == 0) 7965 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7375 { 7966 {
7376 // special case: If we are root, rotate complete SOG to new rotation 7967 // special case: If we are root, rotate complete SOG to new rotation
7377 SetRot(part, q); 7968 SetRot(part, q);
@@ -7631,7 +8222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7631 return null; 8222 return null;
7632 8223
7633 string ph = rules.Data[idx++].ToString(); 8224 string ph = rules.Data[idx++].ToString();
7634 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8225 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7635 8226
7636 break; 8227 break;
7637 8228
@@ -7649,12 +8240,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7649 part.ScriptSetPhysicsStatus(physics); 8240 part.ScriptSetPhysicsStatus(physics);
7650 break; 8241 break;
7651 8242
8243 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8244 if (remain < 1)
8245 return null;
8246
8247 int shape_type = rules.GetLSLIntegerItem(idx++);
8248
8249 ExtraPhysicsData physdata = new ExtraPhysicsData();
8250 physdata.Density = part.Density;
8251 physdata.Bounce = part.Bounciness;
8252 physdata.GravitationModifier = part.GravityModifier;
8253 physdata.PhysShapeType = (PhysShapeType)shape_type;
8254
8255 part.UpdateExtraPhysics(physdata);
8256
8257 break;
8258
8259 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8260 if (remain < 5)
8261 return null;
8262
8263 int material_bits = rules.GetLSLIntegerItem(idx++);
8264 float material_density = (float)rules.GetLSLFloatItem(idx++);
8265 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8266 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8267 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8268
8269 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8270
8271 break;
8272
7652 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8273 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7653 if (remain < 1) 8274 if (remain < 1)
7654 return null; 8275 return null;
7655 string temp = rules.Data[idx++].ToString(); 8276 string temp = rules.Data[idx++].ToString();
7656 8277
7657 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8278 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7658 8279
7659 break; 8280 break;
7660 8281
@@ -7728,7 +8349,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7728 if (part.ParentGroup.RootPart == part) 8349 if (part.ParentGroup.RootPart == part)
7729 { 8350 {
7730 SceneObjectGroup parent = part.ParentGroup; 8351 SceneObjectGroup parent = part.ParentGroup;
7731 parent.UpdateGroupPosition(currentPosition); 8352 Util.FireAndForget(delegate(object x) {
8353 parent.UpdateGroupPosition(currentPosition);
8354 });
7732 } 8355 }
7733 else 8356 else
7734 { 8357 {
@@ -7773,10 +8396,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7773 8396
7774 public LSL_String llXorBase64Strings(string str1, string str2) 8397 public LSL_String llXorBase64Strings(string str1, string str2)
7775 { 8398 {
7776 m_host.AddScriptLPS(1); 8399 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7777 Deprecated("llXorBase64Strings"); 8400
7778 ScriptSleep(300); 8401 ScriptSleep(300);
7779 return String.Empty; 8402 m_host.AddScriptLPS(1);
8403
8404 if (str1 == String.Empty)
8405 return String.Empty;
8406 if (str2 == String.Empty)
8407 return str1;
8408
8409 int len = str2.Length;
8410 if ((len % 4) != 0) // LL is EVIL!!!!
8411 {
8412 while (str2.EndsWith("="))
8413 str2 = str2.Substring(0, str2.Length - 1);
8414
8415 len = str2.Length;
8416 int mod = len % 4;
8417
8418 if (mod == 1)
8419 str2 = str2.Substring(0, str2.Length - 1);
8420 else if (mod == 2)
8421 str2 += "==";
8422 else if (mod == 3)
8423 str2 += "=";
8424 }
8425
8426 byte[] data1;
8427 byte[] data2;
8428 try
8429 {
8430 data1 = Convert.FromBase64String(str1);
8431 data2 = Convert.FromBase64String(str2);
8432 }
8433 catch (Exception)
8434 {
8435 return new LSL_String(String.Empty);
8436 }
8437
8438 // For cases where the decoded length of s2 is greater
8439 // than the decoded length of s1, simply perform a normal
8440 // decode and XOR
8441 //
8442 if (data2.Length >= data1.Length)
8443 {
8444 for (int pos = 0 ; pos < data1.Length ; pos++ )
8445 data1[pos] ^= data2[pos];
8446
8447 return Convert.ToBase64String(data1);
8448 }
8449
8450 // Remove padding
8451 while (str1.EndsWith("="))
8452 str1 = str1.Substring(0, str1.Length - 1);
8453 while (str2.EndsWith("="))
8454 str2 = str2.Substring(0, str2.Length - 1);
8455
8456 byte[] d1 = new byte[str1.Length];
8457 byte[] d2 = new byte[str2.Length];
8458
8459 for (int i = 0 ; i < str1.Length ; i++)
8460 {
8461 int idx = b64.IndexOf(str1.Substring(i, 1));
8462 if (idx == -1)
8463 idx = 0;
8464 d1[i] = (byte)idx;
8465 }
8466
8467 for (int i = 0 ; i < str2.Length ; i++)
8468 {
8469 int idx = b64.IndexOf(str2.Substring(i, 1));
8470 if (idx == -1)
8471 idx = 0;
8472 d2[i] = (byte)idx;
8473 }
8474
8475 string output = String.Empty;
8476
8477 for (int pos = 0 ; pos < d1.Length ; pos++)
8478 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8479
8480 while (output.Length % 3 > 0)
8481 output += "=";
8482
8483 return output;
7780 } 8484 }
7781 8485
7782 public void llRemoteDataSetRegion() 8486 public void llRemoteDataSetRegion()
@@ -7900,8 +8604,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7900 public LSL_Integer llGetNumberOfPrims() 8604 public LSL_Integer llGetNumberOfPrims()
7901 { 8605 {
7902 m_host.AddScriptLPS(1); 8606 m_host.AddScriptLPS(1);
7903 8607 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7904 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8608
8609 return m_host.ParentGroup.PrimCount + avatarCount;
7905 } 8610 }
7906 8611
7907 /// <summary> 8612 /// <summary>
@@ -7916,55 +8621,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7916 m_host.AddScriptLPS(1); 8621 m_host.AddScriptLPS(1);
7917 UUID objID = UUID.Zero; 8622 UUID objID = UUID.Zero;
7918 LSL_List result = new LSL_List(); 8623 LSL_List result = new LSL_List();
8624
8625 // If the ID is not valid, return null result
7919 if (!UUID.TryParse(obj, out objID)) 8626 if (!UUID.TryParse(obj, out objID))
7920 { 8627 {
7921 result.Add(new LSL_Vector()); 8628 result.Add(new LSL_Vector());
7922 result.Add(new LSL_Vector()); 8629 result.Add(new LSL_Vector());
7923 return result; 8630 return result;
7924 } 8631 }
8632
8633 // Check if this is an attached prim. If so, replace
8634 // the UUID with the avatar UUID and report it's bounding box
8635 SceneObjectPart part = World.GetSceneObjectPart(objID);
8636 if (part != null && part.ParentGroup.IsAttachment)
8637 objID = part.ParentGroup.AttachedAvatar;
8638
8639 // Find out if this is an avatar ID. If so, return it's box
7925 ScenePresence presence = World.GetScenePresence(objID); 8640 ScenePresence presence = World.GetScenePresence(objID);
7926 if (presence != null) 8641 if (presence != null)
7927 { 8642 {
7928 if (presence.ParentID == 0) // not sat on an object 8643 // As per LSL Wiki, there is no difference between sitting
8644 // and standing avatar since server 1.36
8645 LSL_Vector lower;
8646 LSL_Vector upper;
8647
8648 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8649
8650 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8651 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8652/*
7929 { 8653 {
7930 LSL_Vector lower; 8654 // This is for ground sitting avatars
7931 LSL_Vector upper; 8655 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7932 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8656 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7933 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8657 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7934 {
7935 // This is for ground sitting avatars
7936 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7937 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7938 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7939 }
7940 else
7941 {
7942 // This is for standing/flying avatars
7943 float height = presence.Appearance.AvatarHeight / 2.0f;
7944 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7945 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7946 }
7947 result.Add(lower);
7948 result.Add(upper);
7949 return result;
7950 } 8658 }
7951 else 8659 else
7952 { 8660 {
7953 // sitting on an object so we need the bounding box of that 8661 // This is for standing/flying avatars
7954 // which should include the avatar so set the UUID to the 8662 float height = presence.Appearance.AvatarHeight / 2.0f;
7955 // UUID of the object the avatar is sat on and allow it to fall through 8663 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7956 // to processing an object 8664 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7957 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID); 8665 }
7958 objID = p.UUID; 8666
8667 // Adjust to the documented error offsets (see LSL Wiki)
8668 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8669 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8670*/
8671 {
8672 // This is for ground sitting avatars TODO!
8673 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8674 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
7959 } 8675 }
8676 else
8677 {
8678 // This is for standing/flying avatars
8679 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8680 upper = new LSL_Vector(box.X, box.Y, box.Z);
8681 }
8682
8683 if (lower.x > upper.x)
8684 lower.x = upper.x;
8685 if (lower.y > upper.y)
8686 lower.y = upper.y;
8687 if (lower.z > upper.z)
8688 lower.z = upper.z;
8689
8690 result.Add(lower);
8691 result.Add(upper);
8692 return result;
7960 } 8693 }
7961 SceneObjectPart part = World.GetSceneObjectPart(objID); 8694
8695 part = World.GetSceneObjectPart(objID);
7962 // Currently only works for single prims without a sitting avatar 8696 // Currently only works for single prims without a sitting avatar
7963 if (part != null) 8697 if (part != null)
7964 { 8698 {
7965 Vector3 halfSize = part.Scale / 2.0f; 8699 float minX;
7966 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8700 float maxX;
7967 LSL_Vector upper = new LSL_Vector(halfSize); 8701 float minY;
8702 float maxY;
8703 float minZ;
8704 float maxZ;
8705
8706 // This BBox is in sim coordinates, with the offset being
8707 // a contained point.
8708 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8709 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8710
8711 minX -= offsets[0].X;
8712 maxX -= offsets[0].X;
8713 minY -= offsets[0].Y;
8714 maxY -= offsets[0].Y;
8715 minZ -= offsets[0].Z;
8716 maxZ -= offsets[0].Z;
8717
8718 LSL_Vector lower;
8719 LSL_Vector upper;
8720
8721 // Adjust to the documented error offsets (see LSL Wiki)
8722 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8723 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8724
8725 if (lower.x > upper.x)
8726 lower.x = upper.x;
8727 if (lower.y > upper.y)
8728 lower.y = upper.y;
8729 if (lower.z > upper.z)
8730 lower.z = upper.z;
8731
7968 result.Add(lower); 8732 result.Add(lower);
7969 result.Add(upper); 8733 result.Add(upper);
7970 return result; 8734 return result;
@@ -7978,7 +8742,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7978 8742
7979 public LSL_Vector llGetGeometricCenter() 8743 public LSL_Vector llGetGeometricCenter()
7980 { 8744 {
7981 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8745 Vector3 tmp = m_host.GetGeometricCenter();
8746 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7982 } 8747 }
7983 8748
7984 public LSL_List llGetPrimitiveParams(LSL_List rules) 8749 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7989,7 +8754,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7989 8754
7990 LSL_List remaining = GetPrimParams(m_host, rules, ref result); 8755 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
7991 8756
7992 while (remaining != null && remaining.Length > 2) 8757 while ((object)remaining != null && remaining.Length > 2)
7993 { 8758 {
7994 int linknumber = remaining.GetLSLIntegerItem(0); 8759 int linknumber = remaining.GetLSLIntegerItem(0);
7995 rules = remaining.GetSublist(1, -1); 8760 rules = remaining.GetSublist(1, -1);
@@ -8006,24 +8771,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8006 { 8771 {
8007 m_host.AddScriptLPS(1); 8772 m_host.AddScriptLPS(1);
8008 8773
8009 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8774 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8775 // keep other options as before
8010 8776
8777 List<SceneObjectPart> parts;
8778 List<ScenePresence> avatars;
8779
8011 LSL_List res = new LSL_List(); 8780 LSL_List res = new LSL_List();
8012 LSL_List remaining = null; 8781 LSL_List remaining = null;
8013 8782
8014 foreach (SceneObjectPart part in parts) 8783 while (rules.Length > 0)
8015 { 8784 {
8016 remaining = GetPrimParams(part, rules, ref res);
8017 }
8018
8019 while (remaining != null && remaining.Length > 2)
8020 {
8021 linknumber = remaining.GetLSLIntegerItem(0);
8022 rules = remaining.GetSublist(1, -1);
8023 parts = GetLinkParts(linknumber); 8785 parts = GetLinkParts(linknumber);
8786 avatars = GetLinkAvatars(linknumber);
8024 8787
8788 remaining = null;
8025 foreach (SceneObjectPart part in parts) 8789 foreach (SceneObjectPart part in parts)
8790 {
8026 remaining = GetPrimParams(part, rules, ref res); 8791 remaining = GetPrimParams(part, rules, ref res);
8792 }
8793 foreach (ScenePresence avatar in avatars)
8794 {
8795 remaining = GetPrimParams(avatar, rules, ref res);
8796 }
8797
8798 if ((object)remaining != null && remaining.Length > 0)
8799 {
8800 linknumber = remaining.GetLSLIntegerItem(0);
8801 rules = remaining.GetSublist(1, -1);
8802 }
8803 else
8804 break;
8027 } 8805 }
8028 8806
8029 return res; 8807 return res;
@@ -8068,13 +8846,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8068 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8846 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8069 part.AbsolutePosition.Y, 8847 part.AbsolutePosition.Y,
8070 part.AbsolutePosition.Z); 8848 part.AbsolutePosition.Z);
8071 // For some reason, the part.AbsolutePosition.* values do not change if the
8072 // linkset is rotated; they always reflect the child prim's world position
8073 // as though the linkset is unrotated. This is incompatible behavior with SL's
8074 // implementation, so will break scripts imported from there (not to mention it
8075 // makes it more difficult to determine a child prim's actual inworld position).
8076 if (part.ParentID != 0)
8077 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8078 res.Add(v); 8849 res.Add(v);
8079 break; 8850 break;
8080 8851
@@ -8246,30 +9017,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8246 if (remain < 1) 9017 if (remain < 1)
8247 return null; 9018 return null;
8248 9019
8249 face=(int)rules.GetLSLIntegerItem(idx++); 9020 face = (int)rules.GetLSLIntegerItem(idx++);
8250 9021
8251 tex = part.Shape.Textures; 9022 tex = part.Shape.Textures;
9023 int shiny;
8252 if (face == ScriptBaseClass.ALL_SIDES) 9024 if (face == ScriptBaseClass.ALL_SIDES)
8253 { 9025 {
8254 for (face = 0; face < GetNumberOfSides(part); face++) 9026 for (face = 0; face < GetNumberOfSides(part); face++)
8255 { 9027 {
8256 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9028 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8257 // Convert Shininess to PRIM_SHINY_* 9029 if (shinyness == Shininess.High)
8258 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9030 {
8259 // PRIM_BUMP_* 9031 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8260 res.Add(new LSL_Integer((int)texface.Bump)); 9032 }
9033 else if (shinyness == Shininess.Medium)
9034 {
9035 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9036 }
9037 else if (shinyness == Shininess.Low)
9038 {
9039 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9040 }
9041 else
9042 {
9043 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9044 }
9045 res.Add(new LSL_Integer(shiny));
9046 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8261 } 9047 }
8262 } 9048 }
8263 else 9049 else
8264 { 9050 {
8265 if (face >= 0 && face < GetNumberOfSides(part)) 9051 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9052 if (shinyness == Shininess.High)
8266 { 9053 {
8267 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9054 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8268 // Convert Shininess to PRIM_SHINY_* 9055 }
8269 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9056 else if (shinyness == Shininess.Medium)
8270 // PRIM_BUMP_* 9057 {
8271 res.Add(new LSL_Integer((int)texface.Bump)); 9058 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9059 }
9060 else if (shinyness == Shininess.Low)
9061 {
9062 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9063 }
9064 else
9065 {
9066 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8272 } 9067 }
9068 res.Add(new LSL_Integer(shiny));
9069 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8273 } 9070 }
8274 break; 9071 break;
8275 9072
@@ -8277,24 +9074,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8277 if (remain < 1) 9074 if (remain < 1)
8278 return null; 9075 return null;
8279 9076
8280 face=(int)rules.GetLSLIntegerItem(idx++); 9077 face = (int)rules.GetLSLIntegerItem(idx++);
8281 9078
8282 tex = part.Shape.Textures; 9079 tex = part.Shape.Textures;
9080 int fullbright;
8283 if (face == ScriptBaseClass.ALL_SIDES) 9081 if (face == ScriptBaseClass.ALL_SIDES)
8284 { 9082 {
8285 for (face = 0; face < GetNumberOfSides(part); face++) 9083 for (face = 0; face < GetNumberOfSides(part); face++)
8286 { 9084 {
8287 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9085 if (tex.GetFace((uint)face).Fullbright == true)
8288 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9086 {
9087 fullbright = ScriptBaseClass.TRUE;
9088 }
9089 else
9090 {
9091 fullbright = ScriptBaseClass.FALSE;
9092 }
9093 res.Add(new LSL_Integer(fullbright));
8289 } 9094 }
8290 } 9095 }
8291 else 9096 else
8292 { 9097 {
8293 if (face >= 0 && face < GetNumberOfSides(part)) 9098 if (tex.GetFace((uint)face).Fullbright == true)
8294 { 9099 {
8295 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9100 fullbright = ScriptBaseClass.TRUE;
8296 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9101 }
9102 else
9103 {
9104 fullbright = ScriptBaseClass.FALSE;
8297 } 9105 }
9106 res.Add(new LSL_Integer(fullbright));
8298 } 9107 }
8299 break; 9108 break;
8300 9109
@@ -8316,27 +9125,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8316 break; 9125 break;
8317 9126
8318 case (int)ScriptBaseClass.PRIM_TEXGEN: 9127 case (int)ScriptBaseClass.PRIM_TEXGEN:
9128 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8319 if (remain < 1) 9129 if (remain < 1)
8320 return null; 9130 return null;
8321 9131
8322 face=(int)rules.GetLSLIntegerItem(idx++); 9132 face = (int)rules.GetLSLIntegerItem(idx++);
8323 9133
8324 tex = part.Shape.Textures; 9134 tex = part.Shape.Textures;
8325 if (face == ScriptBaseClass.ALL_SIDES) 9135 if (face == ScriptBaseClass.ALL_SIDES)
8326 { 9136 {
8327 for (face = 0; face < GetNumberOfSides(part); face++) 9137 for (face = 0; face < GetNumberOfSides(part); face++)
8328 { 9138 {
8329 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9139 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8330 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9140 {
8331 res.Add(new LSL_Integer((uint)texgen >> 1)); 9141 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9142 }
9143 else
9144 {
9145 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9146 }
8332 } 9147 }
8333 } 9148 }
8334 else 9149 else
8335 { 9150 {
8336 if (face >= 0 && face < GetNumberOfSides(part)) 9151 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9152 {
9153 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9154 }
9155 else
8337 { 9156 {
8338 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9157 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8339 res.Add(new LSL_Integer((uint)texgen >> 1));
8340 } 9158 }
8341 } 9159 }
8342 break; 9160 break;
@@ -8360,24 +9178,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8360 if (remain < 1) 9178 if (remain < 1)
8361 return null; 9179 return null;
8362 9180
8363 face=(int)rules.GetLSLIntegerItem(idx++); 9181 face = (int)rules.GetLSLIntegerItem(idx++);
8364 9182
8365 tex = part.Shape.Textures; 9183 tex = part.Shape.Textures;
9184 float primglow;
8366 if (face == ScriptBaseClass.ALL_SIDES) 9185 if (face == ScriptBaseClass.ALL_SIDES)
8367 { 9186 {
8368 for (face = 0; face < GetNumberOfSides(part); face++) 9187 for (face = 0; face < GetNumberOfSides(part); face++)
8369 { 9188 {
8370 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9189 primglow = tex.GetFace((uint)face).Glow;
8371 res.Add(new LSL_Float(texface.Glow)); 9190 res.Add(new LSL_Float(primglow));
8372 } 9191 }
8373 } 9192 }
8374 else 9193 else
8375 { 9194 {
8376 if (face >= 0 && face < GetNumberOfSides(part)) 9195 primglow = tex.GetFace((uint)face).Glow;
8377 { 9196 res.Add(new LSL_Float(primglow));
8378 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8379 res.Add(new LSL_Float(texface.Glow));
8380 }
8381 } 9197 }
8382 break; 9198 break;
8383 9199
@@ -8389,15 +9205,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8389 textColor.B)); 9205 textColor.B));
8390 res.Add(new LSL_Float(textColor.A)); 9206 res.Add(new LSL_Float(textColor.A));
8391 break; 9207 break;
9208
8392 case (int)ScriptBaseClass.PRIM_NAME: 9209 case (int)ScriptBaseClass.PRIM_NAME:
8393 res.Add(new LSL_String(part.Name)); 9210 res.Add(new LSL_String(part.Name));
8394 break; 9211 break;
9212
8395 case (int)ScriptBaseClass.PRIM_DESC: 9213 case (int)ScriptBaseClass.PRIM_DESC:
8396 res.Add(new LSL_String(part.Description)); 9214 res.Add(new LSL_String(part.Description));
8397 break; 9215 break;
9216
8398 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9217 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8399 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9218 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8400 break; 9219 break;
9220
8401 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9221 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8402 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9222 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8403 break; 9223 break;
@@ -9008,8 +9828,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9008 // The function returns an ordered list 9828 // The function returns an ordered list
9009 // representing the tokens found in the supplied 9829 // representing the tokens found in the supplied
9010 // sources string. If two successive tokenizers 9830 // sources string. If two successive tokenizers
9011 // are encountered, then a NULL entry is added 9831 // are encountered, then a null-string entry is
9012 // to the list. 9832 // added to the list.
9013 // 9833 //
9014 // It is a precondition that the source and 9834 // It is a precondition that the source and
9015 // toekizer lisst are non-null. If they are null, 9835 // toekizer lisst are non-null. If they are null,
@@ -9017,7 +9837,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9017 // while their lengths are being determined. 9837 // while their lengths are being determined.
9018 // 9838 //
9019 // A small amount of working memoryis required 9839 // A small amount of working memoryis required
9020 // of approximately 8*#tokenizers. 9840 // of approximately 8*#tokenizers + 8*srcstrlen.
9021 // 9841 //
9022 // There are many ways in which this function 9842 // There are many ways in which this function
9023 // can be implemented, this implementation is 9843 // can be implemented, this implementation is
@@ -9033,155 +9853,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9033 // and eliminates redundant tokenizers as soon 9853 // and eliminates redundant tokenizers as soon
9034 // as is possible. 9854 // as is possible.
9035 // 9855 //
9036 // The implementation tries to avoid any copying 9856 // The implementation tries to minimize temporary
9037 // of arrays or other objects. 9857 // garbage generation.
9038 // </remarks> 9858 // </remarks>
9039 9859
9040 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9860 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9041 { 9861 {
9042 int beginning = 0; 9862 return ParseString2List(src, separators, spacers, true);
9043 int srclen = src.Length; 9863 }
9044 int seplen = separators.Length;
9045 object[] separray = separators.Data;
9046 int spclen = spacers.Length;
9047 object[] spcarray = spacers.Data;
9048 int mlen = seplen+spclen;
9049
9050 int[] offset = new int[mlen+1];
9051 bool[] active = new bool[mlen];
9052
9053 int best;
9054 int j;
9055
9056 // Initial capacity reduces resize cost
9057 9864
9058 LSL_List tokens = new LSL_List(); 9865 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9866 {
9867 int srclen = src.Length;
9868 int seplen = separators.Length;
9869 object[] separray = separators.Data;
9870 int spclen = spacers.Length;
9871 object[] spcarray = spacers.Data;
9872 int dellen = 0;
9873 string[] delarray = new string[seplen+spclen];
9059 9874
9060 // All entries are initially valid 9875 int outlen = 0;
9876 string[] outarray = new string[srclen*2+1];
9061 9877
9062 for (int i = 0; i < mlen; i++) 9878 int i, j;
9063 active[i] = true; 9879 string d;
9064 9880
9065 offset[mlen] = srclen; 9881 m_host.AddScriptLPS(1);
9066 9882
9067 while (beginning < srclen) 9883 /*
9884 * Convert separator and spacer lists to C# strings.
9885 * Also filter out null strings so we don't hang.
9886 */
9887 for (i = 0; i < seplen; i ++)
9068 { 9888 {
9889 d = separray[i].ToString();
9890 if (d.Length > 0)
9891 {
9892 delarray[dellen++] = d;
9893 }
9894 }
9895 seplen = dellen;
9069 9896
9070 best = mlen; // as bad as it gets 9897 for (i = 0; i < spclen; i ++)
9898 {
9899 d = spcarray[i].ToString();
9900 if (d.Length > 0)
9901 {
9902 delarray[dellen++] = d;
9903 }
9904 }
9071 9905
9072 // Scan for separators 9906 /*
9907 * Scan through source string from beginning to end.
9908 */
9909 for (i = 0;;)
9910 {
9073 9911
9074 for (j = 0; j < seplen; j++) 9912 /*
9913 * Find earliest delimeter in src starting at i (if any).
9914 */
9915 int earliestDel = -1;
9916 int earliestSrc = srclen;
9917 string earliestStr = null;
9918 for (j = 0; j < dellen; j ++)
9075 { 9919 {
9076 if (separray[j].ToString() == String.Empty) 9920 d = delarray[j];
9077 active[j] = false; 9921 if (d != null)
9078
9079 if (active[j])
9080 { 9922 {
9081 // scan all of the markers 9923 int index = src.IndexOf(d, i);
9082 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9924 if (index < 0)
9083 { 9925 {
9084 // not present at all 9926 delarray[j] = null; // delim nowhere in src, don't check it anymore
9085 active[j] = false;
9086 } 9927 }
9087 else 9928 else if (index < earliestSrc)
9088 { 9929 {
9089 // present and correct 9930 earliestSrc = index; // where delimeter starts in source string
9090 if (offset[j] < offset[best]) 9931 earliestDel = j; // where delimeter is in delarray[]
9091 { 9932 earliestStr = d; // the delimeter string from delarray[]
9092 // closest so far 9933 if (index == i) break; // can't do any better than found at beg of string
9093 best = j;
9094 if (offset[best] == beginning)
9095 break;
9096 }
9097 } 9934 }
9098 } 9935 }
9099 } 9936 }
9100 9937
9101 // Scan for spacers 9938 /*
9102 9939 * Output source string starting at i through start of earliest delimeter.
9103 if (offset[best] != beginning) 9940 */
9941 if (keepNulls || (earliestSrc > i))
9104 { 9942 {
9105 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9943 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9106 {
9107 if (spcarray[j-seplen].ToString() == String.Empty)
9108 active[j] = false;
9109
9110 if (active[j])
9111 {
9112 // scan all of the markers
9113 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9114 {
9115 // not present at all
9116 active[j] = false;
9117 }
9118 else
9119 {
9120 // present and correct
9121 if (offset[j] < offset[best])
9122 {
9123 // closest so far
9124 best = j;
9125 }
9126 }
9127 }
9128 }
9129 } 9944 }
9130 9945
9131 // This is the normal exit from the scanning loop 9946 /*
9947 * If no delimeter found at or after i, we're done scanning.
9948 */
9949 if (earliestDel < 0) break;
9132 9950
9133 if (best == mlen) 9951 /*
9952 * If delimeter was a spacer, output the spacer.
9953 */
9954 if (earliestDel >= seplen)
9134 { 9955 {
9135 // no markers were found on this pass 9956 outarray[outlen++] = earliestStr;
9136 // so we're pretty much done
9137 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9138 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9139 break;
9140 } 9957 }
9141 9958
9142 // Otherwise we just add the newly delimited token 9959 /*
9143 // and recalculate where the search should continue. 9960 * Look at rest of src string following delimeter.
9144 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9961 */
9145 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9962 i = earliestSrc + earliestStr.Length;
9146
9147 if (best < seplen)
9148 {
9149 beginning = offset[best] + (separray[best].ToString()).Length;
9150 }
9151 else
9152 {
9153 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9154 string str = spcarray[best - seplen].ToString();
9155 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9156 tokens.Add(new LSL_String(str));
9157 }
9158 } 9963 }
9159 9964
9160 // This an awkward an not very intuitive boundary case. If the 9965 /*
9161 // last substring is a tokenizer, then there is an implied trailing 9966 * Make up an exact-sized output array suitable for an LSL_List object.
9162 // null list entry. Hopefully the single comparison will not be too 9967 */
9163 // arduous. Alternatively the 'break' could be replced with a return 9968 object[] outlist = new object[outlen];
9164 // but that's shabby programming. 9969 for (i = 0; i < outlen; i ++)
9165
9166 if ((beginning == srclen) && (keepNulls))
9167 { 9970 {
9168 if (srclen != 0) 9971 outlist[i] = new LSL_String(outarray[i]);
9169 tokens.Add(new LSL_String(""));
9170 } 9972 }
9171 9973 return new LSL_List(outlist);
9172 return tokens;
9173 }
9174
9175 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9176 {
9177 m_host.AddScriptLPS(1);
9178 return this.ParseString(src, separators, spacers, false);
9179 }
9180
9181 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9182 {
9183 m_host.AddScriptLPS(1);
9184 return this.ParseString(src, separators, spacers, true);
9185 } 9974 }
9186 9975
9187 public LSL_Integer llGetObjectPermMask(int mask) 9976 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9276,6 +10065,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9276 case 4: 10065 case 4:
9277 return (int)item.NextPermissions; 10066 return (int)item.NextPermissions;
9278 } 10067 }
10068 m_host.TaskInventory.LockItemsForRead(false);
9279 10069
9280 return -1; 10070 return -1;
9281 } 10071 }
@@ -9478,31 +10268,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9478 UUID key = new UUID(); 10268 UUID key = new UUID();
9479 if (UUID.TryParse(id, out key)) 10269 if (UUID.TryParse(id, out key))
9480 { 10270 {
9481 try 10271 // return total object mass
9482 { 10272 SceneObjectPart part = World.GetSceneObjectPart(key);
9483 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10273 if (part != null)
9484 if (obj != null) 10274 return part.ParentGroup.GetMass();
9485 return (double)obj.GetMass(); 10275
9486 // the object is null so the key is for an avatar 10276 // the object is null so the key is for an avatar
9487 ScenePresence avatar = World.GetScenePresence(key); 10277 ScenePresence avatar = World.GetScenePresence(key);
9488 if (avatar != null) 10278 if (avatar != null)
9489 if (avatar.IsChildAgent)
9490 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9491 // child agents have a mass of 1.0
9492 return 1;
9493 else
9494 return (double)avatar.GetMass();
9495 }
9496 catch (KeyNotFoundException)
9497 { 10279 {
9498 return 0; // The Object/Agent not in the region so just return zero 10280 if (avatar.IsChildAgent)
10281 {
10282 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10283 // child agents have a mass of 1.0
10284 return 1;
10285 }
10286 else
10287 {
10288 return (double)avatar.GetMass();
10289 }
9499 } 10290 }
9500 } 10291 }
9501 return 0; 10292 return 0;
9502 } 10293 }
9503 10294
9504 /// <summary> 10295 /// <summary>
9505 /// illListReplaceList removes the sub-list defined by the inclusive indices 10296 /// llListReplaceList removes the sub-list defined by the inclusive indices
9506 /// start and end and inserts the src list in its place. The inclusive 10297 /// start and end and inserts the src list in its place. The inclusive
9507 /// nature of the indices means that at least one element must be deleted 10298 /// nature of the indices means that at least one element must be deleted
9508 /// if the indices are within the bounds of the existing list. I.e. 2,2 10299 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9559,16 +10350,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9559 // based upon end. Note that if end exceeds the upper 10350 // based upon end. Note that if end exceeds the upper
9560 // bound in this case, the entire destination list 10351 // bound in this case, the entire destination list
9561 // is removed. 10352 // is removed.
9562 else 10353 else if (start == 0)
9563 { 10354 {
9564 if (end + 1 < dest.Length) 10355 if (end + 1 < dest.Length)
9565 {
9566 return src + dest.GetSublist(end + 1, -1); 10356 return src + dest.GetSublist(end + 1, -1);
9567 }
9568 else 10357 else
9569 {
9570 return src; 10358 return src;
9571 } 10359 }
10360 else // Start < 0
10361 {
10362 if (end + 1 < dest.Length)
10363 return dest.GetSublist(end + 1, -1);
10364 else
10365 return new LSL_List();
9572 } 10366 }
9573 } 10367 }
9574 // Finally, if start > end, we strip away a prefix and 10368 // Finally, if start > end, we strip away a prefix and
@@ -9619,17 +10413,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9619 int width = 0; 10413 int width = 0;
9620 int height = 0; 10414 int height = 0;
9621 10415
9622 ParcelMediaCommandEnum? commandToSend = null; 10416 uint commandToSend = 0;
9623 float time = 0.0f; // default is from start 10417 float time = 0.0f; // default is from start
9624 10418
9625 ScenePresence presence = null; 10419 ScenePresence presence = null;
9626 10420
9627 for (int i = 0; i < commandList.Data.Length; i++) 10421 for (int i = 0; i < commandList.Data.Length; i++)
9628 { 10422 {
9629 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10423 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9630 switch (command) 10424 switch (command)
9631 { 10425 {
9632 case ParcelMediaCommandEnum.Agent: 10426 case (uint)ParcelMediaCommandEnum.Agent:
9633 // we send only to one agent 10427 // we send only to one agent
9634 if ((i + 1) < commandList.Length) 10428 if ((i + 1) < commandList.Length)
9635 { 10429 {
@@ -9646,25 +10440,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9646 } 10440 }
9647 break; 10441 break;
9648 10442
9649 case ParcelMediaCommandEnum.Loop: 10443 case (uint)ParcelMediaCommandEnum.Loop:
9650 loop = 1; 10444 loop = 1;
9651 commandToSend = command; 10445 commandToSend = command;
9652 update = true; //need to send the media update packet to set looping 10446 update = true; //need to send the media update packet to set looping
9653 break; 10447 break;
9654 10448
9655 case ParcelMediaCommandEnum.Play: 10449 case (uint)ParcelMediaCommandEnum.Play:
9656 loop = 0; 10450 loop = 0;
9657 commandToSend = command; 10451 commandToSend = command;
9658 update = true; //need to send the media update packet to make sure it doesn't loop 10452 update = true; //need to send the media update packet to make sure it doesn't loop
9659 break; 10453 break;
9660 10454
9661 case ParcelMediaCommandEnum.Pause: 10455 case (uint)ParcelMediaCommandEnum.Pause:
9662 case ParcelMediaCommandEnum.Stop: 10456 case (uint)ParcelMediaCommandEnum.Stop:
9663 case ParcelMediaCommandEnum.Unload: 10457 case (uint)ParcelMediaCommandEnum.Unload:
9664 commandToSend = command; 10458 commandToSend = command;
9665 break; 10459 break;
9666 10460
9667 case ParcelMediaCommandEnum.Url: 10461 case (uint)ParcelMediaCommandEnum.Url:
9668 if ((i + 1) < commandList.Length) 10462 if ((i + 1) < commandList.Length)
9669 { 10463 {
9670 if (commandList.Data[i + 1] is LSL_String) 10464 if (commandList.Data[i + 1] is LSL_String)
@@ -9677,7 +10471,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9677 } 10471 }
9678 break; 10472 break;
9679 10473
9680 case ParcelMediaCommandEnum.Texture: 10474 case (uint)ParcelMediaCommandEnum.Texture:
9681 if ((i + 1) < commandList.Length) 10475 if ((i + 1) < commandList.Length)
9682 { 10476 {
9683 if (commandList.Data[i + 1] is LSL_String) 10477 if (commandList.Data[i + 1] is LSL_String)
@@ -9690,7 +10484,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9690 } 10484 }
9691 break; 10485 break;
9692 10486
9693 case ParcelMediaCommandEnum.Time: 10487 case (uint)ParcelMediaCommandEnum.Time:
9694 if ((i + 1) < commandList.Length) 10488 if ((i + 1) < commandList.Length)
9695 { 10489 {
9696 if (commandList.Data[i + 1] is LSL_Float) 10490 if (commandList.Data[i + 1] is LSL_Float)
@@ -9702,7 +10496,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9702 } 10496 }
9703 break; 10497 break;
9704 10498
9705 case ParcelMediaCommandEnum.AutoAlign: 10499 case (uint)ParcelMediaCommandEnum.AutoAlign:
9706 if ((i + 1) < commandList.Length) 10500 if ((i + 1) < commandList.Length)
9707 { 10501 {
9708 if (commandList.Data[i + 1] is LSL_Integer) 10502 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9716,7 +10510,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9716 } 10510 }
9717 break; 10511 break;
9718 10512
9719 case ParcelMediaCommandEnum.Type: 10513 case (uint)ParcelMediaCommandEnum.Type:
9720 if ((i + 1) < commandList.Length) 10514 if ((i + 1) < commandList.Length)
9721 { 10515 {
9722 if (commandList.Data[i + 1] is LSL_String) 10516 if (commandList.Data[i + 1] is LSL_String)
@@ -9729,7 +10523,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9729 } 10523 }
9730 break; 10524 break;
9731 10525
9732 case ParcelMediaCommandEnum.Desc: 10526 case (uint)ParcelMediaCommandEnum.Desc:
9733 if ((i + 1) < commandList.Length) 10527 if ((i + 1) < commandList.Length)
9734 { 10528 {
9735 if (commandList.Data[i + 1] is LSL_String) 10529 if (commandList.Data[i + 1] is LSL_String)
@@ -9742,7 +10536,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9742 } 10536 }
9743 break; 10537 break;
9744 10538
9745 case ParcelMediaCommandEnum.Size: 10539 case (uint)ParcelMediaCommandEnum.Size:
9746 if ((i + 2) < commandList.Length) 10540 if ((i + 2) < commandList.Length)
9747 { 10541 {
9748 if (commandList.Data[i + 1] is LSL_Integer) 10542 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9812,7 +10606,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9812 } 10606 }
9813 } 10607 }
9814 10608
9815 if (commandToSend != null) 10609 if (commandToSend != 0)
9816 { 10610 {
9817 // the commandList contained a start/stop/... command, too 10611 // the commandList contained a start/stop/... command, too
9818 if (presence == null) 10612 if (presence == null)
@@ -9849,7 +10643,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9849 10643
9850 if (aList.Data[i] != null) 10644 if (aList.Data[i] != null)
9851 { 10645 {
9852 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10646 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9853 { 10647 {
9854 case ParcelMediaCommandEnum.Url: 10648 case ParcelMediaCommandEnum.Url:
9855 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10649 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9906,15 +10700,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9906 10700
9907 if (quick_pay_buttons.Data.Length < 4) 10701 if (quick_pay_buttons.Data.Length < 4)
9908 { 10702 {
9909 LSLError("List must have at least 4 elements"); 10703 int x;
9910 return; 10704 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10705 {
10706 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10707 }
9911 } 10708 }
9912 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10709 int[] nPrice = new int[5];
9913 10710 nPrice[0] = price;
9914 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10711 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9915 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10712 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9916 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10713 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9917 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10714 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10715 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9918 m_host.ParentGroup.HasGroupChanged = true; 10716 m_host.ParentGroup.HasGroupChanged = true;
9919 } 10717 }
9920 10718
@@ -9931,7 +10729,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9931 return new LSL_Vector(); 10729 return new LSL_Vector();
9932 } 10730 }
9933 10731
9934 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10732// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10733 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9935 if (presence != null) 10734 if (presence != null)
9936 { 10735 {
9937 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10736 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9953,7 +10752,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9953 return new LSL_Rotation(); 10752 return new LSL_Rotation();
9954 } 10753 }
9955 10754
9956 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10755// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10756 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9957 if (presence != null) 10757 if (presence != null)
9958 { 10758 {
9959 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10759 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -10013,14 +10813,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10013 { 10813 {
10014 m_host.AddScriptLPS(1); 10814 m_host.AddScriptLPS(1);
10015 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10815 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10016 if (detectedParams == null) return; // only works on the first detected avatar 10816 if (detectedParams == null)
10017 10817 {
10818 if (m_host.ParentGroup.IsAttachment == true)
10819 {
10820 detectedParams = new DetectParams();
10821 detectedParams.Key = m_host.OwnerID;
10822 }
10823 else
10824 {
10825 return;
10826 }
10827 }
10828
10018 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10829 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10019 if (avatar != null) 10830 if (avatar != null)
10020 { 10831 {
10021 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10832 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10022 simname, pos, lookAt); 10833 simname, pos, lookAt);
10023 } 10834 }
10835
10024 ScriptSleep(1000); 10836 ScriptSleep(1000);
10025 } 10837 }
10026 10838
@@ -10144,12 +10956,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10144 10956
10145 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10957 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10146 object[] data = rules.Data; 10958 object[] data = rules.Data;
10147 for (int i = 0; i < data.Length; ++i) { 10959 for (int i = 0; i < data.Length; ++i)
10960 {
10148 int type = Convert.ToInt32(data[i++].ToString()); 10961 int type = Convert.ToInt32(data[i++].ToString());
10149 if (i >= data.Length) break; // odd number of entries => ignore the last 10962 if (i >= data.Length) break; // odd number of entries => ignore the last
10150 10963
10151 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10964 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10152 switch (type) { 10965 switch (type)
10966 {
10153 case ScriptBaseClass.CAMERA_FOCUS: 10967 case ScriptBaseClass.CAMERA_FOCUS:
10154 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10968 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10155 case ScriptBaseClass.CAMERA_POSITION: 10969 case ScriptBaseClass.CAMERA_POSITION:
@@ -10254,19 +11068,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10254 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11068 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10255 { 11069 {
10256 m_host.AddScriptLPS(1); 11070 m_host.AddScriptLPS(1);
10257 string ret = String.Empty; 11071
10258 string src1 = llBase64ToString(str1); 11072 if (str1 == String.Empty)
10259 string src2 = llBase64ToString(str2); 11073 return String.Empty;
10260 int c = 0; 11074 if (str2 == String.Empty)
10261 for (int i = 0; i < src1.Length; i++) 11075 return str1;
11076
11077 int len = str2.Length;
11078 if ((len % 4) != 0) // LL is EVIL!!!!
10262 { 11079 {
10263 ret += (char) (src1[i] ^ src2[c]); 11080 while (str2.EndsWith("="))
11081 str2 = str2.Substring(0, str2.Length - 1);
11082
11083 len = str2.Length;
11084 int mod = len % 4;
11085
11086 if (mod == 1)
11087 str2 = str2.Substring(0, str2.Length - 1);
11088 else if (mod == 2)
11089 str2 += "==";
11090 else if (mod == 3)
11091 str2 += "=";
11092 }
10264 11093
10265 c++; 11094 byte[] data1;
10266 if (c >= src2.Length) 11095 byte[] data2;
10267 c = 0; 11096 try
11097 {
11098 data1 = Convert.FromBase64String(str1);
11099 data2 = Convert.FromBase64String(str2);
10268 } 11100 }
10269 return llStringToBase64(ret); 11101 catch (Exception)
11102 {
11103 return new LSL_String(String.Empty);
11104 }
11105
11106 byte[] d2 = new Byte[data1.Length];
11107 int pos = 0;
11108
11109 if (data1.Length <= data2.Length)
11110 {
11111 Array.Copy(data2, 0, d2, 0, data1.Length);
11112 }
11113 else
11114 {
11115 while (pos < data1.Length)
11116 {
11117 len = data1.Length - pos;
11118 if (len > data2.Length)
11119 len = data2.Length;
11120
11121 Array.Copy(data2, 0, d2, pos, len);
11122 pos += len;
11123 }
11124 }
11125
11126 for (pos = 0 ; pos < data1.Length ; pos++ )
11127 data1[pos] ^= d2[pos];
11128
11129 return Convert.ToBase64String(data1);
10270 } 11130 }
10271 11131
10272 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11132 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10319,16 +11179,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10319 if (userAgent != null) 11179 if (userAgent != null)
10320 httpHeaders["User-Agent"] = userAgent; 11180 httpHeaders["User-Agent"] = userAgent;
10321 11181
11182 // See if the URL contains any header hacks
11183 string[] urlParts = url.Split(new char[] {'\n'});
11184 if (urlParts.Length > 1)
11185 {
11186 // Iterate the passed headers and parse them
11187 for (int i = 1 ; i < urlParts.Length ; i++ )
11188 {
11189 // The rest of those would be added to the body in SL.
11190 // Let's not do that.
11191 if (urlParts[i] == String.Empty)
11192 break;
11193
11194 // See if this could be a valid header
11195 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11196 if (headerParts.Length != 2)
11197 continue;
11198
11199 string headerName = headerParts[0].Trim();
11200 string headerValue = headerParts[1].Trim();
11201
11202 // Filter out headers that could be used to abuse
11203 // another system or cloak the request
11204 if (headerName.ToLower() == "x-secondlife-shard" ||
11205 headerName.ToLower() == "x-secondlife-object-name" ||
11206 headerName.ToLower() == "x-secondlife-object-key" ||
11207 headerName.ToLower() == "x-secondlife-region" ||
11208 headerName.ToLower() == "x-secondlife-local-position" ||
11209 headerName.ToLower() == "x-secondlife-local-velocity" ||
11210 headerName.ToLower() == "x-secondlife-local-rotation" ||
11211 headerName.ToLower() == "x-secondlife-owner-name" ||
11212 headerName.ToLower() == "x-secondlife-owner-key" ||
11213 headerName.ToLower() == "connection" ||
11214 headerName.ToLower() == "content-length" ||
11215 headerName.ToLower() == "from" ||
11216 headerName.ToLower() == "host" ||
11217 headerName.ToLower() == "proxy-authorization" ||
11218 headerName.ToLower() == "referer" ||
11219 headerName.ToLower() == "trailer" ||
11220 headerName.ToLower() == "transfer-encoding" ||
11221 headerName.ToLower() == "via" ||
11222 headerName.ToLower() == "authorization")
11223 continue;
11224
11225 httpHeaders[headerName] = headerValue;
11226 }
11227
11228 // Finally, strip any protocol specifier from the URL
11229 url = urlParts[0].Trim();
11230 int idx = url.IndexOf(" HTTP/");
11231 if (idx != -1)
11232 url = url.Substring(0, idx);
11233 }
11234
10322 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11235 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10323 Regex r = new Regex(authregex); 11236 Regex r = new Regex(authregex);
10324 int[] gnums = r.GetGroupNumbers(); 11237 int[] gnums = r.GetGroupNumbers();
10325 Match m = r.Match(url); 11238 Match m = r.Match(url);
10326 if (m.Success) { 11239 if (m.Success)
10327 for (int i = 1; i < gnums.Length; i++) { 11240 {
11241 for (int i = 1; i < gnums.Length; i++)
11242 {
10328 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11243 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10329 //CaptureCollection cc = g.Captures; 11244 //CaptureCollection cc = g.Captures;
10330 } 11245 }
10331 if (m.Groups.Count == 5) { 11246 if (m.Groups.Count == 5)
11247 {
10332 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11248 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10333 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11249 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10334 } 11250 }
@@ -10531,6 +11447,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10531 11447
10532 LSL_List ret = new LSL_List(); 11448 LSL_List ret = new LSL_List();
10533 UUID key = new UUID(); 11449 UUID key = new UUID();
11450
11451
10534 if (UUID.TryParse(id, out key)) 11452 if (UUID.TryParse(id, out key))
10535 { 11453 {
10536 ScenePresence av = World.GetScenePresence(key); 11454 ScenePresence av = World.GetScenePresence(key);
@@ -10548,13 +11466,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10548 ret.Add(new LSL_String("")); 11466 ret.Add(new LSL_String(""));
10549 break; 11467 break;
10550 case ScriptBaseClass.OBJECT_POS: 11468 case ScriptBaseClass.OBJECT_POS:
10551 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11469 Vector3 avpos;
11470
11471 if (av.ParentID != 0 && av.ParentPart != null)
11472 {
11473 avpos = av.OffsetPosition;
11474
11475 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11476 avpos -= sitOffset;
11477
11478 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11479 }
11480 else
11481 avpos = av.AbsolutePosition;
11482
11483 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10552 break; 11484 break;
10553 case ScriptBaseClass.OBJECT_ROT: 11485 case ScriptBaseClass.OBJECT_ROT:
10554 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11486 Quaternion avrot = av.Rotation;
11487 if (av.ParentID != 0 && av.ParentPart != null)
11488 {
11489 avrot = av.ParentPart.GetWorldRotation() * avrot;
11490 }
11491 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10555 break; 11492 break;
10556 case ScriptBaseClass.OBJECT_VELOCITY: 11493 case ScriptBaseClass.OBJECT_VELOCITY:
10557 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11494 Vector3 avvel = av.Velocity;
11495 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10558 break; 11496 break;
10559 case ScriptBaseClass.OBJECT_OWNER: 11497 case ScriptBaseClass.OBJECT_OWNER:
10560 ret.Add(new LSL_String(id)); 11498 ret.Add(new LSL_String(id));
@@ -10639,11 +11577,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10639 case ScriptBaseClass.OBJECT_NAME: 11577 case ScriptBaseClass.OBJECT_NAME:
10640 ret.Add(new LSL_String(obj.Name)); 11578 ret.Add(new LSL_String(obj.Name));
10641 break; 11579 break;
10642 case ScriptBaseClass.OBJECT_DESC: 11580 case ScriptBaseClass.OBJECT_DESC:
10643 ret.Add(new LSL_String(obj.Description)); 11581 ret.Add(new LSL_String(obj.Description));
10644 break; 11582 break;
10645 case ScriptBaseClass.OBJECT_POS: 11583 case ScriptBaseClass.OBJECT_POS:
10646 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11584 Vector3 opos = obj.AbsolutePosition;
11585 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10647 break; 11586 break;
10648 case ScriptBaseClass.OBJECT_ROT: 11587 case ScriptBaseClass.OBJECT_ROT:
10649 { 11588 {
@@ -10693,9 +11632,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10693 // The value returned in SL for normal prims is prim count 11632 // The value returned in SL for normal prims is prim count
10694 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11633 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10695 break; 11634 break;
10696 // The following 3 costs I have intentionaly coded to return zero. They are part of 11635
10697 // "Land Impact" calculations. These calculations are probably not applicable 11636 // costs below may need to be diferent for root parts, need to check
10698 // to OpenSim and are not yet complete in SL
10699 case ScriptBaseClass.OBJECT_SERVER_COST: 11637 case ScriptBaseClass.OBJECT_SERVER_COST:
10700 // The linden calculation is here 11638 // The linden calculation is here
10701 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11639 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10703,16 +11641,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10703 ret.Add(new LSL_Float(0)); 11641 ret.Add(new LSL_Float(0));
10704 break; 11642 break;
10705 case ScriptBaseClass.OBJECT_STREAMING_COST: 11643 case ScriptBaseClass.OBJECT_STREAMING_COST:
10706 // The linden calculation is here 11644 // The value returned in SL for normal prims is prim count * 0.06
10707 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11645 ret.Add(new LSL_Float(obj.StreamingCost));
10708 // The value returned in SL for normal prims looks like the prim count * 0.06
10709 ret.Add(new LSL_Float(0));
10710 break; 11646 break;
10711 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11647 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10712 // The linden calculation is here 11648 // The value returned in SL for normal prims is prim count
10713 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11649 ret.Add(new LSL_Float(obj.PhysicsCost));
10714 // The value returned in SL for normal prims looks like the prim count
10715 ret.Add(new LSL_Float(0));
10716 break; 11650 break;
10717 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11651 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
10718 ret.Add(new LSL_Float(0)); 11652 ret.Add(new LSL_Float(0));
@@ -10969,15 +11903,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10969 return result; 11903 return result;
10970 } 11904 }
10971 11905
10972 public void print(string str) 11906 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10973 { 11907 {
10974 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11908 List<SceneObjectPart> parts = GetLinkParts(link);
10975 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11909 if (parts.Count < 1)
10976 if (ossl != null) 11910 return 0;
10977 { 11911
10978 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11912 return GetNumberOfSides(parts[0]);
10979 m_log.Info("LSL print():" + str);
10980 }
10981 } 11913 }
10982 11914
10983 private string Name2Username(string name) 11915 private string Name2Username(string name)
@@ -11022,7 +11954,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11022 11954
11023 return rq.ToString(); 11955 return rq.ToString();
11024 } 11956 }
11025 11957/*
11958 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11959 {
11960 m_SayShoutCount = 0;
11961 }
11962*/
11026 private struct Tri 11963 private struct Tri
11027 { 11964 {
11028 public Vector3 p1; 11965 public Vector3 p1;
@@ -11162,9 +12099,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11162 12099
11163 ContactResult result = new ContactResult (); 12100 ContactResult result = new ContactResult ();
11164 result.ConsumerID = group.LocalId; 12101 result.ConsumerID = group.LocalId;
11165 result.Depth = intersection.distance; 12102// result.Depth = intersection.distance;
11166 result.Normal = intersection.normal; 12103 result.Normal = intersection.normal;
11167 result.Pos = intersection.ipoint; 12104 result.Pos = intersection.ipoint;
12105 result.Depth = Vector3.Mag(rayStart - result.Pos);
11168 12106
11169 contacts.Add(result); 12107 contacts.Add(result);
11170 }); 12108 });
@@ -11297,6 +12235,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11297 12235
11298 return contacts[0]; 12236 return contacts[0];
11299 } 12237 }
12238/*
12239 // not done:
12240 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12241 {
12242 ContactResult[] contacts = null;
12243 World.ForEachSOG(delegate(SceneObjectGroup group)
12244 {
12245 if (m_host.ParentGroup == group)
12246 return;
12247
12248 if (group.IsAttachment)
12249 return;
12250
12251 if(group.RootPart.PhysActor != null)
12252 return;
12253
12254 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12255 });
12256 return contacts;
12257 }
12258*/
11300 12259
11301 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12260 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11302 { 12261 {
@@ -11338,32 +12297,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11338 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12297 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11339 12298
11340 12299
11341 if (checkTerrain) 12300 if (World.SuportsRayCastFiltered())
11342 { 12301 {
11343 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12302 if (dist == 0)
11344 if (groundContact != null) 12303 return list;
11345 results.Add((ContactResult)groundContact);
11346 }
11347 12304
11348 if (checkAgents) 12305 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11349 { 12306 if (checkTerrain)
11350 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12307 rayfilter |= RayFilterFlags.land;
11351 foreach (ContactResult r in agentHits) 12308// if (checkAgents)
11352 results.Add(r); 12309// rayfilter |= RayFilterFlags.agent;
11353 } 12310 if (checkPhysical)
12311 rayfilter |= RayFilterFlags.physical;
12312 if (checkNonPhysical)
12313 rayfilter |= RayFilterFlags.nonphysical;
12314 if (detectPhantom)
12315 rayfilter |= RayFilterFlags.LSLPhanton;
12316
12317 Vector3 direction = dir * ( 1/dist);
12318
12319 if(rayfilter == 0)
12320 {
12321 list.Add(new LSL_Integer(0));
12322 return list;
12323 }
12324
12325 // get some more contacts to sort ???
12326 int physcount = 4 * count;
12327 if (physcount > 20)
12328 physcount = 20;
12329
12330 object physresults;
12331 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12332
12333 if (physresults == null)
12334 {
12335 list.Add(new LSL_Integer(-3)); // timeout error
12336 return list;
12337 }
12338
12339 results = (List<ContactResult>)physresults;
12340
12341 // for now physics doesn't detect sitted avatars so do it outside physics
12342 if (checkAgents)
12343 {
12344 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12345 foreach (ContactResult r in agentHits)
12346 results.Add(r);
12347 }
11354 12348
11355 if (checkPhysical || checkNonPhysical || detectPhantom) 12349 // TODO: Replace this with a better solution. ObjectIntersection can only
12350 // detect nonphysical phantoms. They are detected by virtue of being
12351 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12352 // physicsl phantoms as done by the physics scene
12353 // We don't want anything else but phantoms here.
12354 if (detectPhantom)
12355 {
12356 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12357 foreach (ContactResult r in objectHits)
12358 results.Add(r);
12359 }
12360 }
12361 else
11356 { 12362 {
11357 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12363 if (checkTerrain)
11358 foreach (ContactResult r in objectHits) 12364 {
11359 results.Add(r); 12365 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12366 if (groundContact != null)
12367 results.Add((ContactResult)groundContact);
12368 }
12369
12370 if (checkAgents)
12371 {
12372 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12373 foreach (ContactResult r in agentHits)
12374 results.Add(r);
12375 }
12376
12377 if (checkPhysical || checkNonPhysical || detectPhantom)
12378 {
12379 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12380 foreach (ContactResult r in objectHits)
12381 results.Add(r);
12382 }
11360 } 12383 }
11361 12384
11362 results.Sort(delegate(ContactResult a, ContactResult b) 12385 results.Sort(delegate(ContactResult a, ContactResult b)
11363 { 12386 {
11364 return a.Depth.CompareTo(b.Depth); 12387 return a.Depth.CompareTo(b.Depth);
11365 }); 12388 });
11366 12389
11367 int values = 0; 12390 int values = 0;
11368 SceneObjectGroup thisgrp = m_host.ParentGroup; 12391 SceneObjectGroup thisgrp = m_host.ParentGroup;
11369 12392
@@ -11456,7 +12479,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11456 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12479 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11457 if (!isAccount) return 0; 12480 if (!isAccount) return 0;
11458 if (estate.HasAccess(id)) return 1; 12481 if (estate.HasAccess(id)) return 1;
11459 if (estate.IsBanned(id)) 12482 if (estate.IsBanned(id, World.GetUserFlags(id)))
11460 estate.RemoveBan(id); 12483 estate.RemoveBan(id);
11461 estate.AddEstateUser(id); 12484 estate.AddEstateUser(id);
11462 break; 12485 break;
@@ -11475,14 +12498,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11475 break; 12498 break;
11476 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12499 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11477 if (!isAccount) return 0; 12500 if (!isAccount) return 0;
11478 if (estate.IsBanned(id)) return 1; 12501 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11479 EstateBan ban = new EstateBan(); 12502 EstateBan ban = new EstateBan();
11480 ban.EstateID = estate.EstateID; 12503 ban.EstateID = estate.EstateID;
11481 ban.BannedUserID = id; 12504 ban.BannedUserID = id;
11482 estate.AddBan(ban); 12505 estate.AddBan(ban);
11483 break; 12506 break;
11484 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12507 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11485 if (!isAccount || !estate.IsBanned(id)) return 0; 12508 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11486 estate.RemoveBan(id); 12509 estate.RemoveBan(id);
11487 break; 12510 break;
11488 default: return 0; 12511 default: return 0;
@@ -11511,7 +12534,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11511 return 16384; 12534 return 16384;
11512 } 12535 }
11513 12536
11514 public LSL_Integer llGetUsedMemory() 12537 public virtual LSL_Integer llGetUsedMemory()
11515 { 12538 {
11516 m_host.AddScriptLPS(1); 12539 m_host.AddScriptLPS(1);
11517 // The value returned for LSO scripts in SL 12540 // The value returned for LSO scripts in SL
@@ -11539,22 +12562,736 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11539 public void llSetSoundQueueing(int queue) 12562 public void llSetSoundQueueing(int queue)
11540 { 12563 {
11541 m_host.AddScriptLPS(1); 12564 m_host.AddScriptLPS(1);
11542 NotImplemented("llSetSoundQueueing");
11543 } 12565 }
11544 12566
11545 public void llCollisionSprite(string impact_sprite) 12567 public void llCollisionSprite(string impact_sprite)
11546 { 12568 {
11547 m_host.AddScriptLPS(1); 12569 m_host.AddScriptLPS(1);
11548 NotImplemented("llCollisionSprite"); 12570 // Viewer 2.0 broke this and it's likely LL has no intention
12571 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11549 } 12572 }
11550 12573
11551 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12574 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11552 { 12575 {
11553 m_host.AddScriptLPS(1); 12576 m_host.AddScriptLPS(1);
11554 NotImplemented("llGodLikeRezObject"); 12577
12578 if (!World.Permissions.IsGod(m_host.OwnerID))
12579 NotImplemented("llGodLikeRezObject");
12580
12581 AssetBase rezAsset = World.AssetService.Get(inventory);
12582 if (rezAsset == null)
12583 {
12584 llSay(0, "Asset not found");
12585 return;
12586 }
12587
12588 SceneObjectGroup group = null;
12589
12590 try
12591 {
12592 string xmlData = Utils.BytesToString(rezAsset.Data);
12593 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12594 }
12595 catch
12596 {
12597 llSay(0, "Asset not found");
12598 return;
12599 }
12600
12601 if (group == null)
12602 {
12603 llSay(0, "Asset not found");
12604 return;
12605 }
12606
12607 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12608 group.RootPart.AttachOffset = group.AbsolutePosition;
12609
12610 group.ResetIDs();
12611
12612 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12613 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12614 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12615 group.ScheduleGroupForFullUpdate();
12616
12617 // objects rezzed with this method are die_at_edge by default.
12618 group.RootPart.SetDieAtEdge(true);
12619
12620 group.ResumeScripts();
12621
12622 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12623 "object_rez", new Object[] {
12624 new LSL_String(
12625 group.RootPart.UUID.ToString()) },
12626 new DetectParams[0]));
12627 }
12628
12629 public LSL_String llTransferLindenDollars(string destination, int amount)
12630 {
12631 UUID txn = UUID.Random();
12632
12633 Util.FireAndForget(delegate(object x)
12634 {
12635 int replycode = 0;
12636 string replydata = destination + "," + amount.ToString();
12637
12638 try
12639 {
12640 TaskInventoryItem item = m_item;
12641 if (item == null)
12642 {
12643 replydata = "SERVICE_ERROR";
12644 return;
12645 }
12646
12647 m_host.AddScriptLPS(1);
12648
12649 if (item.PermsGranter == UUID.Zero)
12650 {
12651 replydata = "MISSING_PERMISSION_DEBIT";
12652 return;
12653 }
12654
12655 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12656 {
12657 replydata = "MISSING_PERMISSION_DEBIT";
12658 return;
12659 }
12660
12661 UUID toID = new UUID();
12662
12663 if (!UUID.TryParse(destination, out toID))
12664 {
12665 replydata = "INVALID_AGENT";
12666 return;
12667 }
12668
12669 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12670
12671 if (money == null)
12672 {
12673 replydata = "TRANSFERS_DISABLED";
12674 return;
12675 }
12676
12677 bool result = money.ObjectGiveMoney(
12678 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
12679
12680 if (result)
12681 {
12682 replycode = 1;
12683 return;
12684 }
12685
12686 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12687 }
12688 finally
12689 {
12690 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12691 "transaction_result", new Object[] {
12692 new LSL_String(txn.ToString()),
12693 new LSL_Integer(replycode),
12694 new LSL_String(replydata) },
12695 new DetectParams[0]));
12696 }
12697 });
12698
12699 return txn.ToString();
11555 } 12700 }
11556 12701
11557 #endregion 12702 #endregion
12703
12704 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12705 {
12706 SceneObjectGroup group = m_host.ParentGroup;
12707
12708 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12709 return;
12710 if (group.IsAttachment)
12711 return;
12712
12713 if (frames.Data.Length > 0) // We are getting a new motion
12714 {
12715 if (group.RootPart.KeyframeMotion != null)
12716 group.RootPart.KeyframeMotion.Delete();
12717 group.RootPart.KeyframeMotion = null;
12718
12719 int idx = 0;
12720
12721 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12722 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12723
12724 while (idx < options.Data.Length)
12725 {
12726 int option = (int)options.GetLSLIntegerItem(idx++);
12727 int remain = options.Data.Length - idx;
12728
12729 switch (option)
12730 {
12731 case ScriptBaseClass.KFM_MODE:
12732 if (remain < 1)
12733 break;
12734 int modeval = (int)options.GetLSLIntegerItem(idx++);
12735 switch(modeval)
12736 {
12737 case ScriptBaseClass.KFM_FORWARD:
12738 mode = KeyframeMotion.PlayMode.Forward;
12739 break;
12740 case ScriptBaseClass.KFM_REVERSE:
12741 mode = KeyframeMotion.PlayMode.Reverse;
12742 break;
12743 case ScriptBaseClass.KFM_LOOP:
12744 mode = KeyframeMotion.PlayMode.Loop;
12745 break;
12746 case ScriptBaseClass.KFM_PING_PONG:
12747 mode = KeyframeMotion.PlayMode.PingPong;
12748 break;
12749 }
12750 break;
12751 case ScriptBaseClass.KFM_DATA:
12752 if (remain < 1)
12753 break;
12754 int dataval = (int)options.GetLSLIntegerItem(idx++);
12755 data = (KeyframeMotion.DataFormat)dataval;
12756 break;
12757 }
12758 }
12759
12760 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12761
12762 idx = 0;
12763
12764 int elemLength = 2;
12765 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12766 elemLength = 3;
12767
12768 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12769 while (idx < frames.Data.Length)
12770 {
12771 int remain = frames.Data.Length - idx;
12772
12773 if (remain < elemLength)
12774 break;
12775
12776 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12777 frame.Position = null;
12778 frame.Rotation = null;
12779
12780 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12781 {
12782 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12783 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12784 }
12785 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12786 {
12787 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12788 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12789 q.Normalize();
12790 frame.Rotation = q;
12791 }
12792
12793 float tempf = (float)frames.GetLSLFloatItem(idx++);
12794 frame.TimeMS = (int)(tempf * 1000.0f);
12795
12796 keyframes.Add(frame);
12797 }
12798
12799 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12800 group.RootPart.KeyframeMotion.Start();
12801 }
12802 else
12803 {
12804 if (group.RootPart.KeyframeMotion == null)
12805 return;
12806
12807 if (options.Data.Length == 0)
12808 {
12809 group.RootPart.KeyframeMotion.Stop();
12810 return;
12811 }
12812
12813 int code = (int)options.GetLSLIntegerItem(0);
12814
12815 int idx = 0;
12816
12817 while (idx < options.Data.Length)
12818 {
12819 int option = (int)options.GetLSLIntegerItem(idx++);
12820 int remain = options.Data.Length - idx;
12821
12822 switch (option)
12823 {
12824 case ScriptBaseClass.KFM_COMMAND:
12825 int cmd = (int)options.GetLSLIntegerItem(idx++);
12826 switch (cmd)
12827 {
12828 case ScriptBaseClass.KFM_CMD_PLAY:
12829 group.RootPart.KeyframeMotion.Start();
12830 break;
12831 case ScriptBaseClass.KFM_CMD_STOP:
12832 group.RootPart.KeyframeMotion.Stop();
12833 break;
12834 case ScriptBaseClass.KFM_CMD_PAUSE:
12835 group.RootPart.KeyframeMotion.Pause();
12836 break;
12837 }
12838 break;
12839 }
12840 }
12841 }
12842 }
12843
12844 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12845 {
12846 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12847
12848 int idx = 0;
12849 int idxStart = 0;
12850
12851 bool positionChanged = false;
12852 Vector3 finalPos = Vector3.Zero;
12853
12854 try
12855 {
12856 while (idx < rules.Length)
12857 {
12858 ++rulesParsed;
12859 int code = rules.GetLSLIntegerItem(idx++);
12860
12861 int remain = rules.Length - idx;
12862 idxStart = idx;
12863
12864 switch (code)
12865 {
12866 case (int)ScriptBaseClass.PRIM_POSITION:
12867 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12868 {
12869 if (remain < 1)
12870 return null;
12871
12872 LSL_Vector v;
12873 v = rules.GetVector3Item(idx++);
12874
12875 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12876 if (part == null)
12877 break;
12878
12879 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12880 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12881 if (part.LinkNum > 1)
12882 {
12883 localRot = GetPartLocalRot(part);
12884 localPos = GetPartLocalPos(part);
12885 }
12886
12887 v -= localPos;
12888 v /= localRot;
12889
12890 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12891
12892 v = v + 2 * sitOffset;
12893
12894 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12895 av.SendAvatarDataToAllAgents();
12896
12897 }
12898 break;
12899
12900 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12901 case (int)ScriptBaseClass.PRIM_ROTATION:
12902 {
12903 if (remain < 1)
12904 return null;
12905
12906 LSL_Rotation r;
12907 r = rules.GetQuaternionItem(idx++);
12908
12909 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12910 if (part == null)
12911 break;
12912
12913 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12914 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12915
12916 if (part.LinkNum > 1)
12917 localRot = GetPartLocalRot(part);
12918
12919 r = r * llGetRootRotation() / localRot;
12920 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12921 av.SendAvatarDataToAllAgents();
12922 }
12923 break;
12924
12925 // parse rest doing nothing but number of parameters error check
12926 case (int)ScriptBaseClass.PRIM_SIZE:
12927 case (int)ScriptBaseClass.PRIM_MATERIAL:
12928 case (int)ScriptBaseClass.PRIM_PHANTOM:
12929 case (int)ScriptBaseClass.PRIM_PHYSICS:
12930 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12931 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12932 case (int)ScriptBaseClass.PRIM_NAME:
12933 case (int)ScriptBaseClass.PRIM_DESC:
12934 if (remain < 1)
12935 return null;
12936 idx++;
12937 break;
12938
12939 case (int)ScriptBaseClass.PRIM_GLOW:
12940 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12941 case (int)ScriptBaseClass.PRIM_TEXGEN:
12942 if (remain < 2)
12943 return null;
12944 idx += 2;
12945 break;
12946
12947 case (int)ScriptBaseClass.PRIM_TYPE:
12948 if (remain < 3)
12949 return null;
12950 code = (int)rules.GetLSLIntegerItem(idx++);
12951 remain = rules.Length - idx;
12952 switch (code)
12953 {
12954 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12955 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12956 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12957 if (remain < 6)
12958 return null;
12959 idx += 6;
12960 break;
12961
12962 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12963 if (remain < 5)
12964 return null;
12965 idx += 5;
12966 break;
12967
12968 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12969 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12970 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12971 if (remain < 11)
12972 return null;
12973 idx += 11;
12974 break;
12975
12976 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12977 if (remain < 2)
12978 return null;
12979 idx += 2;
12980 break;
12981 }
12982 break;
12983
12984 case (int)ScriptBaseClass.PRIM_COLOR:
12985 case (int)ScriptBaseClass.PRIM_TEXT:
12986 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12987 case (int)ScriptBaseClass.PRIM_OMEGA:
12988 if (remain < 3)
12989 return null;
12990 idx += 3;
12991 break;
12992
12993 case (int)ScriptBaseClass.PRIM_TEXTURE:
12994 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12995 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12996 if (remain < 5)
12997 return null;
12998 idx += 5;
12999 break;
13000
13001 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13002 if (remain < 7)
13003 return null;
13004
13005 idx += 7;
13006 break;
13007
13008 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13009 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13010 return null;
13011
13012 return rules.GetSublist(idx, -1);
13013 }
13014 }
13015 }
13016 catch (InvalidCastException e)
13017 {
13018 ShoutError(string.Format(
13019 "{0} error running rule #{1}: arg #{2} ",
13020 originFunc, rulesParsed, idx - idxStart) + e.Message);
13021 }
13022 finally
13023 {
13024 if (positionChanged)
13025 {
13026 av.OffsetPosition = finalPos;
13027// av.SendAvatarDataToAllAgents();
13028 av.SendTerseUpdateToAllClients();
13029 positionChanged = false;
13030 }
13031 }
13032 return null;
13033 }
13034
13035 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13036 {
13037 // avatars case
13038 // replies as SL wiki
13039
13040// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13041 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13042
13043 int idx = 0;
13044 while (idx < rules.Length)
13045 {
13046 int code = (int)rules.GetLSLIntegerItem(idx++);
13047 int remain = rules.Length - idx;
13048
13049 switch (code)
13050 {
13051 case (int)ScriptBaseClass.PRIM_MATERIAL:
13052 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13053 break;
13054
13055 case (int)ScriptBaseClass.PRIM_PHYSICS:
13056 res.Add(new LSL_Integer(0));
13057 break;
13058
13059 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13060 res.Add(new LSL_Integer(0));
13061 break;
13062
13063 case (int)ScriptBaseClass.PRIM_PHANTOM:
13064 res.Add(new LSL_Integer(0));
13065 break;
13066
13067 case (int)ScriptBaseClass.PRIM_POSITION:
13068
13069 Vector3 pos = avatar.OffsetPosition;
13070
13071 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13072 pos -= sitOffset;
13073
13074 if( sitPart != null)
13075 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13076
13077 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13078 break;
13079
13080 case (int)ScriptBaseClass.PRIM_SIZE:
13081 // as in llGetAgentSize above
13082// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13083 Vector3 s = avatar.Appearance.AvatarSize;
13084 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13085
13086 break;
13087
13088 case (int)ScriptBaseClass.PRIM_ROTATION:
13089 Quaternion rot = avatar.Rotation;
13090 if (sitPart != null)
13091 {
13092 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13093 }
13094
13095 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13096 break;
13097
13098 case (int)ScriptBaseClass.PRIM_TYPE:
13099 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13100 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13101 res.Add(new LSL_Vector(0f,1.0f,0f));
13102 res.Add(new LSL_Float(0.0f));
13103 res.Add(new LSL_Vector(0, 0, 0));
13104 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13105 res.Add(new LSL_Vector(0, 0, 0));
13106 break;
13107
13108 case (int)ScriptBaseClass.PRIM_TEXTURE:
13109 if (remain < 1)
13110 return null;
13111
13112 int face = (int)rules.GetLSLIntegerItem(idx++);
13113 if (face == ScriptBaseClass.ALL_SIDES)
13114 {
13115 for (face = 0; face < 21; face++)
13116 {
13117 res.Add(new LSL_String(""));
13118 res.Add(new LSL_Vector(0,0,0));
13119 res.Add(new LSL_Vector(0,0,0));
13120 res.Add(new LSL_Float(0.0));
13121 }
13122 }
13123 else
13124 {
13125 if (face >= 0 && face < 21)
13126 {
13127 res.Add(new LSL_String(""));
13128 res.Add(new LSL_Vector(0,0,0));
13129 res.Add(new LSL_Vector(0,0,0));
13130 res.Add(new LSL_Float(0.0));
13131 }
13132 }
13133 break;
13134
13135 case (int)ScriptBaseClass.PRIM_COLOR:
13136 if (remain < 1)
13137 return null;
13138
13139 face = (int)rules.GetLSLIntegerItem(idx++);
13140
13141 if (face == ScriptBaseClass.ALL_SIDES)
13142 {
13143 for (face = 0; face < 21; face++)
13144 {
13145 res.Add(new LSL_Vector(0,0,0));
13146 res.Add(new LSL_Float(0));
13147 }
13148 }
13149 else
13150 {
13151 res.Add(new LSL_Vector(0,0,0));
13152 res.Add(new LSL_Float(0));
13153 }
13154 break;
13155
13156 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13157 if (remain < 1)
13158 return null;
13159 face = (int)rules.GetLSLIntegerItem(idx++);
13160
13161 if (face == ScriptBaseClass.ALL_SIDES)
13162 {
13163 for (face = 0; face < 21; face++)
13164 {
13165 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13166 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13167 }
13168 }
13169 else
13170 {
13171 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13172 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13173 }
13174 break;
13175
13176 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13177 if (remain < 1)
13178 return null;
13179 face = (int)rules.GetLSLIntegerItem(idx++);
13180
13181 if (face == ScriptBaseClass.ALL_SIDES)
13182 {
13183 for (face = 0; face < 21; face++)
13184 {
13185 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13186 }
13187 }
13188 else
13189 {
13190 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13191 }
13192 break;
13193
13194 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13195 res.Add(new LSL_Integer(0));
13196 res.Add(new LSL_Integer(0));// softness
13197 res.Add(new LSL_Float(0.0f)); // gravity
13198 res.Add(new LSL_Float(0.0f)); // friction
13199 res.Add(new LSL_Float(0.0f)); // wind
13200 res.Add(new LSL_Float(0.0f)); // tension
13201 res.Add(new LSL_Vector(0f,0f,0f));
13202 break;
13203
13204 case (int)ScriptBaseClass.PRIM_TEXGEN:
13205 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13206 if (remain < 1)
13207 return null;
13208 face = (int)rules.GetLSLIntegerItem(idx++);
13209
13210 if (face == ScriptBaseClass.ALL_SIDES)
13211 {
13212 for (face = 0; face < 21; face++)
13213 {
13214 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13215 }
13216 }
13217 else
13218 {
13219 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13220 }
13221 break;
13222
13223 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13224 res.Add(new LSL_Integer(0));
13225 res.Add(new LSL_Vector(0f,0f,0f));
13226 res.Add(new LSL_Float(0f)); // intensity
13227 res.Add(new LSL_Float(0f)); // radius
13228 res.Add(new LSL_Float(0f)); // falloff
13229 break;
13230
13231 case (int)ScriptBaseClass.PRIM_GLOW:
13232 if (remain < 1)
13233 return null;
13234 face = (int)rules.GetLSLIntegerItem(idx++);
13235
13236 if (face == ScriptBaseClass.ALL_SIDES)
13237 {
13238 for (face = 0; face < 21; face++)
13239 {
13240 res.Add(new LSL_Float(0f));
13241 }
13242 }
13243 else
13244 {
13245 res.Add(new LSL_Float(0f));
13246 }
13247 break;
13248
13249 case (int)ScriptBaseClass.PRIM_TEXT:
13250 res.Add(new LSL_String(""));
13251 res.Add(new LSL_Vector(0f,0f,0f));
13252 res.Add(new LSL_Float(1.0f));
13253 break;
13254
13255 case (int)ScriptBaseClass.PRIM_NAME:
13256 res.Add(new LSL_String(avatar.Name));
13257 break;
13258
13259 case (int)ScriptBaseClass.PRIM_DESC:
13260 res.Add(new LSL_String(""));
13261 break;
13262
13263 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13264 Quaternion lrot = avatar.Rotation;
13265
13266 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13267 {
13268 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13269 }
13270 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13271 break;
13272
13273 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13274 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13275 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13276 lpos -= lsitOffset;
13277
13278 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13279 {
13280 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13281 }
13282 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13283 break;
13284
13285 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13286 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13287 return null;
13288
13289 return rules.GetSublist(idx, -1);
13290 }
13291 }
13292
13293 return null;
13294 }
11558 } 13295 }
11559 13296
11560 public class NotecardCache 13297 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 5c0ff1c..d6ce069 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -138,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
139 internal float m_ScriptDelayFactor = 1.0f; 139 internal float m_ScriptDelayFactor = 1.0f;
140 internal float m_ScriptDistanceFactor = 1.0f; 140 internal float m_ScriptDistanceFactor = 1.0f;
141 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 143
143 protected IUrlModule m_UrlModule = null; 144 protected IUrlModule m_UrlModule = null;
@@ -148,6 +149,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
148 m_ScriptEngine = scriptEngine; 149 m_ScriptEngine = scriptEngine;
149 m_host = host; 150 m_host = host;
150 m_item = item; 151 m_item = item;
152 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
151 153
152 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 154 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
153 155
@@ -211,7 +213,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
211 213
212 internal void OSSLError(string msg) 214 internal void OSSLError(string msg)
213 { 215 {
214 throw new ScriptException("OSSL Runtime Error: " + msg); 216 if (m_debuggerSafe)
217 {
218 OSSLShoutError(msg);
219 }
220 else
221 {
222 throw new ScriptException("OSSL Runtime Error: " + msg);
223 }
215 } 224 }
216 225
217 /// <summary> 226 /// <summary>
@@ -930,18 +939,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
930 if (target != null) 939 if (target != null)
931 { 940 {
932 UUID animID=UUID.Zero; 941 UUID animID=UUID.Zero;
933 lock (m_host.TaskInventory) 942 m_host.TaskInventory.LockItemsForRead(true);
943 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
934 { 944 {
935 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 945 if (inv.Value.Name == animation)
936 { 946 {
937 if (inv.Value.Name == animation) 947 if (inv.Value.Type == (int)AssetType.Animation)
938 { 948 animID = inv.Value.AssetID;
939 if (inv.Value.Type == (int)AssetType.Animation) 949 continue;
940 animID = inv.Value.AssetID;
941 continue;
942 }
943 } 950 }
944 } 951 }
952 m_host.TaskInventory.LockItemsForRead(false);
945 if (animID == UUID.Zero) 953 if (animID == UUID.Zero)
946 target.Animator.AddAnimation(animation, m_host.UUID); 954 target.Animator.AddAnimation(animation, m_host.UUID);
947 else 955 else
@@ -982,6 +990,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
982 else 990 else
983 animID = UUID.Zero; 991 animID = UUID.Zero;
984 } 992 }
993 m_host.TaskInventory.LockItemsForRead(false);
985 994
986 if (animID == UUID.Zero) 995 if (animID == UUID.Zero)
987 target.Animator.RemoveAnimation(animation); 996 target.Animator.RemoveAnimation(animation);
@@ -1850,6 +1859,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1850 1859
1851 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1860 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1852 { 1861 {
1862 m_host.TaskInventory.LockItemsForRead(true);
1853 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1863 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1854 { 1864 {
1855 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1865 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1857,6 +1867,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1857 assetID = item.AssetID; 1867 assetID = item.AssetID;
1858 } 1868 }
1859 } 1869 }
1870 m_host.TaskInventory.LockItemsForRead(false);
1860 } 1871 }
1861 1872
1862 if (assetID == UUID.Zero) 1873 if (assetID == UUID.Zero)
@@ -2342,7 +2353,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2342 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2353 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2343 m_host.AddScriptLPS(1); 2354 m_host.AddScriptLPS(1);
2344 2355
2345 return NpcCreate(firstname, lastname, position, notecard, false, false); 2356 return NpcCreate(firstname, lastname, position, notecard, true, false);
2346 } 2357 }
2347 2358
2348 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2359 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2353,24 +2364,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2353 return NpcCreate( 2364 return NpcCreate(
2354 firstname, lastname, position, notecard, 2365 firstname, lastname, position, notecard,
2355 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2366 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2356 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2367 false);
2368// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2357 } 2369 }
2358 2370
2359 private LSL_Key NpcCreate( 2371 private LSL_Key NpcCreate(
2360 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2372 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2361 { 2373 {
2374 if (!owned)
2375 OSSLError("Unowned NPCs are unsupported");
2376
2377 string groupTitle = String.Empty;
2378
2379 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2380 return new LSL_Key(UUID.Zero.ToString());
2381
2382 if (firstname != String.Empty || lastname != String.Empty)
2383 {
2384 if (firstname != "Shown outfit:")
2385 groupTitle = "- NPC -";
2386 }
2387
2362 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2388 INPCModule module = World.RequestModuleInterface<INPCModule>();
2363 if (module != null) 2389 if (module != null)
2364 { 2390 {
2365 AvatarAppearance appearance = null; 2391 AvatarAppearance appearance = null;
2366 2392
2367 UUID id; 2393// UUID id;
2368 if (UUID.TryParse(notecard, out id)) 2394// if (UUID.TryParse(notecard, out id))
2369 { 2395// {
2370 ScenePresence clonePresence = World.GetScenePresence(id); 2396// ScenePresence clonePresence = World.GetScenePresence(id);
2371 if (clonePresence != null) 2397// if (clonePresence != null)
2372 appearance = clonePresence.Appearance; 2398// appearance = clonePresence.Appearance;
2373 } 2399// }
2374 2400
2375 if (appearance == null) 2401 if (appearance == null)
2376 { 2402 {
@@ -2378,9 +2404,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2378 2404
2379 if (appearanceSerialized != null) 2405 if (appearanceSerialized != null)
2380 { 2406 {
2381 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2407 try
2382 appearance = new AvatarAppearance(); 2408 {
2383 appearance.Unpack(appearanceOsd); 2409 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2410 appearance = new AvatarAppearance();
2411 appearance.Unpack(appearanceOsd);
2412 }
2413 catch
2414 {
2415 return UUID.Zero.ToString();
2416 }
2384 } 2417 }
2385 else 2418 else
2386 { 2419 {
@@ -2399,6 +2432,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2399 World, 2432 World,
2400 appearance); 2433 appearance);
2401 2434
2435 ScenePresence sp;
2436 if (World.TryGetScenePresence(x, out sp))
2437 {
2438 sp.Grouptitle = groupTitle;
2439 sp.SendAvatarDataToAllAgents();
2440 }
2402 return new LSL_Key(x.ToString()); 2441 return new LSL_Key(x.ToString());
2403 } 2442 }
2404 2443
@@ -2702,16 +2741,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2702 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2741 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2703 m_host.AddScriptLPS(1); 2742 m_host.AddScriptLPS(1);
2704 2743
2705 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2744 ManualResetEvent ev = new ManualResetEvent(false);
2706 if (module != null)
2707 {
2708 UUID npcId = new UUID(npc.m_string);
2709 2745
2710 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2746 Util.FireAndForget(delegate(object x) {
2711 return; 2747 try
2748 {
2749 INPCModule module = World.RequestModuleInterface<INPCModule>();
2750 if (module != null)
2751 {
2752 UUID npcId = new UUID(npc.m_string);
2712 2753
2713 module.DeleteNPC(npcId, World); 2754 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2714 } 2755 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2756 {
2757 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2758 return;
2759 }
2760
2761 module.DeleteNPC(npcId, World);
2762 }
2763 }
2764 finally
2765 {
2766 ev.Set();
2767 }
2768 });
2769 ev.WaitOne();
2715 } 2770 }
2716 2771
2717 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2772 public void osNpcPlayAnimation(LSL_Key npc, string animation)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index dd45406..d3ef378 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -93,7 +93,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
93 private const int AGENT = 1; 93 private const int AGENT = 1;
94 private const int AGENT_BY_USERNAME = 0x10; 94 private const int AGENT_BY_USERNAME = 0x10;
95 private const int NPC = 0x20; 95 private const int NPC = 0x20;
96 private const int OS_NPC = 0x01000000;
97 private const int ACTIVE = 2; 96 private const int ACTIVE = 2;
98 private const int PASSIVE = 4; 97 private const int PASSIVE = 4;
99 private const int SCRIPTED = 8; 98 private const int SCRIPTED = 8;
@@ -240,7 +239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
240 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 239 List<SensedEntity> sensedEntities = new List<SensedEntity>();
241 240
242 // Is the sensor type is AGENT and not SCRIPTED then include agents 241 // Is the sensor type is AGENT and not SCRIPTED then include agents
243 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 242 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
244 { 243 {
245 sensedEntities.AddRange(doAgentSensor(ts)); 244 sensedEntities.AddRange(doAgentSensor(ts));
246 } 245 }
@@ -339,7 +338,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
339 float dy; 338 float dy;
340 float dz; 339 float dz;
341 340
342 Quaternion q = SensePoint.GetWorldRotation(); 341// Quaternion q = SensePoint.RotationOffset;
342 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
343 if (SensePoint.ParentGroup.IsAttachment) 343 if (SensePoint.ParentGroup.IsAttachment)
344 { 344 {
345 // In attachments, rotate the sensor cone with the 345 // In attachments, rotate the sensor cone with the
@@ -353,7 +353,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
353 // Position of a sensor in a child prim attached to an avatar 353 // Position of a sensor in a child prim attached to an avatar
354 // will be still wrong. 354 // will be still wrong.
355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
356 q = avatar.Rotation * q; 356 fromRegionPos = avatar.AbsolutePosition;
357 q = avatar.Rotation;
357 } 358 }
358 359
359 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 360 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -480,7 +481,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
480 // Position of a sensor in a child prim attached to an avatar 481 // Position of a sensor in a child prim attached to an avatar
481 // will be still wrong. 482 // will be still wrong.
482 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 483 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
483 q = avatar.Rotation * q; 484 if (avatar == null)
485 return sensedEntities;
486 fromRegionPos = avatar.AbsolutePosition;
487 q = avatar.Rotation;
484 } 488 }
485 489
486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 490 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -496,7 +500,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
496// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 500// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
497// presence.Name, presence.PresenceType, ts.name, ts.type); 501// presence.Name, presence.PresenceType, ts.name, ts.type);
498 502
499 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 503 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
500 { 504 {
501 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 505 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
502 if (npcData == null || !npcData.SenseAsAgent) 506 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 0b14565..68aacd2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -123,25 +123,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
123 if (Timers.Count == 0) 123 if (Timers.Count == 0)
124 return; 124 return;
125 125
126 Dictionary<string, TimerInfo>.ValueCollection tvals;
126 lock (TimerListLock) 127 lock (TimerListLock)
127 { 128 {
128 // Go through all timers 129 // Go through all timers
129 Dictionary<string, TimerInfo>.ValueCollection tvals = Timers.Values; 130 tvals = Timers.Values;
130 foreach (TimerInfo ts in tvals) 131 }
132
133 foreach (TimerInfo ts in tvals)
134 {
135 // Time has passed?
136 if (ts.next < DateTime.Now.Ticks)
131 { 137 {
132 // Time has passed? 138 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
133 if (ts.next < DateTime.Now.Ticks) 139 // Add it to queue
134 { 140 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
135 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 141 new EventParams("timer", new Object[0],
136 // Add it to queue 142 new DetectParams[0]));
137 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 143 // set next interval
138 new EventParams("timer", new Object[0], 144
139 new DetectParams[0])); 145 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
140 // set next interval 146 ts.next = DateTime.Now.Ticks + ts.interval;
141
142 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
143 ts.next = DateTime.Now.Ticks + ts.interval;
144 }
145 } 147 }
146 } 148 }
147 } 149 }
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 98f8be7..9bf6f9b 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);
@@ -356,11 +359,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
356 void llSetParcelMusicURL(string url); 359 void llSetParcelMusicURL(string url);
357 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 360 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
358 void llSetPos(LSL_Vector pos); 361 void llSetPos(LSL_Vector pos);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
359 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 363 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
360 void llSetPrimitiveParams(LSL_List rules); 364 void llSetPrimitiveParams(LSL_List rules);
361 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 365 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
362 void llSetPrimURL(string url); 366 void llSetPrimURL(string url);
363 LSL_Integer llSetRegionPos(LSL_Vector pos);
364 void llSetRemoteScriptAccessPin(int pin); 367 void llSetRemoteScriptAccessPin(int pin);
365 void llSetRot(LSL_Rotation rot); 368 void llSetRot(LSL_Rotation rot);
366 void llSetScale(LSL_Vector scale); 369 void llSetScale(LSL_Vector scale);
@@ -380,6 +383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
380 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 383 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
381 void llSetVehicleType(int type); 384 void llSetVehicleType(int type);
382 void llSetVehicleVectorParam(int param, LSL_Vector vec); 385 void llSetVehicleVectorParam(int param, LSL_Vector vec);
386 void llSetVelocity(LSL_Vector velocity, int local);
383 void llShout(int channelID, string text); 387 void llShout(int channelID, string text);
384 LSL_Float llSin(double f); 388 LSL_Float llSin(double f);
385 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 389 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -423,9 +427,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
423 LSL_Vector llWind(LSL_Vector offset); 427 LSL_Vector llWind(LSL_Vector offset);
424 LSL_String llXorBase64Strings(string str1, string str2); 428 LSL_String llXorBase64Strings(string str1, string str2);
425 LSL_String llXorBase64StringsCorrect(string str1, string str2); 429 LSL_String llXorBase64StringsCorrect(string str1, string str2);
426 void print(string str); 430 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
431 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
427 432
428 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); 433 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
429 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 435 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
430 } 436 }
431} 437}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 51d0581..7eb347e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -144,7 +144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
144 // Avatar Info Commands 144 // Avatar Info Commands
145 string osGetAgentIP(string agent); 145 string osGetAgentIP(string agent);
146 LSL_List osGetAgents(); 146 LSL_List osGetAgents();
147 147
148 // Teleport commands 148 // Teleport commands
149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 9bf1a64..da3b31f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -56,7 +56,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
56 public const int ACTIVE = 2; 56 public const int ACTIVE = 2;
57 public const int PASSIVE = 4; 57 public const int PASSIVE = 4;
58 public const int SCRIPTED = 8; 58 public const int SCRIPTED = 8;
59 public const int OS_NPC = 0x01000000;
60 59
61 public const int CONTROL_FWD = 1; 60 public const int CONTROL_FWD = 1;
62 public const int CONTROL_BACK = 2; 61 public const int CONTROL_BACK = 2;
@@ -95,6 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
95 public const int AGENT_CROUCHING = 1024; 94 public const int AGENT_CROUCHING = 1024;
96 public const int AGENT_BUSY = 2048; 95 public const int AGENT_BUSY = 2048;
97 public const int AGENT_ALWAYS_RUN = 4096; 96 public const int AGENT_ALWAYS_RUN = 4096;
97 public const int AGENT_MALE = 8192;
98 98
99 //Particle Systems 99 //Particle Systems
100 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 100 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -337,6 +337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
337 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 337 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
338 public const int CHANGED_MEDIA = 2048; 338 public const int CHANGED_MEDIA = 2048;
339 public const int CHANGED_ANIMATION = 16384; 339 public const int CHANGED_ANIMATION = 16384;
340 public const int CHANGED_POSITION = 32768;
340 public const int TYPE_INVALID = 0; 341 public const int TYPE_INVALID = 0;
341 public const int TYPE_INTEGER = 1; 342 public const int TYPE_INTEGER = 1;
342 public const int TYPE_FLOAT = 2; 343 public const int TYPE_FLOAT = 2;
@@ -660,6 +661,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
660 public const int PRIM_MEDIA_PERM_OWNER = 1; 661 public const int PRIM_MEDIA_PERM_OWNER = 1;
661 public const int PRIM_MEDIA_PERM_GROUP = 2; 662 public const int PRIM_MEDIA_PERM_GROUP = 2;
662 public const int PRIM_MEDIA_PERM_ANYONE = 4; 663 public const int PRIM_MEDIA_PERM_ANYONE = 4;
664
665 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
666 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
667 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
668 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
669
670 public const int PRIM_PHYSICS_MATERIAL = 31;
671 public const int DENSITY = 1;
672 public const int FRICTION = 2;
673 public const int RESTITUTION = 4;
674 public const int GRAVITY_MULTIPLIER = 8;
663 675
664 // extra constants for llSetPrimMediaParams 676 // extra constants for llSetPrimMediaParams
665 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 677 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -732,7 +744,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
732 744
733 public static readonly LSLInteger RCERR_UNKNOWN = -1; 745 public static readonly LSLInteger RCERR_UNKNOWN = -1;
734 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 746 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
735 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 747 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
748
749 public const int KFM_MODE = 1;
750 public const int KFM_LOOP = 1;
751 public const int KFM_REVERSE = 3;
752 public const int KFM_FORWARD = 0;
753 public const int KFM_PING_PONG = 2;
754 public const int KFM_DATA = 2;
755 public const int KFM_TRANSLATION = 2;
756 public const int KFM_ROTATION = 1;
757 public const int KFM_COMMAND = 0;
758 public const int KFM_CMD_PLAY = 0;
759 public const int KFM_CMD_STOP = 1;
760 public const int KFM_CMD_PAUSE = 2;
736 761
737 /// <summary> 762 /// <summary>
738 /// process name parameter as regex 763 /// process name parameter as regex
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 36803a4..8ecc4f8 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);
@@ -1608,6 +1625,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1608 m_LSL_Functions.llSetPos(pos); 1625 m_LSL_Functions.llSetPos(pos);
1609 } 1626 }
1610 1627
1628 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1629 {
1630 return m_LSL_Functions.llSetRegionPos(pos);
1631 }
1632
1611 public void llSetPrimitiveParams(LSL_List rules) 1633 public void llSetPrimitiveParams(LSL_List rules)
1612 { 1634 {
1613 m_LSL_Functions.llSetPrimitiveParams(rules); 1635 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1623,11 +1645,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1623 m_LSL_Functions.llSetPrimURL(url); 1645 m_LSL_Functions.llSetPrimURL(url);
1624 } 1646 }
1625 1647
1626 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1627 {
1628 return m_LSL_Functions.llSetRegionPos(pos);
1629 }
1630
1631 public void llSetRemoteScriptAccessPin(int pin) 1648 public void llSetRemoteScriptAccessPin(int pin)
1632 { 1649 {
1633 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1650 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1723,6 +1740,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1723 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1740 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1724 } 1741 }
1725 1742
1743 public void llSetVelocity(LSL_Vector velocity, int local)
1744 {
1745 m_LSL_Functions.llSetVelocity(velocity, local);
1746 }
1747
1726 public void llShout(int channelID, string text) 1748 public void llShout(int channelID, string text)
1727 { 1749 {
1728 m_LSL_Functions.llShout(channelID, text); 1750 m_LSL_Functions.llShout(channelID, text);
@@ -1973,9 +1995,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1973 return m_LSL_Functions.llClearLinkMedia(link, face); 1995 return m_LSL_Functions.llClearLinkMedia(link, face);
1974 } 1996 }
1975 1997
1976 public void print(string str) 1998 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1999 {
2000 return m_LSL_Functions.llGetLinkNumberOfSides(link);
2001 }
2002
2003 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
2004 {
2005 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2006 }
2007
2008 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1977 { 2009 {
1978 m_LSL_Functions.print(str); 2010 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1979 } 2011 }
1980 } 2012 }
1981} 2013}
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 e02d35e..e44a106 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
@@ -120,6 +121,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
120 Type = 0; 121 Type = 0;
121 Velocity = new LSL_Types.Vector3(); 122 Velocity = new LSL_Types.Vector3();
122 initializeSurfaceTouch(); 123 initializeSurfaceTouch();
124 Country = String.Empty;
123 } 125 }
124 126
125 public UUID Key; 127 public UUID Key;
@@ -151,6 +153,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
151 private int touchFace; 153 private int touchFace;
152 public int TouchFace { get { return touchFace; } } 154 public int TouchFace { get { return touchFace; } }
153 155
156 public string Country;
157
154 // This can be done in two places including the constructor 158 // This can be done in two places including the constructor
155 // so be carefull what gets added here 159 // so be carefull what gets added here
156 private void initializeSurfaceTouch() 160 private void initializeSurfaceTouch()
@@ -198,6 +202,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
198 return; 202 return;
199 203
200 Name = presence.Firstname + " " + presence.Lastname; 204 Name = presence.Firstname + " " + presence.Lastname;
205 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
206 if (account != null)
207 Country = account.UserCountry;
208
201 Owner = Key; 209 Owner = Key;
202 Position = new LSL_Types.Vector3(presence.AbsolutePosition); 210 Position = new LSL_Types.Vector3(presence.AbsolutePosition);
203 Rotation = new LSL_Types.Quaternion( 211 Rotation = new LSL_Types.Quaternion(
@@ -207,22 +215,27 @@ namespace OpenSim.Region.ScriptEngine.Shared
207 presence.Rotation.W); 215 presence.Rotation.W);
208 Velocity = new LSL_Types.Vector3(presence.Velocity); 216 Velocity = new LSL_Types.Vector3(presence.Velocity);
209 217
210 if (presence.PresenceType != PresenceType.Npc) 218 Type = 0x01; // Avatar
211 { 219 if (presence.PresenceType == PresenceType.Npc)
212 Type = AGENT; 220 Type = 0x20;
213 } 221
214 else 222 // Cope Impl. We don't use OS_NPC.
215 { 223 //if (presence.PresenceType != PresenceType.Npc)
216 Type = OS_NPC; 224 //{
217 225 // Type = AGENT;
218 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 226 //}
219 INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); 227 //else
220 228 //{
221 if (npcData.SenseAsAgent) 229 // Type = OS_NPC;
222 { 230
223 Type |= AGENT; 231 // INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
224 } 232 // INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
225 } 233
234 // if (npcData.SenseAsAgent)
235 // {
236 // Type |= AGENT;
237 // }
238 //}
226 239
227 if (presence.Velocity != Vector3.Zero) 240 if (presence.Velocity != Vector3.Zero)
228 Type |= ACTIVE; 241 Type |= ACTIVE;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 75aea2b..a869a6a 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;
@@ -165,13 +166,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
165 166
166 public UUID ItemID { get; private set; } 167 public UUID ItemID { get; private set; }
167 168
168 public UUID ObjectID { get { return Part.UUID; } } 169 public UUID ObjectID { get; private set; }
169 170
170 public uint LocalID { get { return Part.LocalId; } } 171 public uint LocalID { get; private set; }
171 172
172 public UUID RootObjectID { get { return Part.ParentGroup.UUID; } } 173 public UUID RootObjectID { get; private set; }
173 174
174 public uint RootLocalID { get { return Part.ParentGroup.LocalId; } } 175 public uint RootLocalID { get; private set; }
175 176
176 public UUID AssetID { get; private set; } 177 public UUID AssetID { get; private set; }
177 178
@@ -235,8 +236,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
235 StartParam = startParam; 236 StartParam = startParam;
236 m_MaxScriptQueue = maxScriptQueue; 237 m_MaxScriptQueue = maxScriptQueue;
237 m_postOnRez = postOnRez; 238 m_postOnRez = postOnRez;
238 m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; 239 m_AttachedAvatar = part.ParentGroup.AttachedAvatar;
239 m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; 240 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID;
240 241
241 if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op") 242 if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op")
242 { 243 {
@@ -433,27 +434,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
433 PostEvent(new EventParams("attach", 434 PostEvent(new EventParams("attach",
434 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); 435 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0]));
435 } 436 }
437
436 } 438 }
437 } 439 }
438 440
439 private void ReleaseControls() 441 private void ReleaseControls()
440 { 442 {
441 int permsMask; 443 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
442 UUID permsGranter; 444
443 lock (Part.TaskInventory) 445 if (part != null)
444 { 446 {
445 if (!Part.TaskInventory.ContainsKey(ItemID)) 447 int permsMask;
448 UUID permsGranter;
449 part.TaskInventory.LockItemsForRead(true);
450 if (!part.TaskInventory.ContainsKey(ItemID))
451 {
452 part.TaskInventory.LockItemsForRead(false);
446 return; 453 return;
454 }
455 permsGranter = part.TaskInventory[ItemID].PermsGranter;
456 permsMask = part.TaskInventory[ItemID].PermsMask;
457 part.TaskInventory.LockItemsForRead(false);
447 458
448 permsGranter = Part.TaskInventory[ItemID].PermsGranter; 459 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
449 permsMask = Part.TaskInventory[ItemID].PermsMask; 460 {
450 } 461 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
451 462 if (presence != null)
452 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 463 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
453 { 464 }
454 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
455 if (presence != null)
456 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
457 } 465 }
458 } 466 }
459 467
@@ -600,6 +608,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
600 return true; 608 return true;
601 } 609 }
602 610
611 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
603 public void SetState(string state) 612 public void SetState(string state)
604 { 613 {
605 if (state == State) 614 if (state == State)
@@ -611,7 +620,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
611 new DetectParams[0])); 620 new DetectParams[0]));
612 PostEvent(new EventParams("state_entry", new Object[0], 621 PostEvent(new EventParams("state_entry", new Object[0],
613 new DetectParams[0])); 622 new DetectParams[0]));
614 623
615 throw new EventAbortException(); 624 throw new EventAbortException();
616 } 625 }
617 626
@@ -701,57 +710,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
701 /// <returns></returns> 710 /// <returns></returns>
702 public object EventProcessor() 711 public object EventProcessor()
703 { 712 {
713 EventParams data = null;
704 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 714 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
705 if (!Running) 715 if (!Running)
706 return 0; 716 return 0;
707 717
708 lock (m_Script)
709 {
710// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 718// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
711 719
712 if (Suspended) 720 if (Suspended)
713 return 0; 721 return 0;
714
715 EventParams data = null;
716 722
717 lock (EventQueue) 723 lock (EventQueue)
724 {
725 data = (EventParams) EventQueue.Dequeue();
726 if (data == null) // Shouldn't happen
718 { 727 {
719 data = (EventParams)EventQueue.Dequeue(); 728 if (EventQueue.Count > 0 && Running && !ShuttingDown)
720 if (data == null) // Shouldn't happen
721 { 729 {
722 if (EventQueue.Count > 0 && Running && !ShuttingDown) 730 m_CurrentWorkItem = Engine.QueueEventHandler(this);
723 {
724 m_CurrentWorkItem = Engine.QueueEventHandler(this);
725 }
726 else
727 {
728 m_CurrentWorkItem = null;
729 }
730 return 0;
731 } 731 }
732 732 else
733 if (data.EventName == "timer")
734 m_TimerQueued = false;
735 if (data.EventName == "control")
736 { 733 {
737 if (m_ControlEventsInQueue > 0) 734 m_CurrentWorkItem = null;
738 m_ControlEventsInQueue--;
739 } 735 }
740 if (data.EventName == "collision") 736 return 0;
741 m_CollisionInQueue = false;
742 } 737 }
743 738
739 if (data.EventName == "timer")
740 m_TimerQueued = false;
741 if (data.EventName == "control")
742 {
743 if (m_ControlEventsInQueue > 0)
744 m_ControlEventsInQueue--;
745 }
746 if (data.EventName == "collision")
747 m_CollisionInQueue = false;
748 }
749
750 lock(m_Script)
751 {
752
753// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
754 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
755
744 if (DebugLevel >= 2) 756 if (DebugLevel >= 2)
745 m_log.DebugFormat( 757 m_log.DebugFormat(
746 "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", 758 "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}",
747 data.EventName, 759 data.EventName,
748 ScriptName, 760 ScriptName,
749 Part.Name, 761 part.Name,
750 Part.LocalId, 762 part.LocalId,
751 Part.ParentGroup.Name, 763 part.ParentGroup.Name,
752 Part.ParentGroup.UUID, 764 part.ParentGroup.UUID,
753 Part.AbsolutePosition, 765 part.AbsolutePosition,
754 Part.ParentGroup.Scene.Name); 766 part.ParentGroup.Scene.Name);
755 767
756 m_DetectParams = data.DetectParams; 768 m_DetectParams = data.DetectParams;
757 769
@@ -764,17 +776,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
764 "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", 776 "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}",
765 State, 777 State,
766 ScriptName, 778 ScriptName,
767 Part.Name, 779 part.Name,
768 Part.LocalId, 780 part.LocalId,
769 Part.ParentGroup.Name, 781 part.ParentGroup.Name,
770 Part.ParentGroup.UUID, 782 part.ParentGroup.UUID,
771 Part.AbsolutePosition, 783 part.AbsolutePosition,
772 Part.ParentGroup.Scene.Name); 784 part.ParentGroup.Scene.Name);
773 785
774 AsyncCommandManager.RemoveScript(Engine, 786 AsyncCommandManager.RemoveScript(Engine,
775 LocalID, ItemID); 787 LocalID, ItemID);
776 788
777 Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); 789 if (part != null)
790 {
791 part.SetScriptEvents(ItemID,
792 (int)m_Script.GetStateEventFlags(State));
793 }
778 } 794 }
779 else 795 else
780 { 796 {
@@ -837,17 +853,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
837 text = text.Substring(0, 1000); 853 text = text.Substring(0, 1000);
838 Engine.World.SimChat(Utils.StringToBytes(text), 854 Engine.World.SimChat(Utils.StringToBytes(text),
839 ChatTypeEnum.DebugChannel, 2147483647, 855 ChatTypeEnum.DebugChannel, 2147483647,
840 Part.AbsolutePosition, 856 part.AbsolutePosition,
841 Part.Name, Part.UUID, false); 857 part.Name, part.UUID, false);
842 858
843 859
844 m_log.DebugFormat( 860 m_log.DebugFormat(
845 "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", 861 "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}",
846 ScriptName, 862 ScriptName,
847 PrimName, 863 PrimName,
848 Part.UUID, 864 part.UUID,
849 Part.AbsolutePosition, 865 part.AbsolutePosition,
850 Part.ParentGroup.Scene.Name, 866 part.ParentGroup.Scene.Name,
851 text.Replace("\n", "\\n"), 867 text.Replace("\n", "\\n"),
852 e.InnerException); 868 e.InnerException);
853 } 869 }
@@ -867,12 +883,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
867 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) 883 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
868 { 884 {
869 m_InSelfDelete = true; 885 m_InSelfDelete = true;
870 Engine.World.DeleteSceneObject(Part.ParentGroup, false); 886 if (part != null)
887 Engine.World.DeleteSceneObject(part.ParentGroup, false);
871 } 888 }
872 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) 889 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
873 { 890 {
874 m_InSelfDelete = true; 891 m_InSelfDelete = true;
875 Part.Inventory.RemoveInventoryItem(ItemID); 892 if (part != null)
893 part.Inventory.RemoveInventoryItem(ItemID);
876 } 894 }
877 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) 895 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException))
878 { 896 {
@@ -925,14 +943,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
925 ReleaseControls(); 943 ReleaseControls();
926 944
927 Stop(timeout); 945 Stop(timeout);
928 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 946 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
929 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 947 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
948 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
949 part.CollisionSound = UUID.Zero;
930 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 950 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
931 EventQueue.Clear(); 951 EventQueue.Clear();
932 m_Script.ResetVars(); 952 m_Script.ResetVars();
933 State = "default"; 953 State = "default";
934 954
935 Part.SetScriptEvents(ItemID, 955 part.SetScriptEvents(ItemID,
936 (int)m_Script.GetStateEventFlags(State)); 956 (int)m_Script.GetStateEventFlags(State));
937 if (running) 957 if (running)
938 Start(); 958 Start();
@@ -941,6 +961,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
941 new Object[0], new DetectParams[0])); 961 new Object[0], new DetectParams[0]));
942 } 962 }
943 963
964 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
944 public void ApiResetScript() 965 public void ApiResetScript()
945 { 966 {
946 // bool running = Running; 967 // bool running = Running;
@@ -949,15 +970,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
949 ReleaseControls(); 970 ReleaseControls();
950 971
951 m_Script.ResetVars(); 972 m_Script.ResetVars();
952 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 973 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
953 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 974 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
975 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
976 part.CollisionSound = UUID.Zero;
954 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 977 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
955 978
956 EventQueue.Clear(); 979 EventQueue.Clear();
957 m_Script.ResetVars(); 980 m_Script.ResetVars();
958 State = "default"; 981 State = "default";
959 982
960 Part.SetScriptEvents(ItemID, 983 part.SetScriptEvents(ItemID,
961 (int)m_Script.GetStateEventFlags(State)); 984 (int)m_Script.GetStateEventFlags(State));
962 985
963 if (m_CurrentEvent != "state_entry") 986 if (m_CurrentEvent != "state_entry")
@@ -971,10 +994,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
971 994
972 public Dictionary<string, object> GetVars() 995 public Dictionary<string, object> GetVars()
973 { 996 {
974 if (m_Script != null) 997 return m_Script.GetVars();
975 return m_Script.GetVars();
976 else
977 return new Dictionary<string, object>();
978 } 998 }
979 999
980 public void SetVars(Dictionary<string, object> vars) 1000 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 44fdd1a..2e61fb8 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)
@@ -711,24 +713,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
711 713
712 public static bool operator ==(list a, list b) 714 public static bool operator ==(list a, list b)
713 { 715 {
714 int la = -1; 716 int la = a.Length;
715 int lb = -1; 717 int lb = b.Length;
716 try { la = a.Length; }
717 catch (NullReferenceException) { }
718 try { lb = b.Length; }
719 catch (NullReferenceException) { }
720 718
721 return la == lb; 719 return la == lb;
722 } 720 }
723 721
724 public static bool operator !=(list a, list b) 722 public static bool operator !=(list a, list b)
725 { 723 {
726 int la = -1; 724 int la = a.Length;
727 int lb = -1; 725 int lb = b.Length;
728 try { la = a.Length; }
729 catch (NullReferenceException) { }
730 try {lb = b.Length;}
731 catch (NullReferenceException) { }
732 726
733 return la != lb; 727 return la != lb;
734 } 728 }
@@ -962,7 +956,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
962 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 956 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
963 } 957 }
964 958
965 if (ascending == 0) 959 if (ascending != 1)
966 { 960 {
967 ret = 0 - ret; 961 ret = 0 - ret;
968 } 962 }
@@ -995,6 +989,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
995 stride = 1; 989 stride = 1;
996 } 990 }
997 991
992 if ((Data.Length % stride) != 0)
993 return new list(ret);
994
998 // we can optimize here in the case where stride == 1 and the list 995 // we can optimize here in the case where stride == 1 and the list
999 // consists of homogeneous types 996 // consists of homogeneous types
1000 997
@@ -1014,7 +1011,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1014 if (homogeneous) 1011 if (homogeneous)
1015 { 1012 {
1016 Array.Sort(ret, new HomogeneousComparer()); 1013 Array.Sort(ret, new HomogeneousComparer());
1017 if (ascending == 0) 1014 if (ascending != 1)
1018 { 1015 {
1019 Array.Reverse(ret); 1016 Array.Reverse(ret);
1020 } 1017 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index a17a018..2065a46 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.Linq; 34using System.Linq;
@@ -147,6 +148,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
147 private Dictionary<UUID, IScriptInstance> m_Scripts = 148 private Dictionary<UUID, IScriptInstance> m_Scripts =
148 new Dictionary<UUID, IScriptInstance>(); 149 new Dictionary<UUID, IScriptInstance>();
149 150
151 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
152
150 // Maps the asset ID to the assembly 153 // Maps the asset ID to the assembly
151 154
152 private Dictionary<UUID, string> m_Assemblies = 155 private Dictionary<UUID, string> m_Assemblies =
@@ -169,6 +172,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
169 IWorkItemResult m_CurrentCompile = null; 172 IWorkItemResult m_CurrentCompile = null;
170 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 173 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
171 174
175 private void lockScriptsForRead(bool locked)
176 {
177 if (locked)
178 {
179 if (m_scriptsLock.RecursiveReadCount > 0)
180 {
181 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.");
182 m_scriptsLock.ExitReadLock();
183 }
184 if (m_scriptsLock.RecursiveWriteCount > 0)
185 {
186 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
187 m_scriptsLock.ExitWriteLock();
188 }
189
190 while (!m_scriptsLock.TryEnterReadLock(60000))
191 {
192 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.");
193 if (m_scriptsLock.IsWriteLockHeld)
194 {
195 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
196 }
197 }
198 }
199 else
200 {
201 if (m_scriptsLock.RecursiveReadCount > 0)
202 {
203 m_scriptsLock.ExitReadLock();
204 }
205 }
206 }
207 private void lockScriptsForWrite(bool locked)
208 {
209 if (locked)
210 {
211 if (m_scriptsLock.RecursiveReadCount > 0)
212 {
213 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.");
214 m_scriptsLock.ExitReadLock();
215 }
216 if (m_scriptsLock.RecursiveWriteCount > 0)
217 {
218 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
219 m_scriptsLock.ExitWriteLock();
220 }
221
222 while (!m_scriptsLock.TryEnterWriteLock(60000))
223 {
224 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.");
225 if (m_scriptsLock.IsWriteLockHeld)
226 {
227 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
228 }
229 }
230 }
231 else
232 {
233 if (m_scriptsLock.RecursiveWriteCount > 0)
234 {
235 m_scriptsLock.ExitWriteLock();
236 }
237 }
238 }
239
172 private ScriptEngineConsoleCommands m_consoleCommands; 240 private ScriptEngineConsoleCommands m_consoleCommands;
173 241
174 public string ScriptEngineName 242 public string ScriptEngineName
@@ -677,64 +745,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine
677 { 745 {
678 if (!m_Enabled) 746 if (!m_Enabled)
679 return; 747 return;
748 lockScriptsForRead(true);
680 749
681 lock (m_Scripts) 750 List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values);
682 {
683 m_log.InfoFormat(
684 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName);
685 751
686 foreach (IScriptInstance instance in m_Scripts.Values) 752// foreach (IScriptInstance instance in m_Scripts.Values)
753 foreach (IScriptInstance instance in instancesToDel)
754 {
755 // Force a final state save
756 //
757 if (m_Assemblies.ContainsKey(instance.AssetID))
687 { 758 {
688 // Force a final state save 759 string assembly = m_Assemblies[instance.AssetID];
689 //
690 if (m_Assemblies.ContainsKey(instance.AssetID))
691 {
692 string assembly = m_Assemblies[instance.AssetID];
693 760
694 try 761 try
695 { 762 {
696 instance.SaveState(assembly); 763 instance.SaveState(assembly);
697 }
698 catch (Exception e)
699 {
700 m_log.Error(
701 string.Format(
702 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
703 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
704 , e);
705 }
706 } 764 }
765 catch (Exception e)
766 {
767 m_log.Error(
768 string.Format(
769 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
770 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
771 , e);
772 }
773 }
707 774
708 // Clear the event queue and abort the instance thread 775 // Clear the event queue and abort the instance thread
709 // 776 //
710 instance.ClearQueue(); 777 instance.ClearQueue();
711 instance.Stop(0); 778 instance.Stop(0);
712 779
713 // Release events, timer, etc 780 // Release events, timer, etc
714 // 781 //
715 instance.DestroyScriptInstance(); 782 instance.DestroyScriptInstance();
716 783
717 // Unload scripts and app domains. 784 // Unload scripts and app domains
718 // Must be done explicitly because they have infinite 785 // Must be done explicitly because they have infinite
719 // lifetime. 786 // lifetime
720 // However, don't bother to do this if the simulator is shutting 787 //
721 // down since it takes a long time with many scripts. 788// if (!m_SimulatorShuttingDown)
722 if (!m_SimulatorShuttingDown) 789 {
790 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
791 if (m_DomainScripts[instance.AppDomain].Count == 0)
723 { 792 {
724 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 793 m_DomainScripts.Remove(instance.AppDomain);
725 if (m_DomainScripts[instance.AppDomain].Count == 0) 794 UnloadAppDomain(instance.AppDomain);
726 {
727 m_DomainScripts.Remove(instance.AppDomain);
728 UnloadAppDomain(instance.AppDomain);
729 }
730 } 795 }
731 } 796 }
732 797
733 m_Scripts.Clear(); 798// m_Scripts.Clear();
734 m_PrimObjects.Clear(); 799// m_PrimObjects.Clear();
735 m_Assemblies.Clear(); 800// m_Assemblies.Clear();
736 m_DomainScripts.Clear(); 801// m_DomainScripts.Clear();
737 } 802 }
803 lockScriptsForRead(false);
804 lockScriptsForWrite(true);
805 m_Scripts.Clear();
806 lockScriptsForWrite(false);
807 m_PrimObjects.Clear();
808 m_Assemblies.Clear();
809 m_DomainScripts.Clear();
810
738 lock (m_ScriptEngines) 811 lock (m_ScriptEngines)
739 { 812 {
740 m_ScriptEngines.Remove(this); 813 m_ScriptEngines.Remove(this);
@@ -803,22 +876,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
803 876
804 List<IScriptInstance> instances = new List<IScriptInstance>(); 877 List<IScriptInstance> instances = new List<IScriptInstance>();
805 878
806 lock (m_Scripts) 879 lockScriptsForRead(true);
807 { 880 foreach (IScriptInstance instance in m_Scripts.Values)
808 foreach (IScriptInstance instance in m_Scripts.Values)
809 instances.Add(instance); 881 instances.Add(instance);
810 } 882 lockScriptsForRead(false);
811 883
812 foreach (IScriptInstance i in instances) 884 foreach (IScriptInstance i in instances)
813 { 885 {
814 string assembly = String.Empty; 886 string assembly = String.Empty;
815 887
816 lock (m_Scripts) 888
817 {
818 if (!m_Assemblies.ContainsKey(i.AssetID)) 889 if (!m_Assemblies.ContainsKey(i.AssetID))
819 continue; 890 continue;
820 assembly = m_Assemblies[i.AssetID]; 891 assembly = m_Assemblies[i.AssetID];
821 } 892
822 893
823 try 894 try
824 { 895 {
@@ -1219,96 +1290,98 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1219 } 1290 }
1220 1291
1221 ScriptInstance instance = null; 1292 ScriptInstance instance = null;
1222 lock (m_Scripts) 1293 // Create the object record
1294 lockScriptsForRead(true);
1295 if ((!m_Scripts.ContainsKey(itemID)) ||
1296 (m_Scripts[itemID].AssetID != assetID))
1223 { 1297 {
1224 // Create the object record 1298 lockScriptsForRead(false);
1225 if ((!m_Scripts.ContainsKey(itemID)) ||
1226 (m_Scripts[itemID].AssetID != assetID))
1227 {
1228 UUID appDomain = assetID;
1229 1299
1230 if (part.ParentGroup.IsAttachment) 1300 UUID appDomain = assetID;
1231 appDomain = part.ParentGroup.RootPart.UUID;
1232 1301
1233 if (!m_AppDomains.ContainsKey(appDomain)) 1302 if (part.ParentGroup.IsAttachment)
1234 { 1303 appDomain = part.ParentGroup.RootPart.UUID;
1235 try
1236 {
1237 AppDomainSetup appSetup = new AppDomainSetup();
1238 appSetup.PrivateBinPath = Path.Combine(
1239 m_ScriptEnginesPath,
1240 m_Scene.RegionInfo.RegionID.ToString());
1241 1304
1242 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1305 if (!m_AppDomains.ContainsKey(appDomain))
1243 Evidence evidence = new Evidence(baseEvidence); 1306 {
1307 try
1308 {
1309 AppDomainSetup appSetup = new AppDomainSetup();
1310 appSetup.PrivateBinPath = Path.Combine(
1311 m_ScriptEnginesPath,
1312 m_Scene.RegionInfo.RegionID.ToString());
1244 1313
1245 AppDomain sandbox; 1314 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1246 if (m_AppDomainLoading) 1315 Evidence evidence = new Evidence(baseEvidence);
1247 {
1248 sandbox = AppDomain.CreateDomain(
1249 m_Scene.RegionInfo.RegionID.ToString(),
1250 evidence, appSetup);
1251 sandbox.AssemblyResolve +=
1252 new ResolveEventHandler(
1253 AssemblyResolver.OnAssemblyResolve);
1254 }
1255 else
1256 {
1257 sandbox = AppDomain.CurrentDomain;
1258 }
1259
1260 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1261 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1262 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1263 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1264 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1265 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1266 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1267
1268 m_AppDomains[appDomain] = sandbox;
1269 1316
1270 m_DomainScripts[appDomain] = new List<UUID>(); 1317 AppDomain sandbox;
1318 if (m_AppDomainLoading)
1319 {
1320 sandbox = AppDomain.CreateDomain(
1321 m_Scene.RegionInfo.RegionID.ToString(),
1322 evidence, appSetup);
1323 m_AppDomains[appDomain].AssemblyResolve +=
1324 new ResolveEventHandler(
1325 AssemblyResolver.OnAssemblyResolve);
1271 } 1326 }
1272 catch (Exception e) 1327 else
1273 { 1328 {
1274 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1329 sandbox = AppDomain.CurrentDomain;
1275 m_ScriptErrorMessage += "Exception creating app domain:\n";
1276 m_ScriptFailCount++;
1277 lock (m_AddingAssemblies)
1278 {
1279 m_AddingAssemblies[assembly]--;
1280 }
1281 return false;
1282 } 1330 }
1283 }
1284 m_DomainScripts[appDomain].Add(itemID);
1285
1286 instance = new ScriptInstance(this, part,
1287 item,
1288 startParam, postOnRez,
1289 m_MaxScriptQueue);
1290 1331
1291 instance.Load(m_AppDomains[appDomain], assembly, stateSource); 1332 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1333 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1334 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1335 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1336 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1337 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1338 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1292 1339
1293// if (DebugLevel >= 1) 1340 m_AppDomains[appDomain] = sandbox;
1294// m_log.DebugFormat(
1295// "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1296// part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1297// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1298 1341
1299 if (presence != null) 1342 m_DomainScripts[appDomain] = new List<UUID>();
1343 }
1344 catch (Exception e)
1300 { 1345 {
1301 ShowScriptSaveResponse(item.OwnerID, 1346 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1302 assetID, "Compile successful", true); 1347 m_ScriptErrorMessage += "Exception creating app domain:\n";
1348 m_ScriptFailCount++;
1349 lock (m_AddingAssemblies)
1350 {
1351 m_AddingAssemblies[assembly]--;
1352 }
1353 return false;
1303 } 1354 }
1355 }
1356 m_DomainScripts[appDomain].Add(itemID);
1357
1358 instance = new ScriptInstance(this, part,
1359 item,
1360 startParam, postOnRez,
1361 m_MaxScriptQueue);
1304 1362
1305 instance.AppDomain = appDomain; 1363 instance.Load(m_AppDomains[appDomain], assembly, stateSource);
1306 instance.LineMap = linemap; 1364// m_log.DebugFormat(
1365// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1366// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1367// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1307 1368
1308 m_Scripts[itemID] = instance; 1369 if (presence != null)
1370 {
1371 ShowScriptSaveResponse(item.OwnerID,
1372 assetID, "Compile successful", true);
1309 } 1373 }
1310 }
1311 1374
1375 instance.AppDomain = appDomain;
1376 instance.LineMap = linemap;
1377 lockScriptsForWrite(true);
1378 m_Scripts[itemID] = instance;
1379 lockScriptsForWrite(false);
1380 }
1381 else
1382 {
1383 lockScriptsForRead(false);
1384 }
1312 lock (m_PrimObjects) 1385 lock (m_PrimObjects)
1313 { 1386 {
1314 if (!m_PrimObjects.ContainsKey(localID)) 1387 if (!m_PrimObjects.ContainsKey(localID))
@@ -1326,7 +1399,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1326 m_AddingAssemblies[assembly]--; 1399 m_AddingAssemblies[assembly]--;
1327 } 1400 }
1328 1401
1329 if (instance != null) 1402 if (instance!=null)
1330 instance.Init(); 1403 instance.Init();
1331 1404
1332 bool runIt; 1405 bool runIt;
@@ -1349,18 +1422,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1349 m_CompileDict.Remove(itemID); 1422 m_CompileDict.Remove(itemID);
1350 } 1423 }
1351 1424
1352 IScriptInstance instance = null; 1425 lockScriptsForRead(true);
1353 1426 // Do we even have it?
1354 lock (m_Scripts) 1427 if (!m_Scripts.ContainsKey(itemID))
1355 { 1428 {
1356 // Do we even have it? 1429 // Do we even have it?
1357 if (!m_Scripts.ContainsKey(itemID)) 1430 if (!m_Scripts.ContainsKey(itemID))
1358 return; 1431 return;
1359 1432
1360 instance = m_Scripts[itemID]; 1433 lockScriptsForRead(false);
1434 lockScriptsForWrite(true);
1361 m_Scripts.Remove(itemID); 1435 m_Scripts.Remove(itemID);
1436 lockScriptsForWrite(false);
1437
1438 return;
1362 } 1439 }
1440
1363 1441
1442 IScriptInstance instance=m_Scripts[itemID];
1443 lockScriptsForRead(false);
1444 lockScriptsForWrite(true);
1445 m_Scripts.Remove(itemID);
1446 lockScriptsForWrite(false);
1364 instance.ClearQueue(); 1447 instance.ClearQueue();
1365 1448
1366 instance.Stop(m_WaitForEventCompletionOnScriptStop); 1449 instance.Stop(m_WaitForEventCompletionOnScriptStop);
@@ -1397,8 +1480,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1397 1480
1398 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1481 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1399 if (handlerObjectRemoved != null) 1482 if (handlerObjectRemoved != null)
1400 handlerObjectRemoved(instance.ObjectID); 1483 {
1484 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1485 handlerObjectRemoved(part.UUID);
1486 }
1401 1487
1488 CleanAssemblies();
1489
1402 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1490 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1403 if (handlerScriptRemoved != null) 1491 if (handlerScriptRemoved != null)
1404 handlerScriptRemoved(itemID); 1492 handlerScriptRemoved(itemID);
@@ -1659,12 +1747,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1659 private IScriptInstance GetInstance(UUID itemID) 1747 private IScriptInstance GetInstance(UUID itemID)
1660 { 1748 {
1661 IScriptInstance instance; 1749 IScriptInstance instance;
1662 lock (m_Scripts) 1750 lockScriptsForRead(true);
1751 if (!m_Scripts.ContainsKey(itemID))
1663 { 1752 {
1664 if (!m_Scripts.ContainsKey(itemID)) 1753 lockScriptsForRead(false);
1665 return null; 1754 return null;
1666 instance = m_Scripts[itemID];
1667 } 1755 }
1756 instance = m_Scripts[itemID];
1757 lockScriptsForRead(false);
1668 return instance; 1758 return instance;
1669 } 1759 }
1670 1760
@@ -1688,6 +1778,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1688 return false; 1778 return false;
1689 } 1779 }
1690 1780
1781 [DebuggerNonUserCode]
1691 public void ApiResetScript(UUID itemID) 1782 public void ApiResetScript(UUID itemID)
1692 { 1783 {
1693 IScriptInstance instance = GetInstance(itemID); 1784 IScriptInstance instance = GetInstance(itemID);
@@ -1749,6 +1840,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1749 return UUID.Zero; 1840 return UUID.Zero;
1750 } 1841 }
1751 1842
1843 [DebuggerNonUserCode]
1752 public void SetState(UUID itemID, string newState) 1844 public void SetState(UUID itemID, string newState)
1753 { 1845 {
1754 IScriptInstance instance = GetInstance(itemID); 1846 IScriptInstance instance = GetInstance(itemID);
@@ -1771,11 +1863,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1771 1863
1772 List<IScriptInstance> instances = new List<IScriptInstance>(); 1864 List<IScriptInstance> instances = new List<IScriptInstance>();
1773 1865
1774 lock (m_Scripts) 1866 lockScriptsForRead(true);
1775 { 1867 foreach (IScriptInstance instance in m_Scripts.Values)
1776 foreach (IScriptInstance instance in m_Scripts.Values)
1777 instances.Add(instance); 1868 instances.Add(instance);
1778 } 1869 lockScriptsForRead(false);
1779 1870
1780 foreach (IScriptInstance i in instances) 1871 foreach (IScriptInstance i in instances)
1781 { 1872 {