aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs23
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs117
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3311
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs162
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs18
-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.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs3
-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.cs22
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs55
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs5
-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.cs39
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs363
21 files changed, 3260 insertions, 1268 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..fce8ff8
--- /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, WaitHandle 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 bf3d8ab..f677cdf 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.Framework.Scenes.Scripting; 51using OpenSim.Region.Framework.Scenes.Scripting;
49using OpenSim.Region.Physics.Manager; 52using OpenSim.Region.Physics.Manager;
@@ -67,6 +70,8 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
67using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 70using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
68using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 71using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
69using System.Reflection; 72using System.Reflection;
73using Timer = System.Timers.Timer;
74using PermissionMask = OpenSim.Framework.PermissionMask;
70 75
71namespace OpenSim.Region.ScriptEngine.Shared.Api 76namespace OpenSim.Region.ScriptEngine.Shared.Api
72{ 77{
@@ -113,17 +118,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
113 protected int m_notecardLineReadCharsMax = 255; 118 protected int m_notecardLineReadCharsMax = 255;
114 protected int m_scriptConsoleChannel = 0; 119 protected int m_scriptConsoleChannel = 0;
115 protected bool m_scriptConsoleChannelEnabled = false; 120 protected bool m_scriptConsoleChannelEnabled = false;
121 protected bool m_debuggerSafe = false;
116 protected IUrlModule m_UrlModule = null; 122 protected IUrlModule m_UrlModule = null;
117 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 123 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
118 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 124 new Dictionary<UUID, UserInfoCacheEntry>();
125 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
119 protected ISoundModule m_SoundModule = null; 126 protected ISoundModule m_SoundModule = null;
120 127
128// protected Timer m_ShoutSayTimer;
129 protected int m_SayShoutCount = 0;
130 DateTime m_lastSayShoutCheck;
131
132 private Dictionary<string, string> MovementAnimationsForLSL =
133 new Dictionary<string, string> {
134 {"FLY", "Flying"},
135 {"FLYSLOW", "FlyingSlow"},
136 {"HOVER_UP", "Hovering Up"},
137 {"HOVER_DOWN", "Hovering Down"},
138 {"HOVER", "Hovering"},
139 {"LAND", "Landing"},
140 {"FALLDOWN", "Falling Down"},
141 {"PREJUMP", "PreJumping"},
142 {"JUMP", "Jumping"},
143 {"STANDUP", "Standing Up"},
144 {"SOFT_LAND", "Soft Landing"},
145 {"STAND", "Standing"},
146 {"CROUCHWALK", "CrouchWalking"},
147 {"RUN", "Running"},
148 {"WALK", "Walking"},
149 {"CROUCH", "Crouching"},
150 {"TURNLEFT", "Turning Left"},
151 {"TURNRIGHT", "Turning Right"}
152 };
153
121 public void Initialize( 154 public void Initialize(
122 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) 155 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
123 { 156 {
157 m_lastSayShoutCheck = DateTime.UtcNow;
158
124 m_ScriptEngine = scriptEngine; 159 m_ScriptEngine = scriptEngine;
125 m_host = host; 160 m_host = host;
126 m_item = item; 161 m_item = item;
162 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
127 m_coopSleepHandle = coopSleepHandle; 163 m_coopSleepHandle = coopSleepHandle;
128 164
129 LoadConfig(); 165 LoadConfig();
@@ -212,6 +248,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
212 get { return m_ScriptEngine.World; } 248 get { return m_ScriptEngine.World; }
213 } 249 }
214 250
251 [DebuggerNonUserCode]
215 public void state(string newState) 252 public void state(string newState)
216 { 253 {
217 m_ScriptEngine.SetState(m_item.ItemID, newState); 254 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -221,6 +258,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
221 /// Reset the named script. The script must be present 258 /// Reset the named script. The script must be present
222 /// in the same prim. 259 /// in the same prim.
223 /// </summary> 260 /// </summary>
261 [DebuggerNonUserCode]
224 public void llResetScript() 262 public void llResetScript()
225 { 263 {
226 m_host.AddScriptLPS(1); 264 m_host.AddScriptLPS(1);
@@ -283,6 +321,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
283 } 321 }
284 } 322 }
285 323
324 public List<ScenePresence> GetLinkAvatars(int linkType)
325 {
326 List<ScenePresence> ret = new List<ScenePresence>();
327 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
328 return ret;
329
330 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
331
332 switch (linkType)
333 {
334 case ScriptBaseClass.LINK_SET:
335 return avs;
336
337 case ScriptBaseClass.LINK_ROOT:
338 return ret;
339
340 case ScriptBaseClass.LINK_ALL_OTHERS:
341 return avs;
342
343 case ScriptBaseClass.LINK_ALL_CHILDREN:
344 return avs;
345
346 case ScriptBaseClass.LINK_THIS:
347 return ret;
348
349 default:
350 if (linkType < 0)
351 return ret;
352
353 int partCount = m_host.ParentGroup.GetPartCount();
354
355 if (linkType <= partCount)
356 {
357 return ret;
358 }
359 else
360 {
361 linkType = linkType - partCount;
362 if (linkType > avs.Count)
363 {
364 return ret;
365 }
366 else
367 {
368 ret.Add(avs[linkType-1]);
369 return ret;
370 }
371 }
372 }
373 }
374
286 /// <summary> 375 /// <summary>
287 /// Get a given link entity from a linkset (linked objects and any sitting avatars). 376 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
288 /// </summary> 377 /// </summary>
@@ -365,6 +454,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
365 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 454 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
366 { 455 {
367 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 456 List<SceneObjectPart> ret = new List<SceneObjectPart>();
457 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
458 return ret;
368 ret.Add(part); 459 ret.Add(part);
369 460
370 switch (linkType) 461 switch (linkType)
@@ -518,31 +609,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
518 609
519 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 610 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
520 611
521 /// <summary> 612 // Utility function for llRot2Euler
522 /// Convert an LSL rotation to a Euler vector. 613
523 /// </summary> 614 // normalize an angle between -PI and PI (-180 to +180 degrees)
524 /// <remarks> 615 protected double NormalizeAngle(double angle)
525 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
526 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
527 /// </remarks>
528 /// <param name="r"></param>
529 /// <returns></returns>
530 public LSL_Vector llRot2Euler(LSL_Rotation r)
531 { 616 {
532 m_host.AddScriptLPS(1); 617 if (angle > -Math.PI && angle < Math.PI)
618 return angle;
533 619
534 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 620 int numPis = (int)(Math.PI / angle);
535 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 621 double remainder = angle - Math.PI * numPis;
536 if (m == 0.0) return new LSL_Vector(); 622 if (numPis % 2 == 1)
537 double x = Math.Atan2(-v.y, v.z); 623 return Math.PI - angle;
538 double sin = v.x / m; 624 return remainder;
539 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 625 }
540 double y = Math.Asin(sin); 626
541 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation 627 public LSL_Vector llRot2Euler(LSL_Rotation q1)
542 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))); 628 {
543 double z = Math.Atan2(v.y, v.x); 629 m_host.AddScriptLPS(1);
630 LSL_Vector eul = new LSL_Vector();
544 631
545 return new LSL_Vector(x, y, z); 632 double sqw = q1.s*q1.s;
633 double sqx = q1.x*q1.x;
634 double sqy = q1.z*q1.z;
635 double sqz = q1.y*q1.y;
636 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
637 double test = q1.x*q1.z + q1.y*q1.s;
638 if (test > 0.4999*unit) { // singularity at north pole
639 eul.z = 2 * Math.Atan2(q1.x,q1.s);
640 eul.y = Math.PI/2;
641 eul.x = 0;
642 return eul;
643 }
644 if (test < -0.4999*unit) { // singularity at south pole
645 eul.z = -2 * Math.Atan2(q1.x,q1.s);
646 eul.y = -Math.PI/2;
647 eul.x = 0;
648 return eul;
649 }
650 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
651 eul.y = Math.Asin(2*test/unit);
652 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
653 return eul;
546 } 654 }
547 655
548 /* From wiki: 656 /* From wiki:
@@ -595,18 +703,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
595 m_host.AddScriptLPS(1); 703 m_host.AddScriptLPS(1);
596 704
597 double x,y,z,s; 705 double x,y,z,s;
598 706 v.x *= 0.5;
599 double c1 = Math.Cos(v.x * 0.5); 707 v.y *= 0.5;
600 double c2 = Math.Cos(v.y * 0.5); 708 v.z *= 0.5;
601 double c3 = Math.Cos(v.z * 0.5); 709 double c1 = Math.Cos(v.x);
602 double s1 = Math.Sin(v.x * 0.5); 710 double c2 = Math.Cos(v.y);
603 double s2 = Math.Sin(v.y * 0.5); 711 double c1c2 = c1 * c2;
604 double s3 = Math.Sin(v.z * 0.5); 712 double s1 = Math.Sin(v.x);
605 713 double s2 = Math.Sin(v.y);
606 x = s1 * c2 * c3 + c1 * s2 * s3; 714 double s1s2 = s1 * s2;
607 y = c1 * s2 * c3 - s1 * c2 * s3; 715 double c1s2 = c1 * s2;
608 z = s1 * s2 * c3 + c1 * c2 * s3; 716 double s1c2 = s1 * c2;
609 s = c1 * c2 * c3 - s1 * s2 * s3; 717 double c3 = Math.Cos(v.z);
718 double s3 = Math.Sin(v.z);
719
720 x = s1c2 * c3 + c1s2 * s3;
721 y = c1s2 * c3 - s1c2 * s3;
722 z = s1s2 * c3 + c1c2 * s3;
723 s = c1c2 * c3 - s1s2 * s3;
610 724
611 return new LSL_Rotation(x, y, z, s); 725 return new LSL_Rotation(x, y, z, s);
612 } 726 }
@@ -744,77 +858,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
744 { 858 {
745 //A and B should both be normalized 859 //A and B should both be normalized
746 m_host.AddScriptLPS(1); 860 m_host.AddScriptLPS(1);
747 LSL_Rotation rotBetween; 861 /* This method is more accurate than the SL one, and thus causes problems
748 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 862 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
749 // continue calculation. 863
750 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 864 double dotProduct = LSL_Vector.Dot(a, b);
865 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
866 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
867 double angle = Math.Acos(dotProduct / magProduct);
868 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
869 double s = Math.Sin(angle / 2);
870
871 double x = axis.x * s;
872 double y = axis.y * s;
873 double z = axis.z * s;
874 double w = Math.Cos(angle / 2);
875
876 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
877 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
878
879 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
880 */
881
882 // This method mimics the 180 errors found in SL
883 // See www.euclideanspace.com... angleBetween
884 LSL_Vector vec_a = a;
885 LSL_Vector vec_b = b;
886
887 // Eliminate zero length
888 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
889 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
890 if (vec_a_mag < 0.00001 ||
891 vec_b_mag < 0.00001)
751 { 892 {
752 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 893 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
753 } 894 }
754 else 895
896 // Normalize
897 vec_a = llVecNorm(vec_a);
898 vec_b = llVecNorm(vec_b);
899
900 // Calculate axis and rotation angle
901 LSL_Vector axis = vec_a % vec_b;
902 LSL_Float cos_theta = vec_a * vec_b;
903
904 // Check if parallel
905 if (cos_theta > 0.99999)
755 { 906 {
756 a = LSL_Vector.Norm(a); 907 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
757 b = LSL_Vector.Norm(b); 908 }
758 double dotProduct = LSL_Vector.Dot(a, b); 909
759 // There are two degenerate cases possible. These are for vectors 180 or 910 // Check if anti-parallel
760 // 0 degrees apart. These have to be detected and handled individually. 911 else if (cos_theta < -0.99999)
761 // 912 {
762 // Check for vectors 180 degrees apart. 913 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
763 // A dot product of -1 would mean the angle between vectors is 180 degrees. 914 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
764 if (dotProduct < -0.9999999f) 915 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
765 { 916 }
766 // First assume X axis is orthogonal to the vectors. 917 else // other rotation
767 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 918 {
768 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 919 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
769 // Check for near zero vector. A very small non-zero number here will create 920 axis = llVecNorm(axis);
770 // a rotation in an undesired direction. 921 double x, y, z, s, t;
771 if (LSL_Vector.Mag(orthoVector) > 0.0001) 922 s = Math.Cos(theta);
772 { 923 t = Math.Sin(theta);
773 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 924 x = axis.x * t;
774 } 925 y = axis.y * t;
775 // If the magnitude of the vector was near zero, then assume the X axis is not 926 z = axis.z * t;
776 // orthogonal and use the Z axis instead. 927 return new LSL_Rotation(x,y,z,s);
777 else
778 {
779 // Set 180 z rotation.
780 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
781 }
782 }
783 // Check for parallel vectors.
784 // A dot product of 1 would mean the angle between vectors is 0 degrees.
785 else if (dotProduct > 0.9999999f)
786 {
787 // Set zero rotation.
788 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
789 }
790 else
791 {
792 // All special checks have been performed so get the axis of rotation.
793 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
794 // Quarternion s value is the length of the unit vector + dot product.
795 double qs = 1.0 + dotProduct;
796 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
797 // Normalize the rotation.
798 double mag = LSL_Rotation.Mag(rotBetween);
799 // We shouldn't have to worry about a divide by zero here. The qs value will be
800 // non-zero because we already know if we're here, then the dotProduct is not -1 so
801 // qs will not be zero. Also, we've already handled the input vectors being zero so the
802 // crossProduct vector should also not be zero.
803 rotBetween.x = rotBetween.x / mag;
804 rotBetween.y = rotBetween.y / mag;
805 rotBetween.z = rotBetween.z / mag;
806 rotBetween.s = rotBetween.s / mag;
807 // Check for undefined values and set zero rotation if any found. This code might not actually be required
808 // any longer since zero vectors are checked for at the top.
809 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
810 {
811 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
812 }
813 }
814 } 928 }
815 return rotBetween;
816 } 929 }
817 930
818 public void llWhisper(int channelID, string text) 931 public void llWhisper(int channelID, string text)
819 { 932 {
820 m_host.AddScriptLPS(1); 933 m_host.AddScriptLPS(1);
@@ -830,10 +943,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
830 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 943 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
831 } 944 }
832 945
946 private void CheckSayShoutTime()
947 {
948 DateTime now = DateTime.UtcNow;
949 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
950 {
951 m_lastSayShoutCheck = now;
952 m_SayShoutCount = 0;
953 }
954 else
955 m_SayShoutCount++;
956 }
957
833 public void llSay(int channelID, string text) 958 public void llSay(int channelID, string text)
834 { 959 {
835 m_host.AddScriptLPS(1); 960 m_host.AddScriptLPS(1);
836 961
962 if (channelID == 0)
963// m_SayShoutCount++;
964 CheckSayShoutTime();
965
966 if (m_SayShoutCount >= 11)
967 ScriptSleep(2000);
968
837 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 969 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
838 { 970 {
839 Console.WriteLine(text); 971 Console.WriteLine(text);
@@ -856,6 +988,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
856 { 988 {
857 m_host.AddScriptLPS(1); 989 m_host.AddScriptLPS(1);
858 990
991 if (channelID == 0)
992// m_SayShoutCount++;
993 CheckSayShoutTime();
994
995 if (m_SayShoutCount >= 11)
996 ScriptSleep(2000);
997
859 if (text.Length > 1023) 998 if (text.Length > 1023)
860 text = text.Substring(0, 1023); 999 text = text.Substring(0, 1023);
861 1000
@@ -887,22 +1026,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
887 1026
888 public void llRegionSayTo(string target, int channel, string msg) 1027 public void llRegionSayTo(string target, int channel, string msg)
889 { 1028 {
1029 string error = String.Empty;
1030
890 if (msg.Length > 1023) 1031 if (msg.Length > 1023)
891 msg = msg.Substring(0, 1023); 1032 msg = msg.Substring(0, 1023);
892 1033
893 m_host.AddScriptLPS(1); 1034 m_host.AddScriptLPS(1);
894 1035
895 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
896 {
897 return;
898 }
899
900 UUID TargetID; 1036 UUID TargetID;
901 UUID.TryParse(target, out TargetID); 1037 UUID.TryParse(target, out TargetID);
902 1038
903 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1039 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
904 if (wComm != null) 1040 if (wComm != null)
905 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1041 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1042 LSLError(error);
906 } 1043 }
907 1044
908 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1045 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1158,10 +1295,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1158 return detectedParams.TouchUV; 1295 return detectedParams.TouchUV;
1159 } 1296 }
1160 1297
1298 [DebuggerNonUserCode]
1161 public virtual void llDie() 1299 public virtual void llDie()
1162 { 1300 {
1163 m_host.AddScriptLPS(1); 1301 m_host.AddScriptLPS(1);
1164 throw new SelfDeleteException(); 1302 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1165 } 1303 }
1166 1304
1167 public LSL_Float llGround(LSL_Vector offset) 1305 public LSL_Float llGround(LSL_Vector offset)
@@ -1232,6 +1370,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1232 1370
1233 public void llSetStatus(int status, int value) 1371 public void llSetStatus(int status, int value)
1234 { 1372 {
1373 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1374 return;
1235 m_host.AddScriptLPS(1); 1375 m_host.AddScriptLPS(1);
1236 1376
1237 int statusrotationaxis = 0; 1377 int statusrotationaxis = 0;
@@ -1255,6 +1395,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1255 if (!allow) 1395 if (!allow)
1256 return; 1396 return;
1257 1397
1398 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1399 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1400 return;
1401
1258 m_host.ScriptSetPhysicsStatus(true); 1402 m_host.ScriptSetPhysicsStatus(true);
1259 } 1403 }
1260 else 1404 else
@@ -1455,6 +1599,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1455 { 1599 {
1456 m_host.AddScriptLPS(1); 1600 m_host.AddScriptLPS(1);
1457 1601
1602 SetColor(m_host, color, face);
1603 }
1604
1605 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1606 {
1607 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1608 return;
1609
1610 Primitive.TextureEntry tex = part.Shape.Textures;
1611 Color4 texcolor;
1612 if (face >= 0 && face < GetNumberOfSides(part))
1613 {
1614 texcolor = tex.CreateFace((uint)face).RGBA;
1615 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1616 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1617 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1618 tex.FaceTextures[face].RGBA = texcolor;
1619 part.UpdateTextureEntry(tex.GetBytes());
1620 return;
1621 }
1622 else if (face == ScriptBaseClass.ALL_SIDES)
1623 {
1624 for (uint i = 0; i < GetNumberOfSides(part); i++)
1625 {
1626 if (tex.FaceTextures[i] != null)
1627 {
1628 texcolor = tex.FaceTextures[i].RGBA;
1629 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1630 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1631 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1632 tex.FaceTextures[i].RGBA = texcolor;
1633 }
1634 texcolor = tex.DefaultTexture.RGBA;
1635 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1636 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1637 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1638 tex.DefaultTexture.RGBA = texcolor;
1639 }
1640 part.UpdateTextureEntry(tex.GetBytes());
1641 return;
1642 }
1643
1458 if (face == ScriptBaseClass.ALL_SIDES) 1644 if (face == ScriptBaseClass.ALL_SIDES)
1459 face = SceneObjectPart.ALL_SIDES; 1645 face = SceneObjectPart.ALL_SIDES;
1460 1646
@@ -1463,6 +1649,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1463 1649
1464 public void SetTexGen(SceneObjectPart part, int face,int style) 1650 public void SetTexGen(SceneObjectPart part, int face,int style)
1465 { 1651 {
1652 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1653 return;
1654
1466 Primitive.TextureEntry tex = part.Shape.Textures; 1655 Primitive.TextureEntry tex = part.Shape.Textures;
1467 MappingType textype; 1656 MappingType textype;
1468 textype = MappingType.Default; 1657 textype = MappingType.Default;
@@ -1493,6 +1682,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1493 1682
1494 public void SetGlow(SceneObjectPart part, int face, float glow) 1683 public void SetGlow(SceneObjectPart part, int face, float glow)
1495 { 1684 {
1685 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1686 return;
1687
1496 Primitive.TextureEntry tex = part.Shape.Textures; 1688 Primitive.TextureEntry tex = part.Shape.Textures;
1497 if (face >= 0 && face < GetNumberOfSides(part)) 1689 if (face >= 0 && face < GetNumberOfSides(part))
1498 { 1690 {
@@ -1518,6 +1710,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1518 1710
1519 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1711 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1520 { 1712 {
1713 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1714 return;
1521 1715
1522 Shininess sval = new Shininess(); 1716 Shininess sval = new Shininess();
1523 1717
@@ -1568,6 +1762,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1568 1762
1569 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1763 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1570 { 1764 {
1765 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1766 return;
1767
1571 Primitive.TextureEntry tex = part.Shape.Textures; 1768 Primitive.TextureEntry tex = part.Shape.Textures;
1572 if (face >= 0 && face < GetNumberOfSides(part)) 1769 if (face >= 0 && face < GetNumberOfSides(part))
1573 { 1770 {
@@ -1628,13 +1825,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1628 m_host.AddScriptLPS(1); 1825 m_host.AddScriptLPS(1);
1629 1826
1630 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1827 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1631 1828 if (parts.Count > 0)
1632 foreach (SceneObjectPart part in parts) 1829 {
1633 SetAlpha(part, alpha, face); 1830 try
1831 {
1832 foreach (SceneObjectPart part in parts)
1833 SetAlpha(part, alpha, face);
1834 }
1835 finally
1836 {
1837 }
1838 }
1634 } 1839 }
1635 1840
1636 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1841 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1637 { 1842 {
1843 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1844 return;
1845
1638 Primitive.TextureEntry tex = part.Shape.Textures; 1846 Primitive.TextureEntry tex = part.Shape.Textures;
1639 Color4 texcolor; 1847 Color4 texcolor;
1640 if (face >= 0 && face < GetNumberOfSides(part)) 1848 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1687,7 +1895,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1687 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1895 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1688 float wind, float tension, LSL_Vector Force) 1896 float wind, float tension, LSL_Vector Force)
1689 { 1897 {
1690 if (part == null) 1898 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1691 return; 1899 return;
1692 1900
1693 if (flexi) 1901 if (flexi)
@@ -1728,7 +1936,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1728 /// <param name="falloff"></param> 1936 /// <param name="falloff"></param>
1729 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1937 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1730 { 1938 {
1731 if (part == null) 1939 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1732 return; 1940 return;
1733 1941
1734 if (light) 1942 if (light)
@@ -1761,11 +1969,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1761 Primitive.TextureEntry tex = part.Shape.Textures; 1969 Primitive.TextureEntry tex = part.Shape.Textures;
1762 Color4 texcolor; 1970 Color4 texcolor;
1763 LSL_Vector rgb = new LSL_Vector(); 1971 LSL_Vector rgb = new LSL_Vector();
1972 int nsides = GetNumberOfSides(part);
1973
1764 if (face == ScriptBaseClass.ALL_SIDES) 1974 if (face == ScriptBaseClass.ALL_SIDES)
1765 { 1975 {
1766 int i; 1976 int i;
1767 1977 for (i = 0; i < nsides; i++)
1768 for (i = 0 ; i < GetNumberOfSides(part); i++)
1769 { 1978 {
1770 texcolor = tex.GetFace((uint)i).RGBA; 1979 texcolor = tex.GetFace((uint)i).RGBA;
1771 rgb.x += texcolor.R; 1980 rgb.x += texcolor.R;
@@ -1773,14 +1982,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1773 rgb.z += texcolor.B; 1982 rgb.z += texcolor.B;
1774 } 1983 }
1775 1984
1776 rgb.x /= (float)GetNumberOfSides(part); 1985 float invnsides = 1.0f / (float)nsides;
1777 rgb.y /= (float)GetNumberOfSides(part); 1986
1778 rgb.z /= (float)GetNumberOfSides(part); 1987 rgb.x *= invnsides;
1988 rgb.y *= invnsides;
1989 rgb.z *= invnsides;
1779 1990
1780 return rgb; 1991 return rgb;
1781 } 1992 }
1782 1993 if (face >= 0 && face < nsides)
1783 if (face >= 0 && face < GetNumberOfSides(part))
1784 { 1994 {
1785 texcolor = tex.GetFace((uint)face).RGBA; 1995 texcolor = tex.GetFace((uint)face).RGBA;
1786 rgb.x = texcolor.R; 1996 rgb.x = texcolor.R;
@@ -1807,15 +2017,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1807 m_host.AddScriptLPS(1); 2017 m_host.AddScriptLPS(1);
1808 2018
1809 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2019 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1810 2020 if (parts.Count > 0)
1811 foreach (SceneObjectPart part in parts) 2021 {
1812 SetTexture(part, texture, face); 2022 try
1813 2023 {
2024 foreach (SceneObjectPart part in parts)
2025 SetTexture(part, texture, face);
2026 }
2027 finally
2028 {
2029 }
2030 }
1814 ScriptSleep(200); 2031 ScriptSleep(200);
1815 } 2032 }
1816 2033
1817 protected void SetTexture(SceneObjectPart part, string texture, int face) 2034 protected void SetTexture(SceneObjectPart part, string texture, int face)
1818 { 2035 {
2036 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2037 return;
2038
1819 UUID textureID = new UUID(); 2039 UUID textureID = new UUID();
1820 2040
1821 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 2041 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
@@ -1860,6 +2080,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1860 2080
1861 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2081 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1862 { 2082 {
2083 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2084 return;
2085
1863 Primitive.TextureEntry tex = part.Shape.Textures; 2086 Primitive.TextureEntry tex = part.Shape.Textures;
1864 if (face >= 0 && face < GetNumberOfSides(part)) 2087 if (face >= 0 && face < GetNumberOfSides(part))
1865 { 2088 {
@@ -1896,6 +2119,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1896 2119
1897 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2120 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1898 { 2121 {
2122 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2123 return;
2124
1899 Primitive.TextureEntry tex = part.Shape.Textures; 2125 Primitive.TextureEntry tex = part.Shape.Textures;
1900 if (face >= 0 && face < GetNumberOfSides(part)) 2126 if (face >= 0 && face < GetNumberOfSides(part))
1901 { 2127 {
@@ -1932,6 +2158,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1932 2158
1933 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2159 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1934 { 2160 {
2161 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2162 return;
2163
1935 Primitive.TextureEntry tex = part.Shape.Textures; 2164 Primitive.TextureEntry tex = part.Shape.Textures;
1936 if (face >= 0 && face < GetNumberOfSides(part)) 2165 if (face >= 0 && face < GetNumberOfSides(part))
1937 { 2166 {
@@ -2073,7 +2302,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2073 return end; 2302 return end;
2074 } 2303 }
2075 2304
2076 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2305 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2077 { 2306 {
2078 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2307 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2079 return fromPos; 2308 return fromPos;
@@ -2089,9 +2318,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2089 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2318 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2090 targetPos.z = ground; 2319 targetPos.z = ground;
2091 } 2320 }
2092 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2321 if (adjust)
2322 return SetPosAdjust(fromPos, targetPos);
2093 2323
2094 return real_vec; 2324 return targetPos;
2095 } 2325 }
2096 2326
2097 /// <summary> 2327 /// <summary>
@@ -2102,27 +2332,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2102 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2332 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2103 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2333 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2104 { 2334 {
2105 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2335 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2336 return;
2337
2106 LSL_Vector currentPos = GetPartLocalPos(part); 2338 LSL_Vector currentPos = GetPartLocalPos(part);
2339 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2107 2340
2108 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2109 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2110 2341
2111 if (part.ParentGroup.RootPart == part) 2342 if (part.ParentGroup.RootPart == part)
2112 { 2343 {
2113 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2114 targetPos.z = ground;
2115 SceneObjectGroup parent = part.ParentGroup; 2344 SceneObjectGroup parent = part.ParentGroup;
2116 parent.UpdateGroupPosition(!adjust ? targetPos : 2345 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2117 SetPosAdjust(currentPos, targetPos)); 2346 return;
2347 Util.FireAndForget(delegate(object x) {
2348 parent.UpdateGroupPosition((Vector3)toPos);
2349 });
2118 } 2350 }
2119 else 2351 else
2120 { 2352 {
2121 part.OffsetPosition = !adjust ? targetPos : 2353 part.OffsetPosition = (Vector3)toPos;
2122 SetPosAdjust(currentPos, targetPos); 2354// SceneObjectGroup parent = part.ParentGroup;
2123 SceneObjectGroup parent = part.ParentGroup; 2355// parent.HasGroupChanged = true;
2124 parent.HasGroupChanged = true; 2356// parent.ScheduleGroupForTerseUpdate();
2125 parent.ScheduleGroupForTerseUpdate(); 2357 part.ScheduleTerseUpdate();
2126 } 2358 }
2127 } 2359 }
2128 2360
@@ -2151,13 +2383,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2151 else 2383 else
2152 { 2384 {
2153 if (part.ParentGroup.IsAttachment) 2385 if (part.ParentGroup.IsAttachment)
2154 {
2155 pos = part.AttachedPos; 2386 pos = part.AttachedPos;
2156 }
2157 else 2387 else
2158 {
2159 pos = part.AbsolutePosition; 2388 pos = part.AbsolutePosition;
2160 }
2161 } 2389 }
2162 2390
2163// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2391// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2169,8 +2397,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2169 { 2397 {
2170 m_host.AddScriptLPS(1); 2398 m_host.AddScriptLPS(1);
2171 2399
2400
2401 // 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
2402 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2403 // 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.
2404 // RootPart != null should shortcircuit
2405
2172 // try to let this work as in SL... 2406 // try to let this work as in SL...
2173 if (m_host.ParentID == 0) 2407 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2174 { 2408 {
2175 // special case: If we are root, rotate complete SOG to new rotation 2409 // special case: If we are root, rotate complete SOG to new rotation
2176 SetRot(m_host, rot); 2410 SetRot(m_host, rot);
@@ -2197,25 +2431,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2197 2431
2198 protected void SetRot(SceneObjectPart part, Quaternion rot) 2432 protected void SetRot(SceneObjectPart part, Quaternion rot)
2199 { 2433 {
2200 part.UpdateRotation(rot); 2434 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2201 // Update rotation does not move the object in the physics scene if it's a linkset. 2435 return;
2202 2436
2203//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2437 bool isroot = (part == part.ParentGroup.RootPart);
2204// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2438 bool isphys;
2205 2439
2206 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2207 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2208 // It's perfectly okay when the object is not an active physical body though.
2209 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2210 // but only if the object is not physial and active. This is important for rotating doors.
2211 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2212 // scene
2213 PhysicsActor pa = part.PhysActor; 2440 PhysicsActor pa = part.PhysActor;
2214 2441
2215 if (pa != null && !pa.IsPhysical) 2442 // keep using physactor ideia of isphysical
2443 // it should be SOP ideia of that
2444 // not much of a issue with ubitODE
2445 if (pa != null && pa.IsPhysical)
2446 isphys = true;
2447 else
2448 isphys = false;
2449
2450 // SL doesn't let scripts rotate root of physical linksets
2451 if (isroot && isphys)
2452 return;
2453
2454 part.UpdateRotation(rot);
2455
2456 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2457 // so do a nasty update of parts positions if is a root part rotation
2458 if (isroot && pa != null) // with if above implies non physical root part
2216 { 2459 {
2217 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2460 part.ParentGroup.ResetChildPrimPhysicsPositions();
2218 } 2461 }
2462 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2463 {
2464 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2465 if (sittingavas.Count > 0)
2466 {
2467 foreach (ScenePresence av in sittingavas)
2468 {
2469 if (isroot || part.LocalId == av.ParentID)
2470 av.SendTerseUpdateToAllClients();
2471 }
2472 }
2473 }
2219 } 2474 }
2220 2475
2221 /// <summary> 2476 /// <summary>
@@ -2232,6 +2487,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2232 2487
2233 m_host.AddScriptLPS(1); 2488 m_host.AddScriptLPS(1);
2234 Quaternion q = m_host.GetWorldRotation(); 2489 Quaternion q = m_host.GetWorldRotation();
2490
2491 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2492 {
2493 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2494 if (avatar != null)
2495 {
2496 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2497 q = avatar.CameraRotation * q; // Mouselook
2498 else
2499 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2500 }
2501 }
2502
2235 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2503 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2236 } 2504 }
2237 2505
@@ -2259,14 +2527,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2259 return new LSL_Rotation(q); 2527 return new LSL_Rotation(q);
2260 } 2528 }
2261 2529
2262 return new LSL_Rotation(part.GetWorldRotation()); 2530 q = part.GetWorldRotation();
2531 if (part.ParentGroup.AttachmentPoint != 0)
2532 {
2533 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2534 if (avatar != null)
2535 {
2536 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2537 q = avatar.CameraRotation * q; // Mouselook
2538 else
2539 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2540 }
2541 }
2542
2543 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2263 } 2544 }
2264 2545
2265 public LSL_Rotation llGetLocalRot() 2546 public LSL_Rotation llGetLocalRot()
2266 { 2547 {
2267 m_host.AddScriptLPS(1); 2548 return GetPartLocalRot(m_host);
2549 }
2268 2550
2269 return new LSL_Rotation(m_host.RotationOffset); 2551 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2552 {
2553 m_host.AddScriptLPS(1);
2554 Quaternion rot = part.RotationOffset;
2555 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2270 } 2556 }
2271 2557
2272 public void llSetForce(LSL_Vector force, int local) 2558 public void llSetForce(LSL_Vector force, int local)
@@ -2346,16 +2632,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2346 m_host.ApplyImpulse(v, local != 0); 2632 m_host.ApplyImpulse(v, local != 0);
2347 } 2633 }
2348 2634
2635
2349 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2636 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2350 { 2637 {
2351 m_host.AddScriptLPS(1); 2638 m_host.AddScriptLPS(1);
2352 m_host.ApplyAngularImpulse(force, local != 0); 2639 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2353 } 2640 }
2354 2641
2355 public void llSetTorque(LSL_Vector torque, int local) 2642 public void llSetTorque(LSL_Vector torque, int local)
2356 { 2643 {
2357 m_host.AddScriptLPS(1); 2644 m_host.AddScriptLPS(1);
2358 m_host.SetAngularImpulse(torque, local != 0); 2645 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2359 } 2646 }
2360 2647
2361 public LSL_Vector llGetTorque() 2648 public LSL_Vector llGetTorque()
@@ -2372,20 +2659,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2372 llSetTorque(torque, local); 2659 llSetTorque(torque, local);
2373 } 2660 }
2374 2661
2662 public void llSetVelocity(LSL_Vector vel, int local)
2663 {
2664 m_host.AddScriptLPS(1);
2665 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2666 }
2667
2375 public LSL_Vector llGetVel() 2668 public LSL_Vector llGetVel()
2376 { 2669 {
2377 m_host.AddScriptLPS(1); 2670 m_host.AddScriptLPS(1);
2378 2671
2379 Vector3 vel; 2672 Vector3 vel = Vector3.Zero;
2380 2673
2381 if (m_host.ParentGroup.IsAttachment) 2674 if (m_host.ParentGroup.IsAttachment)
2382 { 2675 {
2383 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2676 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2384 vel = avatar.Velocity; 2677 if (avatar != null)
2678 vel = avatar.Velocity;
2385 } 2679 }
2386 else 2680 else
2387 { 2681 {
2388 vel = m_host.Velocity; 2682 vel = m_host.ParentGroup.RootPart.Velocity;
2389 } 2683 }
2390 2684
2391 return new LSL_Vector(vel); 2685 return new LSL_Vector(vel);
@@ -2398,11 +2692,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2398 return new LSL_Vector(m_host.Acceleration); 2692 return new LSL_Vector(m_host.Acceleration);
2399 } 2693 }
2400 2694
2401 public LSL_Vector llGetOmega() 2695 public void llSetAngularVelocity(LSL_Vector avel, int local)
2402 { 2696 {
2403 m_host.AddScriptLPS(1); 2697 m_host.AddScriptLPS(1);
2698 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2699 }
2404 2700
2405 return new LSL_Vector(m_host.AngularVelocity); 2701 public LSL_Vector llGetOmega()
2702 {
2703 m_host.AddScriptLPS(1);
2704 Vector3 avel = m_host.AngularVelocity;
2705 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2406 } 2706 }
2407 2707
2408 public LSL_Float llGetTimeOfDay() 2708 public LSL_Float llGetTimeOfDay()
@@ -2761,7 +3061,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2761 return src.ToLower(); 3061 return src.ToLower();
2762 } 3062 }
2763 3063
2764 public void llGiveMoney(string destination, int amount) 3064 public LSL_Integer llGiveMoney(string destination, int amount)
2765 { 3065 {
2766 Util.FireAndForget(x => 3066 Util.FireAndForget(x =>
2767 { 3067 {
@@ -2793,8 +3093,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2793 } 3093 }
2794 3094
2795 money.ObjectGiveMoney( 3095 money.ObjectGiveMoney(
2796 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3096 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2797 }); 3097 });
3098
3099 return 0;
2798 } 3100 }
2799 3101
2800 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3102 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -2873,13 +3175,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2873 new_group.RootPart.UUID.ToString()) }, 3175 new_group.RootPart.UUID.ToString()) },
2874 new DetectParams[0])); 3176 new DetectParams[0]));
2875 3177
2876 float groupmass = new_group.GetMass(); 3178 // do recoil
3179 SceneObjectGroup hostgrp = m_host.ParentGroup;
3180 if (hostgrp == null)
3181 return;
3182
3183 if (hostgrp.IsAttachment) // don't recoil avatars
3184 return;
2877 3185
2878 PhysicsActor pa = new_group.RootPart.PhysActor; 3186 PhysicsActor pa = new_group.RootPart.PhysActor;
2879 3187
2880 //Recoil. 3188 //Recoil.
2881 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3189 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2882 { 3190 {
3191 float groupmass = new_group.GetMass();
2883 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3192 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2884 if (recoil != Vector3.Zero) 3193 if (recoil != Vector3.Zero)
2885 { 3194 {
@@ -2887,6 +3196,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2887 } 3196 }
2888 } 3197 }
2889 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3198 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3199 return;
3200
2890 }); 3201 });
2891 3202
2892 //ScriptSleep((int)((groupmass * velmag) / 10)); 3203 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2901,35 +3212,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2901 public void llLookAt(LSL_Vector target, double strength, double damping) 3212 public void llLookAt(LSL_Vector target, double strength, double damping)
2902 { 3213 {
2903 m_host.AddScriptLPS(1); 3214 m_host.AddScriptLPS(1);
2904 // Determine where we are looking from
2905 LSL_Vector from = llGetPos();
2906 3215
2907 // Work out the normalised vector from the source to the target 3216 // Get the normalized vector to the target
2908 LSL_Vector delta = llVecNorm(target - from); 3217 LSL_Vector d1 = llVecNorm(target - llGetPos());
2909 LSL_Vector angle = new LSL_Vector(0,0,0);
2910 3218
2911 // Calculate the yaw 3219 // Get the bearing (yaw)
2912 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3220 LSL_Vector a1 = new LSL_Vector(0,0,0);
2913 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3221 a1.z = llAtan2(d1.y, d1.x);
2914 3222
2915 // Calculate pitch 3223 // Get the elevation (pitch)
2916 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3224 LSL_Vector a2 = new LSL_Vector(0,0,0);
3225 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2917 3226
2918 // we need to convert from a vector describing 3227 LSL_Rotation r1 = llEuler2Rot(a1);
2919 // the angles of rotation in radians into rotation value 3228 LSL_Rotation r2 = llEuler2Rot(a2);
2920 LSL_Rotation rot = llEuler2Rot(angle); 3229 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2921
2922 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2923 // set the rotation of the object, copy that behavior
2924 PhysicsActor pa = m_host.PhysActor;
2925 3230
2926 if (strength == 0 || pa == null || !pa.IsPhysical) 3231 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2927 { 3232 {
2928 llSetRot(rot); 3233 // Do nothing if either value is 0 (this has been checked in SL)
3234 if (strength <= 0.0 || damping <= 0.0)
3235 return;
3236
3237 llSetRot(r3 * r2 * r1);
2929 } 3238 }
2930 else 3239 else
2931 { 3240 {
2932 m_host.StartLookAt(rot, (float)strength, (float)damping); 3241 if (strength == 0)
3242 {
3243 llSetRot(r3 * r2 * r1);
3244 return;
3245 }
3246
3247 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2933 } 3248 }
2934 } 3249 }
2935 3250
@@ -2976,17 +3291,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2976 } 3291 }
2977 else 3292 else
2978 { 3293 {
2979 if (m_host.IsRoot) 3294 // new SL always returns object mass
2980 { 3295// if (m_host.IsRoot)
3296// {
2981 return m_host.ParentGroup.GetMass(); 3297 return m_host.ParentGroup.GetMass();
2982 } 3298// }
2983 else 3299// else
2984 { 3300// {
2985 return m_host.GetMass(); 3301// return m_host.GetMass();
2986 } 3302// }
2987 } 3303 }
2988 } 3304 }
2989 3305
3306
3307 public LSL_Float llGetMassMKS()
3308 {
3309 return 100f * llGetMass();
3310 }
3311
2990 public void llCollisionFilter(string name, string id, int accept) 3312 public void llCollisionFilter(string name, string id, int accept)
2991 { 3313 {
2992 m_host.AddScriptLPS(1); 3314 m_host.AddScriptLPS(1);
@@ -3034,8 +3356,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3034 { 3356 {
3035 // Unregister controls from Presence 3357 // Unregister controls from Presence
3036 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3358 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3037 // Remove Take Control permission.
3038 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3039 } 3359 }
3040 } 3360 }
3041 } 3361 }
@@ -3063,7 +3383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3063 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3383 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3064 3384
3065 if (attachmentsModule != null) 3385 if (attachmentsModule != null)
3066 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true); 3386 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3067 else 3387 else
3068 return false; 3388 return false;
3069 } 3389 }
@@ -3093,9 +3413,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3093 { 3413 {
3094 m_host.AddScriptLPS(1); 3414 m_host.AddScriptLPS(1);
3095 3415
3096// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3097// return;
3098
3099 if (m_item.PermsGranter != m_host.OwnerID) 3416 if (m_item.PermsGranter != m_host.OwnerID)
3100 return; 3417 return;
3101 3418
@@ -3138,6 +3455,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3138 3455
3139 public void llInstantMessage(string user, string message) 3456 public void llInstantMessage(string user, string message)
3140 { 3457 {
3458 UUID result;
3459 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3460 {
3461 ShoutError("An invalid key was passed to llInstantMessage");
3462 ScriptSleep(2000);
3463 return;
3464 }
3465
3466
3141 m_host.AddScriptLPS(1); 3467 m_host.AddScriptLPS(1);
3142 3468
3143 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3469 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3152,14 +3478,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3152 UUID friendTransactionID = UUID.Random(); 3478 UUID friendTransactionID = UUID.Random();
3153 3479
3154 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3480 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3155 3481
3156 GridInstantMessage msg = new GridInstantMessage(); 3482 GridInstantMessage msg = new GridInstantMessage();
3157 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3483 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3158 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3484 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3159 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3485 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3160// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3486// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3161// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3487// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3162 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3488// DateTime dt = DateTime.UtcNow;
3489//
3490// // Ticks from UtcNow, but make it look like local. Evil, huh?
3491// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3492//
3493// try
3494// {
3495// // Convert that to the PST timezone
3496// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3497// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3498// }
3499// catch
3500// {
3501// // No logging here, as it could be VERY spammy
3502// }
3503//
3504// // And make it look local again to fool the unix time util
3505// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3506
3507 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3508
3163 //if (client != null) 3509 //if (client != null)
3164 //{ 3510 //{
3165 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3511 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3173,10 +3519,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3173 msg.message = message.Substring(0, 1024); 3519 msg.message = message.Substring(0, 1024);
3174 else 3520 else
3175 msg.message = message; 3521 msg.message = message;
3176 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3522 msg.dialog = (byte)19; // MessageFromObject
3177 msg.fromGroup = false;// fromGroup; 3523 msg.fromGroup = false;// fromGroup;
3178 msg.offline = (byte)0; //offline; 3524 msg.offline = (byte)0; //offline;
3179 msg.ParentEstateID = 0; //ParentEstateID; 3525 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3180 msg.Position = new Vector3(m_host.AbsolutePosition); 3526 msg.Position = new Vector3(m_host.AbsolutePosition);
3181 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3527 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3182 3528
@@ -3208,7 +3554,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3208 } 3554 }
3209 3555
3210 emailModule.SendEmail(m_host.UUID, address, subject, message); 3556 emailModule.SendEmail(m_host.UUID, address, subject, message);
3211 llSleep(EMAIL_PAUSE_TIME); 3557 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3212 } 3558 }
3213 3559
3214 public void llGetNextEmail(string address, string subject) 3560 public void llGetNextEmail(string address, string subject)
@@ -3454,7 +3800,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3454 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3800 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3455 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3801 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3456 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3802 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3803 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3457 ScriptBaseClass.PERMISSION_ATTACH; 3804 ScriptBaseClass.PERMISSION_ATTACH;
3805
3458 } 3806 }
3459 else 3807 else
3460 { 3808 {
@@ -3471,15 +3819,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3471 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3819 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3472 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3820 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3473 } 3821 }
3822 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3823 {
3824 implicitPerms = perm;
3825 }
3474 } 3826 }
3475 3827
3476 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3828 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3477 { 3829 {
3478 lock (m_host.TaskInventory) 3830 m_host.TaskInventory.LockItemsForWrite(true);
3479 { 3831 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3480 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3832 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3481 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3833 m_host.TaskInventory.LockItemsForWrite(false);
3482 }
3483 3834
3484 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3835 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3485 "run_time_permissions", new Object[] { 3836 "run_time_permissions", new Object[] {
@@ -3522,11 +3873,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3522 3873
3523 if (!m_waitingForScriptAnswer) 3874 if (!m_waitingForScriptAnswer)
3524 { 3875 {
3525 lock (m_host.TaskInventory) 3876 m_host.TaskInventory.LockItemsForWrite(true);
3526 { 3877 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3527 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3878 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3528 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3879 m_host.TaskInventory.LockItemsForWrite(false);
3529 }
3530 3880
3531 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3881 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3532 m_waitingForScriptAnswer=true; 3882 m_waitingForScriptAnswer=true;
@@ -3555,14 +3905,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3555 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3905 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3556 llReleaseControls(); 3906 llReleaseControls();
3557 3907
3558 lock (m_host.TaskInventory) 3908 m_host.TaskInventory.LockItemsForWrite(true);
3559 { 3909 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3560 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3910 m_host.TaskInventory.LockItemsForWrite(false);
3561 } 3911
3562 3912 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3563 m_ScriptEngine.PostScriptEvent( 3913 "run_time_permissions", new Object[] {
3564 m_item.ItemID, 3914 new LSL_Integer(answer) },
3565 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3915 new DetectParams[0]));
3566 } 3916 }
3567 3917
3568 public LSL_String llGetPermissionsKey() 3918 public LSL_String llGetPermissionsKey()
@@ -3601,14 +3951,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3601 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3951 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3602 { 3952 {
3603 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3953 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3604 3954 if (parts.Count > 0)
3605 foreach (SceneObjectPart part in parts) 3955 {
3606 part.SetFaceColorAlpha(face, color, null); 3956 try
3957 {
3958 foreach (SceneObjectPart part in parts)
3959 part.SetFaceColorAlpha(face, color, null);
3960 }
3961 finally
3962 {
3963 }
3964 }
3607 } 3965 }
3608 3966
3609 public void llCreateLink(string target, int parent) 3967 public void llCreateLink(string target, int parent)
3610 { 3968 {
3611 m_host.AddScriptLPS(1); 3969 m_host.AddScriptLPS(1);
3970
3612 UUID targetID; 3971 UUID targetID;
3613 3972
3614 if (!UUID.TryParse(target, out targetID)) 3973 if (!UUID.TryParse(target, out targetID))
@@ -3714,10 +4073,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3714 // Restructuring Multiple Prims. 4073 // Restructuring Multiple Prims.
3715 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4074 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3716 parts.Remove(parentPrim.RootPart); 4075 parts.Remove(parentPrim.RootPart);
3717 foreach (SceneObjectPart part in parts) 4076 if (parts.Count > 0)
3718 { 4077 {
3719 parentPrim.DelinkFromGroup(part.LocalId, true); 4078 try
4079 {
4080 foreach (SceneObjectPart part in parts)
4081 {
4082 parentPrim.DelinkFromGroup(part.LocalId, true);
4083 }
4084 }
4085 finally
4086 {
4087 }
3720 } 4088 }
4089
3721 parentPrim.HasGroupChanged = true; 4090 parentPrim.HasGroupChanged = true;
3722 parentPrim.ScheduleGroupForFullUpdate(); 4091 parentPrim.ScheduleGroupForFullUpdate();
3723 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4092 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3726,12 +4095,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3726 { 4095 {
3727 SceneObjectPart newRoot = parts[0]; 4096 SceneObjectPart newRoot = parts[0];
3728 parts.Remove(newRoot); 4097 parts.Remove(newRoot);
3729 foreach (SceneObjectPart part in parts) 4098
4099 try
3730 { 4100 {
3731 // Required for linking 4101 foreach (SceneObjectPart part in parts)
3732 part.ClearUpdateSchedule(); 4102 {
3733 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4103 part.ClearUpdateSchedule();
4104 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4105 }
3734 } 4106 }
4107 finally
4108 {
4109 }
4110
4111
3735 newRoot.ParentGroup.HasGroupChanged = true; 4112 newRoot.ParentGroup.HasGroupChanged = true;
3736 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4113 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3737 } 4114 }
@@ -3751,6 +4128,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3751 public void llBreakAllLinks() 4128 public void llBreakAllLinks()
3752 { 4129 {
3753 m_host.AddScriptLPS(1); 4130 m_host.AddScriptLPS(1);
4131
4132 TaskInventoryItem item = m_item;
4133
4134 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4135 && !m_automaticLinkPermission)
4136 {
4137 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4138 return;
4139 }
4140
3754 SceneObjectGroup parentPrim = m_host.ParentGroup; 4141 SceneObjectGroup parentPrim = m_host.ParentGroup;
3755 if (parentPrim.AttachmentPoint != 0) 4142 if (parentPrim.AttachmentPoint != 0)
3756 return; // Fail silently if attached 4143 return; // Fail silently if attached
@@ -3770,13 +4157,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3770 public LSL_String llGetLinkKey(int linknum) 4157 public LSL_String llGetLinkKey(int linknum)
3771 { 4158 {
3772 m_host.AddScriptLPS(1); 4159 m_host.AddScriptLPS(1);
4160 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
4161 if (part != null)
4162 {
4163 return part.UUID.ToString();
4164 }
4165 else
4166 {
4167 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4168 {
4169 linknum -= (m_host.ParentGroup.PrimCount) + 1;
3773 4170
3774 ISceneEntity entity = GetLinkEntity(linknum); 4171 if (linknum < 0)
4172 return UUID.Zero.ToString();
3775 4173
3776 if (entity != null) 4174 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
3777 return entity.UUID.ToString(); 4175 if (avatars.Count > linknum)
3778 else 4176 {
3779 return ScriptBaseClass.NULL_KEY; 4177 return avatars[linknum].UUID.ToString();
4178 }
4179 }
4180 return UUID.Zero.ToString();
4181 }
3780 } 4182 }
3781 4183
3782 /// <summary> 4184 /// <summary>
@@ -3835,17 +4237,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3835 m_host.AddScriptLPS(1); 4237 m_host.AddScriptLPS(1);
3836 int count = 0; 4238 int count = 0;
3837 4239
3838 lock (m_host.TaskInventory) 4240 m_host.TaskInventory.LockItemsForRead(true);
4241 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3839 { 4242 {
3840 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4243 if (inv.Value.Type == type || type == -1)
3841 { 4244 {
3842 if (inv.Value.Type == type || type == -1) 4245 count = count + 1;
3843 {
3844 count = count + 1;
3845 }
3846 } 4246 }
3847 } 4247 }
3848 4248
4249 m_host.TaskInventory.LockItemsForRead(false);
3849 return count; 4250 return count;
3850 } 4251 }
3851 4252
@@ -3854,16 +4255,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3854 m_host.AddScriptLPS(1); 4255 m_host.AddScriptLPS(1);
3855 ArrayList keys = new ArrayList(); 4256 ArrayList keys = new ArrayList();
3856 4257
3857 lock (m_host.TaskInventory) 4258 m_host.TaskInventory.LockItemsForRead(true);
4259 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3858 { 4260 {
3859 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4261 if (inv.Value.Type == type || type == -1)
3860 { 4262 {
3861 if (inv.Value.Type == type || type == -1) 4263 keys.Add(inv.Value.Name);
3862 {
3863 keys.Add(inv.Value.Name);
3864 }
3865 } 4264 }
3866 } 4265 }
4266 m_host.TaskInventory.LockItemsForRead(false);
3867 4267
3868 if (keys.Count == 0) 4268 if (keys.Count == 0)
3869 { 4269 {
@@ -3901,7 +4301,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3901 if (item == null) 4301 if (item == null)
3902 { 4302 {
3903 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4303 llSay(0, String.Format("Could not find object '{0}'", inventory));
3904 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4304 return;
4305// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3905 } 4306 }
3906 4307
3907 UUID objId = item.ItemID; 4308 UUID objId = item.ItemID;
@@ -3929,33 +4330,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3929 return; 4330 return;
3930 } 4331 }
3931 } 4332 }
4333
3932 // destination is an avatar 4334 // destination is an avatar
3933 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4335 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3934 4336
3935 if (agentItem == null) 4337 if (agentItem == null)
3936 return; 4338 return;
3937 4339
3938 if (m_TransferModule != null) 4340 byte[] bucket = new byte[1];
3939 { 4341 bucket[0] = (byte)item.Type;
3940 byte[] bucket = new byte[1]; 4342 //byte[] objBytes = agentItem.ID.GetBytes();
3941 bucket[0] = (byte)item.Type; 4343 //Array.Copy(objBytes, 0, bucket, 1, 16);
3942 4344
3943 GridInstantMessage msg = new GridInstantMessage(World, 4345 GridInstantMessage msg = new GridInstantMessage(World,
3944 m_host.OwnerID, m_host.Name, destId, 4346 m_host.OwnerID, m_host.Name, destId,
3945 (byte)InstantMessageDialog.TaskInventoryOffered, 4347 (byte)InstantMessageDialog.TaskInventoryOffered,
3946 false, item.Name+". "+m_host.Name+" is located at "+ 4348 false, item.Name+". "+m_host.Name+" is located at "+
3947 World.RegionInfo.RegionName+" "+ 4349 World.RegionInfo.RegionName+" "+
3948 m_host.AbsolutePosition.ToString(), 4350 m_host.AbsolutePosition.ToString(),
3949 agentItem.ID, true, m_host.AbsolutePosition, 4351 agentItem.ID, true, m_host.AbsolutePosition,
3950 bucket, true); 4352 bucket, true);
3951 4353
3952 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4354 ScenePresence sp;
3953 }
3954 4355
4356 if (World.TryGetScenePresence(destId, out sp))
4357 {
4358 sp.ControllingClient.SendInstantMessage(msg);
4359 }
4360 else
4361 {
4362 if (m_TransferModule != null)
4363 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4364 }
4365
4366 //This delay should only occur when giving inventory to avatars.
3955 ScriptSleep(3000); 4367 ScriptSleep(3000);
3956 } 4368 }
3957 } 4369 }
3958 4370
4371 [DebuggerNonUserCode]
3959 public void llRemoveInventory(string name) 4372 public void llRemoveInventory(string name)
3960 { 4373 {
3961 m_host.AddScriptLPS(1); 4374 m_host.AddScriptLPS(1);
@@ -4010,109 +4423,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4010 { 4423 {
4011 m_host.AddScriptLPS(1); 4424 m_host.AddScriptLPS(1);
4012 4425
4013 UUID uuid = (UUID)id; 4426 UUID uuid;
4014 PresenceInfo pinfo = null; 4427 if (UUID.TryParse(id, out uuid))
4015 UserAccount account;
4016
4017 UserInfoCacheEntry ce;
4018 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4019 { 4428 {
4020 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4429 PresenceInfo pinfo = null;
4021 if (account == null) 4430 UserAccount account;
4431
4432 UserInfoCacheEntry ce;
4433 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4022 { 4434 {
4023 m_userInfoCache[uuid] = null; // Cache negative 4435 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4024 return UUID.Zero.ToString(); 4436 if (account == null)
4025 } 4437 {
4438 m_userInfoCache[uuid] = null; // Cache negative
4439 return UUID.Zero.ToString();
4440 }
4026 4441
4027 4442
4028 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4443 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4029 if (pinfos != null && pinfos.Length > 0) 4444 if (pinfos != null && pinfos.Length > 0)
4030 {
4031 foreach (PresenceInfo p in pinfos)
4032 { 4445 {
4033 if (p.RegionID != UUID.Zero) 4446 foreach (PresenceInfo p in pinfos)
4034 { 4447 {
4035 pinfo = p; 4448 if (p.RegionID != UUID.Zero)
4449 {
4450 pinfo = p;
4451 }
4036 } 4452 }
4037 } 4453 }
4038 }
4039 4454
4040 ce = new UserInfoCacheEntry(); 4455 ce = new UserInfoCacheEntry();
4041 ce.time = Util.EnvironmentTickCount(); 4456 ce.time = Util.EnvironmentTickCount();
4042 ce.account = account; 4457 ce.account = account;
4043 ce.pinfo = pinfo; 4458 ce.pinfo = pinfo;
4044 } 4459 m_userInfoCache[uuid] = ce;
4045 else 4460 }
4046 { 4461 else
4047 if (ce == null) 4462 {
4048 return UUID.Zero.ToString(); 4463 if (ce == null)
4464 return UUID.Zero.ToString();
4049 4465
4050 account = ce.account; 4466 account = ce.account;
4051 pinfo = ce.pinfo; 4467 pinfo = ce.pinfo;
4052 } 4468 }
4053 4469
4054 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4470 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4055 {
4056 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4057 if (pinfos != null && pinfos.Length > 0)
4058 { 4471 {
4059 foreach (PresenceInfo p in pinfos) 4472 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4473 if (pinfos != null && pinfos.Length > 0)
4060 { 4474 {
4061 if (p.RegionID != UUID.Zero) 4475 foreach (PresenceInfo p in pinfos)
4062 { 4476 {
4063 pinfo = p; 4477 if (p.RegionID != UUID.Zero)
4478 {
4479 pinfo = p;
4480 }
4064 } 4481 }
4065 } 4482 }
4066 } 4483 else
4067 else 4484 pinfo = null;
4068 pinfo = null;
4069 4485
4070 ce.time = Util.EnvironmentTickCount(); 4486 ce.time = Util.EnvironmentTickCount();
4071 ce.pinfo = pinfo; 4487 ce.pinfo = pinfo;
4072 } 4488 }
4073 4489
4074 string reply = String.Empty; 4490 string reply = String.Empty;
4075 4491
4076 switch (data) 4492 switch (data)
4077 { 4493 {
4078 case 1: // DATA_ONLINE (0|1) 4494 case 1: // DATA_ONLINE (0|1)
4079 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4495 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4080 reply = "1"; 4496 reply = "1";
4081 else 4497 else
4082 reply = "0"; 4498 reply = "0";
4083 break; 4499 break;
4084 case 2: // DATA_NAME (First Last) 4500 case 2: // DATA_NAME (First Last)
4085 reply = account.FirstName + " " + account.LastName; 4501 reply = account.FirstName + " " + account.LastName;
4086 break; 4502 break;
4087 case 3: // DATA_BORN (YYYY-MM-DD) 4503 case 3: // DATA_BORN (YYYY-MM-DD)
4088 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4504 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4089 born = born.AddSeconds(account.Created); 4505 born = born.AddSeconds(account.Created);
4090 reply = born.ToString("yyyy-MM-dd"); 4506 reply = born.ToString("yyyy-MM-dd");
4091 break; 4507 break;
4092 case 4: // DATA_RATING (0,0,0,0,0,0) 4508 case 4: // DATA_RATING (0,0,0,0,0,0)
4093 reply = "0,0,0,0,0,0"; 4509 reply = "0,0,0,0,0,0";
4094 break; 4510 break;
4095 case 7: // DATA_USERLEVEL (integer) 4511 case 8: // DATA_PAYINFO (0|1|2|3)
4096 reply = account.UserLevel.ToString(); 4512 reply = "0";
4097 break; 4513 break;
4098 case 8: // DATA_PAYINFO (0|1|2|3) 4514 default:
4099 reply = "0"; 4515 return UUID.Zero.ToString(); // Raise no event
4100 break; 4516 }
4101 default:
4102 return UUID.Zero.ToString(); // Raise no event
4103 }
4104 4517
4105 UUID rq = UUID.Random(); 4518 UUID rq = UUID.Random();
4106 4519
4107 UUID tid = AsyncCommands. 4520 UUID tid = AsyncCommands.
4108 DataserverPlugin.RegisterRequest(m_host.LocalId, 4521 DataserverPlugin.RegisterRequest(m_host.LocalId,
4109 m_item.ItemID, rq.ToString()); 4522 m_item.ItemID, rq.ToString());
4110 4523
4111 AsyncCommands. 4524 AsyncCommands.
4112 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4525 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4113 4526
4114 ScriptSleep(100); 4527 ScriptSleep(100);
4115 return tid.ToString(); 4528 return tid.ToString();
4529 }
4530 else
4531 {
4532 ShoutError("Invalid UUID passed to llRequestAgentData.");
4533 }
4534 return "";
4116 } 4535 }
4117 4536
4118 public LSL_String llRequestInventoryData(string name) 4537 public LSL_String llRequestInventoryData(string name)
@@ -4169,12 +4588,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4169 if (UUID.TryParse(agent, out agentId)) 4588 if (UUID.TryParse(agent, out agentId))
4170 { 4589 {
4171 ScenePresence presence = World.GetScenePresence(agentId); 4590 ScenePresence presence = World.GetScenePresence(agentId);
4172 if (presence != null) 4591 if (presence != null && presence.PresenceType != PresenceType.Npc)
4173 { 4592 {
4593 // agent must not be a god
4594 if (presence.UserLevel >= 200) return;
4595
4174 // agent must be over the owners land 4596 // agent must be over the owners land
4175 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4597 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4176 { 4598 {
4177 World.TeleportClientHome(agentId, presence.ControllingClient); 4599 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4600 {
4601 // They can't be teleported home for some reason
4602 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4603 if (regionInfo != null)
4604 {
4605 World.RequestTeleportLocation(
4606 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4607 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4608 }
4609 }
4178 } 4610 }
4179 } 4611 }
4180 } 4612 }
@@ -4280,7 +4712,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4280 UUID av = new UUID(); 4712 UUID av = new UUID();
4281 if (!UUID.TryParse(agent,out av)) 4713 if (!UUID.TryParse(agent,out av))
4282 { 4714 {
4283 LSLError("First parameter to llDialog needs to be a key");
4284 return; 4715 return;
4285 } 4716 }
4286 4717
@@ -4312,10 +4743,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4312 public void llCollisionSound(string impact_sound, double impact_volume) 4743 public void llCollisionSound(string impact_sound, double impact_volume)
4313 { 4744 {
4314 m_host.AddScriptLPS(1); 4745 m_host.AddScriptLPS(1);
4315 4746
4747 if(impact_sound == "")
4748 {
4749 m_host.CollisionSoundVolume = (float)impact_volume;
4750 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4751 m_host.CollisionSoundType = 0;
4752 return;
4753 }
4316 // TODO: Parameter check logic required. 4754 // TODO: Parameter check logic required.
4317 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 4755 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4318 m_host.CollisionSoundVolume = (float)impact_volume; 4756 m_host.CollisionSoundVolume = (float)impact_volume;
4757 m_host.CollisionSoundType = 1;
4319 } 4758 }
4320 4759
4321 public LSL_String llGetAnimation(string id) 4760 public LSL_String llGetAnimation(string id)
@@ -4329,14 +4768,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4329 4768
4330 if (m_host.RegionHandle == presence.RegionHandle) 4769 if (m_host.RegionHandle == presence.RegionHandle)
4331 { 4770 {
4332 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4333
4334 if (presence != null) 4771 if (presence != null)
4335 { 4772 {
4336 AnimationSet currentAnims = presence.Animator.Animations; 4773 if (presence.SitGround)
4337 string currentAnimationState = String.Empty; 4774 return "Sitting on Ground";
4338 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4775 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4339 return currentAnimationState; 4776 return "Sitting";
4777
4778 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4779 string lslMovementAnimation;
4780
4781 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4782 return lslMovementAnimation;
4340 } 4783 }
4341 } 4784 }
4342 4785
@@ -4484,7 +4927,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4484 { 4927 {
4485 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4928 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4486 float distance_term = distance * distance * distance; // Script Energy 4929 float distance_term = distance * distance * distance; // Script Energy
4487 float pusher_mass = m_host.GetMass(); 4930 // use total object mass and not part
4931 float pusher_mass = m_host.ParentGroup.GetMass();
4488 4932
4489 float PUSH_ATTENUATION_DISTANCE = 17f; 4933 float PUSH_ATTENUATION_DISTANCE = 17f;
4490 float PUSH_ATTENUATION_SCALE = 5f; 4934 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4738,6 +5182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4738 { 5182 {
4739 return item.AssetID.ToString(); 5183 return item.AssetID.ToString();
4740 } 5184 }
5185 m_host.TaskInventory.LockItemsForRead(false);
4741 5186
4742 return UUID.Zero.ToString(); 5187 return UUID.Zero.ToString();
4743 } 5188 }
@@ -4890,14 +5335,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4890 { 5335 {
4891 m_host.AddScriptLPS(1); 5336 m_host.AddScriptLPS(1);
4892 5337
4893 if (src == null) 5338 return src.Length;
4894 {
4895 return 0;
4896 }
4897 else
4898 {
4899 return src.Length;
4900 }
4901 } 5339 }
4902 5340
4903 public LSL_Integer llList2Integer(LSL_List src, int index) 5341 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4968,7 +5406,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4968 else if (src.Data[index] is LSL_Float) 5406 else if (src.Data[index] is LSL_Float)
4969 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5407 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4970 else if (src.Data[index] is LSL_String) 5408 else if (src.Data[index] is LSL_String)
4971 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5409 {
5410 string str = ((LSL_String) src.Data[index]).m_string;
5411 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5412 if (m != Match.Empty)
5413 {
5414 str = m.Value;
5415 double d = 0.0;
5416 if (!Double.TryParse(str, out d))
5417 return 0.0;
5418
5419 return d;
5420 }
5421 return 0.0;
5422 }
4972 return Convert.ToDouble(src.Data[index]); 5423 return Convert.ToDouble(src.Data[index]);
4973 } 5424 }
4974 catch (FormatException) 5425 catch (FormatException)
@@ -5010,7 +5461,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5010 // for completion and should LSL_Key ever be implemented 5461 // for completion and should LSL_Key ever be implemented
5011 // as it's own struct 5462 // as it's own struct
5012 else if (!(src.Data[index] is LSL_String || 5463 else if (!(src.Data[index] is LSL_String ||
5013 src.Data[index] is LSL_Key)) 5464 src.Data[index] is LSL_Key ||
5465 src.Data[index] is String))
5014 { 5466 {
5015 return ""; 5467 return "";
5016 } 5468 }
@@ -5268,7 +5720,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5268 } 5720 }
5269 } 5721 }
5270 } 5722 }
5271 else { 5723 else
5724 {
5272 object[] array = new object[src.Length]; 5725 object[] array = new object[src.Length];
5273 Array.Copy(src.Data, 0, array, 0, src.Length); 5726 Array.Copy(src.Data, 0, array, 0, src.Length);
5274 result = new LSL_List(array); 5727 result = new LSL_List(array);
@@ -5375,7 +5828,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5375 public LSL_Integer llGetRegionAgentCount() 5828 public LSL_Integer llGetRegionAgentCount()
5376 { 5829 {
5377 m_host.AddScriptLPS(1); 5830 m_host.AddScriptLPS(1);
5378 return new LSL_Integer(World.GetRootAgentCount()); 5831
5832 int count = 0;
5833 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5834 count++;
5835 });
5836
5837 return new LSL_Integer(count);
5379 } 5838 }
5380 5839
5381 public LSL_Vector llGetRegionCorner() 5840 public LSL_Vector llGetRegionCorner()
@@ -5616,6 +6075,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5616 flags |= ScriptBaseClass.AGENT_AWAY; 6075 flags |= ScriptBaseClass.AGENT_AWAY;
5617 } 6076 }
5618 6077
6078 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6079 UUID[] anims = agent.Animator.GetAnimationArray();
6080 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6081 {
6082 flags |= ScriptBaseClass.AGENT_BUSY;
6083 }
6084
5619 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6085 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5620 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6086 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5621 { 6087 {
@@ -5663,6 +6129,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5663 flags |= ScriptBaseClass.AGENT_SITTING; 6129 flags |= ScriptBaseClass.AGENT_SITTING;
5664 } 6130 }
5665 6131
6132 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6133 {
6134 flags |= ScriptBaseClass.AGENT_MALE;
6135 }
6136
5666 return flags; 6137 return flags;
5667 } 6138 }
5668 6139
@@ -5808,9 +6279,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5808 6279
5809 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6280 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5810 6281
5811 foreach (SceneObjectPart part in parts) 6282 try
6283 {
6284 foreach (SceneObjectPart part in parts)
6285 {
6286 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6287 }
6288 }
6289 finally
5812 { 6290 {
5813 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5814 } 6291 }
5815 } 6292 }
5816 6293
@@ -5864,13 +6341,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5864 6341
5865 if (m_host.OwnerID == land.LandData.OwnerID) 6342 if (m_host.OwnerID == land.LandData.OwnerID)
5866 { 6343 {
5867 World.TeleportClientHome(agentID, presence.ControllingClient); 6344 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6345 presence.TeleportWithMomentum(p, null);
6346 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5868 } 6347 }
5869 } 6348 }
5870 } 6349 }
5871 ScriptSleep(5000); 6350 ScriptSleep(5000);
5872 } 6351 }
5873 6352
6353 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6354 {
6355 return ParseString2List(str, separators, in_spacers, false);
6356 }
6357
5874 public LSL_Integer llOverMyLand(string id) 6358 public LSL_Integer llOverMyLand(string id)
5875 { 6359 {
5876 m_host.AddScriptLPS(1); 6360 m_host.AddScriptLPS(1);
@@ -5923,26 +6407,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5923 } 6407 }
5924 else 6408 else
5925 { 6409 {
5926 agentSize = GetAgentSize(avatar); 6410// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6411 Vector3 s = avatar.Appearance.AvatarSize;
6412 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5927 } 6413 }
5928
5929 return agentSize; 6414 return agentSize;
5930 } 6415 }
5931 6416
5932 public LSL_Integer llSameGroup(string agent) 6417 public LSL_Integer llSameGroup(string id)
5933 { 6418 {
5934 m_host.AddScriptLPS(1); 6419 m_host.AddScriptLPS(1);
5935 UUID agentId = new UUID(); 6420 UUID uuid = new UUID();
5936 if (!UUID.TryParse(agent, out agentId)) 6421 if (!UUID.TryParse(id, out uuid))
5937 return new LSL_Integer(0);
5938 ScenePresence presence = World.GetScenePresence(agentId);
5939 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5940 return new LSL_Integer(0); 6422 return new LSL_Integer(0);
5941 IClientAPI client = presence.ControllingClient; 6423
5942 if (m_host.GroupID == client.ActiveGroupId) 6424 // Check if it's a group key
6425 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5943 return new LSL_Integer(1); 6426 return new LSL_Integer(1);
5944 else 6427
6428 // We got passed a UUID.Zero
6429 if (uuid == UUID.Zero)
5945 return new LSL_Integer(0); 6430 return new LSL_Integer(0);
6431
6432 // Handle the case where id names an avatar
6433 ScenePresence presence = World.GetScenePresence(uuid);
6434 if (presence != null)
6435 {
6436 if (presence.IsChildAgent)
6437 return new LSL_Integer(0);
6438
6439 IClientAPI client = presence.ControllingClient;
6440 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6441 return new LSL_Integer(1);
6442
6443 return new LSL_Integer(0);
6444 }
6445
6446 // Handle object case
6447 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6448 if (part != null)
6449 {
6450 // This will handle both deed and non-deed and also the no
6451 // group case
6452 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6453 return new LSL_Integer(1);
6454
6455 return new LSL_Integer(0);
6456 }
6457
6458 return new LSL_Integer(0);
5946 } 6459 }
5947 6460
5948 public void llUnSit(string id) 6461 public void llUnSit(string id)
@@ -6501,6 +7014,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6501 7014
6502 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7015 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6503 { 7016 {
7017 // LSL quaternions can normalize to 0, normal Quaternions can't.
7018 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7019 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7020
6504 part.SitTargetPosition = offset; 7021 part.SitTargetPosition = offset;
6505 part.SitTargetOrientation = rot; 7022 part.SitTargetOrientation = rot;
6506 part.ParentGroup.HasGroupChanged = true; 7023 part.ParentGroup.HasGroupChanged = true;
@@ -6687,30 +7204,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6687 UUID av = new UUID(); 7204 UUID av = new UUID();
6688 if (!UUID.TryParse(avatar,out av)) 7205 if (!UUID.TryParse(avatar,out av))
6689 { 7206 {
6690 LSLError("First parameter to llDialog needs to be a key"); 7207 //LSLError("First parameter to llDialog needs to be a key");
6691 return; 7208 return;
6692 } 7209 }
6693 if (buttons.Length < 1) 7210 if (buttons.Length < 1)
6694 { 7211 {
6695 LSLError("No less than 1 button can be shown"); 7212 buttons.Add("OK");
6696 return;
6697 } 7213 }
6698 if (buttons.Length > 12) 7214 if (buttons.Length > 12)
6699 { 7215 {
6700 LSLError("No more than 12 buttons can be shown"); 7216 ShoutError("button list too long, must be 12 or fewer entries");
6701 return;
6702 } 7217 }
6703 string[] buts = new string[buttons.Length]; 7218 int length = buttons.Length;
6704 for (int i = 0; i < buttons.Length; i++) 7219 if (length > 12)
7220 length = 12;
7221
7222 string[] buts = new string[length];
7223 for (int i = 0; i < length; i++)
6705 { 7224 {
6706 if (buttons.Data[i].ToString() == String.Empty) 7225 if (buttons.Data[i].ToString() == String.Empty)
6707 { 7226 {
6708 LSLError("button label cannot be blank"); 7227 ShoutError("button label cannot be blank");
6709 return; 7228 return;
6710 } 7229 }
6711 if (buttons.Data[i].ToString().Length > 24) 7230 if (buttons.Data[i].ToString().Length > 24)
6712 { 7231 {
6713 LSLError("button label cannot be longer than 24 characters"); 7232 ShoutError("button label cannot be longer than 24 characters");
6714 return; 7233 return;
6715 } 7234 }
6716 buts[i] = buttons.Data[i].ToString(); 7235 buts[i] = buttons.Data[i].ToString();
@@ -6777,9 +7296,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6777 return; 7296 return;
6778 } 7297 }
6779 7298
6780 // the rest of the permission checks are done in RezScript, so check the pin there as well 7299 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6781 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7300 if (dest != null)
7301 {
7302 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7303 {
7304 // the rest of the permission checks are done in RezScript, so check the pin there as well
7305 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6782 7306
7307 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7308 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7309 }
7310 }
6783 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7311 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6784 ScriptSleep(3000); 7312 ScriptSleep(3000);
6785 } 7313 }
@@ -6853,19 +7381,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6853 public LSL_String llMD5String(string src, int nonce) 7381 public LSL_String llMD5String(string src, int nonce)
6854 { 7382 {
6855 m_host.AddScriptLPS(1); 7383 m_host.AddScriptLPS(1);
6856 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7384 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6857 } 7385 }
6858 7386
6859 public LSL_String llSHA1String(string src) 7387 public LSL_String llSHA1String(string src)
6860 { 7388 {
6861 m_host.AddScriptLPS(1); 7389 m_host.AddScriptLPS(1);
6862 return Util.SHA1Hash(src).ToLower(); 7390 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6863 } 7391 }
6864 7392
6865 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7393 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6866 { 7394 {
6867 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7395 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6868 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7396 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7397 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7398 return shapeBlock;
6869 7399
6870 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7400 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6871 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7401 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6970,6 +7500,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6970 // Prim type box, cylinder and prism. 7500 // Prim type box, cylinder and prism.
6971 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) 7501 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)
6972 { 7502 {
7503 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7504 return;
7505
6973 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7506 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6974 ObjectShapePacket.ObjectDataBlock shapeBlock; 7507 ObjectShapePacket.ObjectDataBlock shapeBlock;
6975 7508
@@ -7023,6 +7556,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7023 // Prim type sphere. 7556 // Prim type sphere.
7024 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7557 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7025 { 7558 {
7559 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7560 return;
7561
7026 ObjectShapePacket.ObjectDataBlock shapeBlock; 7562 ObjectShapePacket.ObjectDataBlock shapeBlock;
7027 7563
7028 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7564 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7064,6 +7600,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7064 // Prim type torus, tube and ring. 7600 // Prim type torus, tube and ring.
7065 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) 7601 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)
7066 { 7602 {
7603 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7604 return;
7605
7067 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7606 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7068 ObjectShapePacket.ObjectDataBlock shapeBlock; 7607 ObjectShapePacket.ObjectDataBlock shapeBlock;
7069 7608
@@ -7199,6 +7738,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7199 // Prim type sculpt. 7738 // Prim type sculpt.
7200 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7739 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7201 { 7740 {
7741 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7742 return;
7743
7202 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7744 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7203 UUID sculptId; 7745 UUID sculptId;
7204 7746
@@ -7221,7 +7763,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7221 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7763 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7222 { 7764 {
7223 // default 7765 // default
7224 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7766 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7225 } 7767 }
7226 7768
7227 part.Shape.SetSculptProperties((byte)type, sculptId); 7769 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7238,48 +7780,130 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7238 ScriptSleep(200); 7780 ScriptSleep(200);
7239 } 7781 }
7240 7782
7241 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7783 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7242 { 7784 {
7243 m_host.AddScriptLPS(1); 7785 m_host.AddScriptLPS(1);
7244 7786
7245 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7787 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7788 }
7246 7789
7247 ScriptSleep(200); 7790 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7791 {
7792 List<object> parts = new List<object>();
7793 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7794 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7795 foreach (SceneObjectPart p in prims)
7796 parts.Add(p);
7797 foreach (ScenePresence p in avatars)
7798 parts.Add(p);
7799
7800 LSL_List remaining = null;
7801 uint rulesParsed = 0;
7802
7803 if (parts.Count > 0)
7804 {
7805 foreach (object part in parts)
7806 {
7807 if (part is SceneObjectPart)
7808 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7809 else
7810 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7811 }
7812
7813 while ((object)remaining != null && remaining.Length > 2)
7814 {
7815 linknumber = remaining.GetLSLIntegerItem(0);
7816 rules = remaining.GetSublist(1, -1);
7817 parts.Clear();
7818 prims = GetLinkParts(linknumber);
7819 avatars = GetLinkAvatars(linknumber);
7820 foreach (SceneObjectPart p in prims)
7821 parts.Add(p);
7822 foreach (ScenePresence p in avatars)
7823 parts.Add(p);
7824
7825 remaining = null;
7826 foreach (object part in parts)
7827 {
7828 if (part is SceneObjectPart)
7829 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7830 else
7831 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7832 }
7833 }
7834 }
7248 } 7835 }
7249 7836
7250 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7837 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7838 float material_density, float material_friction,
7839 float material_restitution, float material_gravity_modifier)
7251 { 7840 {
7252 m_host.AddScriptLPS(1); 7841 ExtraPhysicsData physdata = new ExtraPhysicsData();
7842 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7843 physdata.Density = part.Density;
7844 physdata.Friction = part.Friction;
7845 physdata.Bounce = part.Restitution;
7846 physdata.GravitationModifier = part.GravityModifier;
7253 7847
7254 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7848 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7849 physdata.Density = material_density;
7850 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7851 physdata.Friction = material_friction;
7852 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7853 physdata.Bounce = material_restitution;
7854 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7855 physdata.GravitationModifier = material_gravity_modifier;
7856
7857 part.UpdateExtraPhysics(physdata);
7255 } 7858 }
7256 7859
7257 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7860 public void llSetPhysicsMaterial(int material_bits,
7861 float material_gravity_modifier, float material_restitution,
7862 float material_friction, float material_density)
7258 { 7863 {
7259 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7864 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7865 }
7260 7866
7261 LSL_List remaining = null; 7867 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7262 uint rulesParsed = 0; 7868 {
7869 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7870 llSetLinkPrimitiveParamsFast(linknumber, rules);
7871 ScriptSleep(200);
7872 }
7263 7873
7264 foreach (SceneObjectPart part in parts) 7874 // vector up using libomv (c&p from sop )
7265 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7875 // vector up rotated by r
7876 private Vector3 Zrot(Quaternion r)
7877 {
7878 double x, y, z, m;
7266 7879
7267 while (remaining != null && remaining.Length > 2) 7880 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7881 if (Math.Abs(1.0 - m) > 0.000001)
7268 { 7882 {
7269 linknumber = remaining.GetLSLIntegerItem(0); 7883 m = 1.0 / Math.Sqrt(m);
7270 rules = remaining.GetSublist(1, -1); 7884 r.X *= (float)m;
7271 parts = GetLinkParts(linknumber); 7885 r.Y *= (float)m;
7272 7886 r.Z *= (float)m;
7273 foreach (SceneObjectPart part in parts) 7887 r.W *= (float)m;
7274 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7275 } 7888 }
7889
7890 x = 2 * (r.X * r.Z + r.Y * r.W);
7891 y = 2 * (-r.X * r.W + r.Y * r.Z);
7892 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7893
7894 return new Vector3((float)x, (float)y, (float)z);
7276 } 7895 }
7277 7896
7278 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7897 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7279 { 7898 {
7899 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7900 return null;
7901
7280 int idx = 0; 7902 int idx = 0;
7281 int idxStart = 0; 7903 int idxStart = 0;
7282 7904
7905 SceneObjectGroup parentgrp = part.ParentGroup;
7906
7283 bool positionChanged = false; 7907 bool positionChanged = false;
7284 LSL_Vector currentPosition = GetPartLocalPos(part); 7908 LSL_Vector currentPosition = GetPartLocalPos(part);
7285 7909
@@ -7304,8 +7928,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7304 return null; 7928 return null;
7305 7929
7306 v=rules.GetVector3Item(idx++); 7930 v=rules.GetVector3Item(idx++);
7931 if (part.IsRoot && !part.ParentGroup.IsAttachment)
7932 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
7933 else
7934 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7307 positionChanged = true; 7935 positionChanged = true;
7308 currentPosition = GetSetPosTarget(part, v, currentPosition);
7309 7936
7310 break; 7937 break;
7311 case (int)ScriptBaseClass.PRIM_SIZE: 7938 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7322,7 +7949,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7322 7949
7323 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7950 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7324 // try to let this work as in SL... 7951 // try to let this work as in SL...
7325 if (part.ParentID == 0) 7952 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7326 { 7953 {
7327 // special case: If we are root, rotate complete SOG to new rotation 7954 // special case: If we are root, rotate complete SOG to new rotation
7328 SetRot(part, q); 7955 SetRot(part, q);
@@ -7582,7 +8209,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7582 return null; 8209 return null;
7583 8210
7584 string ph = rules.Data[idx++].ToString(); 8211 string ph = rules.Data[idx++].ToString();
7585 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8212 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7586 8213
7587 break; 8214 break;
7588 8215
@@ -7616,12 +8243,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7616 8243
7617 break; 8244 break;
7618 8245
8246 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8247 if (remain < 5)
8248 return null;
8249
8250 int material_bits = rules.GetLSLIntegerItem(idx++);
8251 float material_density = (float)rules.GetLSLFloatItem(idx++);
8252 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8253 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8254 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8255
8256 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8257
8258 break;
8259
7619 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8260 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7620 if (remain < 1) 8261 if (remain < 1)
7621 return null; 8262 return null;
7622 string temp = rules.Data[idx++].ToString(); 8263 string temp = rules.Data[idx++].ToString();
7623 8264
7624 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8265 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7625 8266
7626 break; 8267 break;
7627 8268
@@ -7695,14 +8336,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7695 if (part.ParentGroup.RootPart == part) 8336 if (part.ParentGroup.RootPart == part)
7696 { 8337 {
7697 SceneObjectGroup parent = part.ParentGroup; 8338 SceneObjectGroup parent = part.ParentGroup;
7698 parent.UpdateGroupPosition(currentPosition); 8339 Util.FireAndForget(delegate(object x) {
8340 parent.UpdateGroupPosition(currentPosition);
8341 });
7699 } 8342 }
7700 else 8343 else
7701 { 8344 {
7702 part.OffsetPosition = currentPosition; 8345 part.OffsetPosition = currentPosition;
7703 SceneObjectGroup parent = part.ParentGroup; 8346// SceneObjectGroup parent = part.ParentGroup;
7704 parent.HasGroupChanged = true; 8347// parent.HasGroupChanged = true;
7705 parent.ScheduleGroupForTerseUpdate(); 8348// parent.ScheduleGroupForTerseUpdate();
8349 part.ScheduleTerseUpdate();
7706 } 8350 }
7707 } 8351 }
7708 } 8352 }
@@ -7740,10 +8384,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7740 8384
7741 public LSL_String llXorBase64Strings(string str1, string str2) 8385 public LSL_String llXorBase64Strings(string str1, string str2)
7742 { 8386 {
7743 m_host.AddScriptLPS(1); 8387 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7744 Deprecated("llXorBase64Strings"); 8388
7745 ScriptSleep(300); 8389 ScriptSleep(300);
7746 return String.Empty; 8390 m_host.AddScriptLPS(1);
8391
8392 if (str1 == String.Empty)
8393 return String.Empty;
8394 if (str2 == String.Empty)
8395 return str1;
8396
8397 int len = str2.Length;
8398 if ((len % 4) != 0) // LL is EVIL!!!!
8399 {
8400 while (str2.EndsWith("="))
8401 str2 = str2.Substring(0, str2.Length - 1);
8402
8403 len = str2.Length;
8404 int mod = len % 4;
8405
8406 if (mod == 1)
8407 str2 = str2.Substring(0, str2.Length - 1);
8408 else if (mod == 2)
8409 str2 += "==";
8410 else if (mod == 3)
8411 str2 += "=";
8412 }
8413
8414 byte[] data1;
8415 byte[] data2;
8416 try
8417 {
8418 data1 = Convert.FromBase64String(str1);
8419 data2 = Convert.FromBase64String(str2);
8420 }
8421 catch (Exception)
8422 {
8423 return new LSL_String(String.Empty);
8424 }
8425
8426 // For cases where the decoded length of s2 is greater
8427 // than the decoded length of s1, simply perform a normal
8428 // decode and XOR
8429 //
8430 if (data2.Length >= data1.Length)
8431 {
8432 for (int pos = 0 ; pos < data1.Length ; pos++ )
8433 data1[pos] ^= data2[pos];
8434
8435 return Convert.ToBase64String(data1);
8436 }
8437
8438 // Remove padding
8439 while (str1.EndsWith("="))
8440 str1 = str1.Substring(0, str1.Length - 1);
8441 while (str2.EndsWith("="))
8442 str2 = str2.Substring(0, str2.Length - 1);
8443
8444 byte[] d1 = new byte[str1.Length];
8445 byte[] d2 = new byte[str2.Length];
8446
8447 for (int i = 0 ; i < str1.Length ; i++)
8448 {
8449 int idx = b64.IndexOf(str1.Substring(i, 1));
8450 if (idx == -1)
8451 idx = 0;
8452 d1[i] = (byte)idx;
8453 }
8454
8455 for (int i = 0 ; i < str2.Length ; i++)
8456 {
8457 int idx = b64.IndexOf(str2.Substring(i, 1));
8458 if (idx == -1)
8459 idx = 0;
8460 d2[i] = (byte)idx;
8461 }
8462
8463 string output = String.Empty;
8464
8465 for (int pos = 0 ; pos < d1.Length ; pos++)
8466 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8467
8468 while (output.Length % 3 > 0)
8469 output += "=";
8470
8471 return output;
7747 } 8472 }
7748 8473
7749 public void llRemoteDataSetRegion() 8474 public void llRemoteDataSetRegion()
@@ -7868,8 +8593,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7868 public LSL_Integer llGetNumberOfPrims() 8593 public LSL_Integer llGetNumberOfPrims()
7869 { 8594 {
7870 m_host.AddScriptLPS(1); 8595 m_host.AddScriptLPS(1);
7871 8596 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7872 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8597
8598 return m_host.ParentGroup.PrimCount + avatarCount;
7873 } 8599 }
7874 8600
7875 /// <summary> 8601 /// <summary>
@@ -7884,55 +8610,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7884 m_host.AddScriptLPS(1); 8610 m_host.AddScriptLPS(1);
7885 UUID objID = UUID.Zero; 8611 UUID objID = UUID.Zero;
7886 LSL_List result = new LSL_List(); 8612 LSL_List result = new LSL_List();
8613
8614 // If the ID is not valid, return null result
7887 if (!UUID.TryParse(obj, out objID)) 8615 if (!UUID.TryParse(obj, out objID))
7888 { 8616 {
7889 result.Add(new LSL_Vector()); 8617 result.Add(new LSL_Vector());
7890 result.Add(new LSL_Vector()); 8618 result.Add(new LSL_Vector());
7891 return result; 8619 return result;
7892 } 8620 }
8621
8622 // Check if this is an attached prim. If so, replace
8623 // the UUID with the avatar UUID and report it's bounding box
8624 SceneObjectPart part = World.GetSceneObjectPart(objID);
8625 if (part != null && part.ParentGroup.IsAttachment)
8626 objID = part.ParentGroup.AttachedAvatar;
8627
8628 // Find out if this is an avatar ID. If so, return it's box
7893 ScenePresence presence = World.GetScenePresence(objID); 8629 ScenePresence presence = World.GetScenePresence(objID);
7894 if (presence != null) 8630 if (presence != null)
7895 { 8631 {
7896 if (presence.ParentID == 0) // not sat on an object 8632 // As per LSL Wiki, there is no difference between sitting
8633 // and standing avatar since server 1.36
8634 LSL_Vector lower;
8635 LSL_Vector upper;
8636
8637 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8638
8639 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8640 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8641/*
7897 { 8642 {
7898 LSL_Vector lower; 8643 // This is for ground sitting avatars
7899 LSL_Vector upper; 8644 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7900 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8645 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7901 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8646 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7902 {
7903 // This is for ground sitting avatars
7904 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7905 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7906 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7907 }
7908 else
7909 {
7910 // This is for standing/flying avatars
7911 float height = presence.Appearance.AvatarHeight / 2.0f;
7912 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7913 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7914 }
7915 result.Add(lower);
7916 result.Add(upper);
7917 return result;
7918 } 8647 }
7919 else 8648 else
7920 { 8649 {
7921 // sitting on an object so we need the bounding box of that 8650 // This is for standing/flying avatars
7922 // which should include the avatar so set the UUID to the 8651 float height = presence.Appearance.AvatarHeight / 2.0f;
7923 // UUID of the object the avatar is sat on and allow it to fall through 8652 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7924 // to processing an object 8653 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7925 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7926 objID = p.UUID;
7927 } 8654 }
8655
8656 // Adjust to the documented error offsets (see LSL Wiki)
8657 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8658 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8659*/
8660 {
8661 // This is for ground sitting avatars TODO!
8662 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8663 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
8664 }
8665 else
8666 {
8667 // This is for standing/flying avatars
8668 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8669 upper = new LSL_Vector(box.X, box.Y, box.Z);
8670 }
8671
8672 if (lower.x > upper.x)
8673 lower.x = upper.x;
8674 if (lower.y > upper.y)
8675 lower.y = upper.y;
8676 if (lower.z > upper.z)
8677 lower.z = upper.z;
8678
8679 result.Add(lower);
8680 result.Add(upper);
8681 return result;
7928 } 8682 }
7929 SceneObjectPart part = World.GetSceneObjectPart(objID); 8683
8684 part = World.GetSceneObjectPart(objID);
7930 // Currently only works for single prims without a sitting avatar 8685 // Currently only works for single prims without a sitting avatar
7931 if (part != null) 8686 if (part != null)
7932 { 8687 {
7933 Vector3 halfSize = part.Scale / 2.0f; 8688 float minX;
7934 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8689 float maxX;
7935 LSL_Vector upper = new LSL_Vector(halfSize); 8690 float minY;
8691 float maxY;
8692 float minZ;
8693 float maxZ;
8694
8695 // This BBox is in sim coordinates, with the offset being
8696 // a contained point.
8697 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8698 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8699
8700 minX -= offsets[0].X;
8701 maxX -= offsets[0].X;
8702 minY -= offsets[0].Y;
8703 maxY -= offsets[0].Y;
8704 minZ -= offsets[0].Z;
8705 maxZ -= offsets[0].Z;
8706
8707 LSL_Vector lower;
8708 LSL_Vector upper;
8709
8710 // Adjust to the documented error offsets (see LSL Wiki)
8711 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8712 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8713
8714 if (lower.x > upper.x)
8715 lower.x = upper.x;
8716 if (lower.y > upper.y)
8717 lower.y = upper.y;
8718 if (lower.z > upper.z)
8719 lower.z = upper.z;
8720
7936 result.Add(lower); 8721 result.Add(lower);
7937 result.Add(upper); 8722 result.Add(upper);
7938 return result; 8723 return result;
@@ -7949,224 +8734,74 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7949 return new LSL_Vector(m_host.GetGeometricCenter()); 8734 return new LSL_Vector(m_host.GetGeometricCenter());
7950 } 8735 }
7951 8736
7952 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 8737 public LSL_List llGetPrimitiveParams(LSL_List rules)
7953 { 8738 {
7954 LSL_List result = new LSL_List(); 8739 m_host.AddScriptLPS(1);
7955 LSL_List remaining = null;
7956 8740
7957 while (true) 8741 LSL_List result = new LSL_List();
7958 {
7959 if (entity is SceneObjectPart)
7960 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result);
7961 else
7962 remaining = GetAgentParams((ScenePresence)entity, rules, ref result);
7963 8742
7964 if (remaining == null || remaining.Length <= 2) 8743 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
7965 return result;
7966 8744
8745 while ((object)remaining != null && remaining.Length > 2)
8746 {
7967 int linknumber = remaining.GetLSLIntegerItem(0); 8747 int linknumber = remaining.GetLSLIntegerItem(0);
7968 rules = remaining.GetSublist(1, -1); 8748 rules = remaining.GetSublist(1, -1);
7969 entity = GetLinkEntity(linknumber); 8749 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7970 }
7971 }
7972 8750
7973 public LSL_List llGetPrimitiveParams(LSL_List rules) 8751 foreach (SceneObjectPart part in parts)
7974 { 8752 remaining = GetPrimParams(part, rules, ref result);
7975 m_host.AddScriptLPS(1); 8753 }
7976 8754
7977 return GetEntityParams(m_host, rules); 8755 return result;
7978 } 8756 }
7979 8757
7980 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8758 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
7981 { 8759 {
7982 m_host.AddScriptLPS(1); 8760 m_host.AddScriptLPS(1);
7983 8761
7984 return GetEntityParams(GetLinkEntity(linknumber), rules); 8762 // acording to SL wiki this must indicate a single link number or link_root or link_this.
7985 } 8763 // keep other options as before
7986 8764
7987 public LSL_Vector GetAgentSize(ScenePresence sp) 8765 List<SceneObjectPart> parts;
7988 { 8766 List<ScenePresence> avatars;
7989 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); 8767
7990 } 8768 LSL_List res = new LSL_List();
8769 LSL_List remaining = null;
7991 8770
7992 /// <summary> 8771 while (rules.Length > 0)
7993 /// Gets params for a seated avatar in a linkset.
7994 /// </summary>
7995 /// <returns></returns>
7996 /// <param name='sp'></param>
7997 /// <param name='rules'></param>
7998 /// <param name='res'></param>
7999 public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res)
8000 {
8001 int idx = 0;
8002 while (idx < rules.Length)
8003 { 8772 {
8004 int code = (int)rules.GetLSLIntegerItem(idx++); 8773 parts = GetLinkParts(linknumber);
8005 int remain = rules.Length-idx; 8774 avatars = GetLinkAvatars(linknumber);
8006 8775
8007 switch (code) 8776 remaining = null;
8777 foreach (SceneObjectPart part in parts)
8008 { 8778 {
8009 case (int)ScriptBaseClass.PRIM_MATERIAL: 8779 remaining = GetPrimParams(part, rules, ref res);
8010 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 8780 }
8011 break; 8781 foreach (ScenePresence avatar in avatars)
8012 8782 {
8013 case (int)ScriptBaseClass.PRIM_PHYSICS: 8783 remaining = GetPrimParams(avatar, rules, ref res);
8014 res.Add(ScriptBaseClass.FALSE); 8784 }
8015 break;
8016
8017 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8018 res.Add(ScriptBaseClass.FALSE);
8019 break;
8020
8021 case (int)ScriptBaseClass.PRIM_PHANTOM:
8022 res.Add(ScriptBaseClass.FALSE);
8023 break;
8024
8025 case (int)ScriptBaseClass.PRIM_POSITION:
8026 res.Add(new LSL_Vector(sp.AbsolutePosition));
8027 break;
8028
8029 case (int)ScriptBaseClass.PRIM_SIZE:
8030 res.Add(GetAgentSize(sp));
8031 break;
8032
8033 case (int)ScriptBaseClass.PRIM_ROTATION:
8034 res.Add(sp.GetWorldRotation());
8035 break;
8036
8037 case (int)ScriptBaseClass.PRIM_TYPE:
8038 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8039 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8040 res.Add(new LSL_Vector(0, 1, 0));
8041 res.Add(new LSL_Float(0));
8042 res.Add(new LSL_Vector(0, 0, 0));
8043 res.Add(new LSL_Vector(1, 1, 0));
8044 res.Add(new LSL_Vector(0, 0, 0));
8045 break;
8046
8047 case (int)ScriptBaseClass.PRIM_TEXTURE:
8048 if (remain < 1)
8049 return null;
8050
8051 int face = (int)rules.GetLSLIntegerItem(idx++);
8052 if (face > 21)
8053 break;
8054
8055 res.Add(new LSL_String(""));
8056 res.Add(ScriptBaseClass.ZERO_VECTOR);
8057 res.Add(ScriptBaseClass.ZERO_VECTOR);
8058 res.Add(new LSL_Float(0));
8059 break;
8060
8061 case (int)ScriptBaseClass.PRIM_COLOR:
8062 if (remain < 1)
8063 return null;
8064
8065 face = (int)rules.GetLSLIntegerItem(idx++);
8066 if (face > 21)
8067 break;
8068
8069 res.Add(ScriptBaseClass.ZERO_VECTOR);
8070 res.Add(new LSL_Float(0));
8071 break;
8072
8073 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8074 if (remain < 1)
8075 return null;
8076
8077 face = (int)rules.GetLSLIntegerItem(idx++);
8078 if (face > 21)
8079 break;
8080
8081 res.Add(ScriptBaseClass.PRIM_SHINY_NONE);
8082 res.Add(ScriptBaseClass.PRIM_BUMP_NONE);
8083 break;
8084
8085 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8086 if (remain < 1)
8087 return null;
8088
8089 face = (int)rules.GetLSLIntegerItem(idx++);
8090 if (face > 21)
8091 break;
8092
8093 res.Add(ScriptBaseClass.FALSE);
8094 break;
8095
8096 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8097 res.Add(ScriptBaseClass.FALSE);
8098 res.Add(new LSL_Integer(0));
8099 res.Add(new LSL_Float(0));
8100 res.Add(new LSL_Float(0));
8101 res.Add(new LSL_Float(0));
8102 res.Add(new LSL_Float(0));
8103 res.Add(ScriptBaseClass.ZERO_VECTOR);
8104 break;
8105
8106 case (int)ScriptBaseClass.PRIM_TEXGEN:
8107 if (remain < 1)
8108 return null;
8109
8110 face = (int)rules.GetLSLIntegerItem(idx++);
8111 if (face > 21)
8112 break;
8113
8114 res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT);
8115 break;
8116
8117 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8118 res.Add(ScriptBaseClass.FALSE);
8119 res.Add(ScriptBaseClass.ZERO_VECTOR);
8120 res.Add(ScriptBaseClass.ZERO_VECTOR);
8121 break;
8122
8123 case (int)ScriptBaseClass.PRIM_GLOW:
8124 if (remain < 1)
8125 return null;
8126
8127 face = (int)rules.GetLSLIntegerItem(idx++);
8128 if (face > 21)
8129 break;
8130
8131 res.Add(new LSL_Float(0));
8132 break;
8133
8134 case (int)ScriptBaseClass.PRIM_TEXT:
8135 res.Add(new LSL_String(""));
8136 res.Add(ScriptBaseClass.ZERO_VECTOR);
8137 res.Add(new LSL_Float(1));
8138 break;
8139
8140 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8141 res.Add(new LSL_Rotation(sp.Rotation));
8142 break;
8143
8144 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8145 res.Add(new LSL_Vector(sp.OffsetPosition));
8146 break;
8147
8148 case (int)ScriptBaseClass.PRIM_SLICE:
8149 res.Add(new LSL_Vector(0, 1, 0));
8150 break;
8151
8152 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8153 if(remain < 3)
8154 return null;
8155 8785
8156 return rules.GetSublist(idx, -1); 8786 if ((object)remaining != null && remaining.Length > 0)
8787 {
8788 linknumber = remaining.GetLSLIntegerItem(0);
8789 rules = remaining.GetSublist(1, -1);
8157 } 8790 }
8791 else
8792 break;
8158 } 8793 }
8159 8794
8160 return null; 8795 return res;
8161 } 8796 }
8162 8797
8163 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 8798 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
8164 { 8799 {
8165 int idx = 0; 8800 int idx=0;
8166 while (idx < rules.Length) 8801 while (idx < rules.Length)
8167 { 8802 {
8168 int code = (int)rules.GetLSLIntegerItem(idx++); 8803 int code=(int)rules.GetLSLIntegerItem(idx++);
8169 int remain = rules.Length-idx; 8804 int remain=rules.Length-idx;
8170 8805
8171 switch (code) 8806 switch (code)
8172 { 8807 {
@@ -8196,19 +8831,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8196 break; 8831 break;
8197 8832
8198 case (int)ScriptBaseClass.PRIM_POSITION: 8833 case (int)ScriptBaseClass.PRIM_POSITION:
8199 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 8834 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8200 8835 part.AbsolutePosition.Y,
8201 // For some reason, the part.AbsolutePosition.* values do not change if the 8836 part.AbsolutePosition.Z);
8202 // linkset is rotated; they always reflect the child prim's world position
8203 // as though the linkset is unrotated. This is incompatible behavior with SL's
8204 // implementation, so will break scripts imported from there (not to mention it
8205 // makes it more difficult to determine a child prim's actual inworld position).
8206 if (!part.IsRoot)
8207 {
8208 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8209 v = ((v - rootPos) * llGetRootRotation()) + rootPos;
8210 }
8211
8212 res.Add(v); 8837 res.Add(v);
8213 break; 8838 break;
8214 8839
@@ -8378,30 +9003,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8378 if (remain < 1) 9003 if (remain < 1)
8379 return null; 9004 return null;
8380 9005
8381 face=(int)rules.GetLSLIntegerItem(idx++); 9006 face = (int)rules.GetLSLIntegerItem(idx++);
8382 9007
8383 tex = part.Shape.Textures; 9008 tex = part.Shape.Textures;
9009 int shiny;
8384 if (face == ScriptBaseClass.ALL_SIDES) 9010 if (face == ScriptBaseClass.ALL_SIDES)
8385 { 9011 {
8386 for (face = 0; face < GetNumberOfSides(part); face++) 9012 for (face = 0; face < GetNumberOfSides(part); face++)
8387 { 9013 {
8388 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9014 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8389 // Convert Shininess to PRIM_SHINY_* 9015 if (shinyness == Shininess.High)
8390 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9016 {
8391 // PRIM_BUMP_* 9017 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8392 res.Add(new LSL_Integer((int)texface.Bump)); 9018 }
9019 else if (shinyness == Shininess.Medium)
9020 {
9021 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9022 }
9023 else if (shinyness == Shininess.Low)
9024 {
9025 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9026 }
9027 else
9028 {
9029 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9030 }
9031 res.Add(new LSL_Integer(shiny));
9032 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8393 } 9033 }
8394 } 9034 }
8395 else 9035 else
8396 { 9036 {
8397 if (face >= 0 && face < GetNumberOfSides(part)) 9037 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9038 if (shinyness == Shininess.High)
8398 { 9039 {
8399 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9040 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8400 // Convert Shininess to PRIM_SHINY_* 9041 }
8401 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9042 else if (shinyness == Shininess.Medium)
8402 // PRIM_BUMP_* 9043 {
8403 res.Add(new LSL_Integer((int)texface.Bump)); 9044 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9045 }
9046 else if (shinyness == Shininess.Low)
9047 {
9048 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9049 }
9050 else
9051 {
9052 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8404 } 9053 }
9054 res.Add(new LSL_Integer(shiny));
9055 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8405 } 9056 }
8406 break; 9057 break;
8407 9058
@@ -8412,21 +9063,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8412 face = (int)rules.GetLSLIntegerItem(idx++); 9063 face = (int)rules.GetLSLIntegerItem(idx++);
8413 9064
8414 tex = part.Shape.Textures; 9065 tex = part.Shape.Textures;
9066 int fullbright;
8415 if (face == ScriptBaseClass.ALL_SIDES) 9067 if (face == ScriptBaseClass.ALL_SIDES)
8416 { 9068 {
8417 for (face = 0; face < GetNumberOfSides(part); face++) 9069 for (face = 0; face < GetNumberOfSides(part); face++)
8418 { 9070 {
8419 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9071 if (tex.GetFace((uint)face).Fullbright == true)
8420 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9072 {
9073 fullbright = ScriptBaseClass.TRUE;
9074 }
9075 else
9076 {
9077 fullbright = ScriptBaseClass.FALSE;
9078 }
9079 res.Add(new LSL_Integer(fullbright));
8421 } 9080 }
8422 } 9081 }
8423 else 9082 else
8424 { 9083 {
8425 if (face >= 0 && face < GetNumberOfSides(part)) 9084 if (tex.GetFace((uint)face).Fullbright == true)
8426 { 9085 {
8427 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9086 fullbright = ScriptBaseClass.TRUE;
8428 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9087 }
9088 else
9089 {
9090 fullbright = ScriptBaseClass.FALSE;
8429 } 9091 }
9092 res.Add(new LSL_Integer(fullbright));
8430 } 9093 }
8431 break; 9094 break;
8432 9095
@@ -8448,27 +9111,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8448 break; 9111 break;
8449 9112
8450 case (int)ScriptBaseClass.PRIM_TEXGEN: 9113 case (int)ScriptBaseClass.PRIM_TEXGEN:
9114 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8451 if (remain < 1) 9115 if (remain < 1)
8452 return null; 9116 return null;
8453 9117
8454 face=(int)rules.GetLSLIntegerItem(idx++); 9118 face = (int)rules.GetLSLIntegerItem(idx++);
8455 9119
8456 tex = part.Shape.Textures; 9120 tex = part.Shape.Textures;
8457 if (face == ScriptBaseClass.ALL_SIDES) 9121 if (face == ScriptBaseClass.ALL_SIDES)
8458 { 9122 {
8459 for (face = 0; face < GetNumberOfSides(part); face++) 9123 for (face = 0; face < GetNumberOfSides(part); face++)
8460 { 9124 {
8461 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9125 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8462 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9126 {
8463 res.Add(new LSL_Integer((uint)texgen >> 1)); 9127 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9128 }
9129 else
9130 {
9131 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9132 }
8464 } 9133 }
8465 } 9134 }
8466 else 9135 else
8467 { 9136 {
8468 if (face >= 0 && face < GetNumberOfSides(part)) 9137 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9138 {
9139 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9140 }
9141 else
8469 { 9142 {
8470 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9143 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8471 res.Add(new LSL_Integer((uint)texgen >> 1));
8472 } 9144 }
8473 } 9145 }
8474 break; 9146 break;
@@ -8492,24 +9164,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8492 if (remain < 1) 9164 if (remain < 1)
8493 return null; 9165 return null;
8494 9166
8495 face=(int)rules.GetLSLIntegerItem(idx++); 9167 face = (int)rules.GetLSLIntegerItem(idx++);
8496 9168
8497 tex = part.Shape.Textures; 9169 tex = part.Shape.Textures;
9170 float primglow;
8498 if (face == ScriptBaseClass.ALL_SIDES) 9171 if (face == ScriptBaseClass.ALL_SIDES)
8499 { 9172 {
8500 for (face = 0; face < GetNumberOfSides(part); face++) 9173 for (face = 0; face < GetNumberOfSides(part); face++)
8501 { 9174 {
8502 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9175 primglow = tex.GetFace((uint)face).Glow;
8503 res.Add(new LSL_Float(texface.Glow)); 9176 res.Add(new LSL_Float(primglow));
8504 } 9177 }
8505 } 9178 }
8506 else 9179 else
8507 { 9180 {
8508 if (face >= 0 && face < GetNumberOfSides(part)) 9181 primglow = tex.GetFace((uint)face).Glow;
8509 { 9182 res.Add(new LSL_Float(primglow));
8510 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8511 res.Add(new LSL_Float(texface.Glow));
8512 }
8513 } 9183 }
8514 break; 9184 break;
8515 9185
@@ -8521,15 +9191,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8521 textColor.B)); 9191 textColor.B));
8522 res.Add(new LSL_Float(textColor.A)); 9192 res.Add(new LSL_Float(textColor.A));
8523 break; 9193 break;
9194
8524 case (int)ScriptBaseClass.PRIM_NAME: 9195 case (int)ScriptBaseClass.PRIM_NAME:
8525 res.Add(new LSL_String(part.Name)); 9196 res.Add(new LSL_String(part.Name));
8526 break; 9197 break;
9198
8527 case (int)ScriptBaseClass.PRIM_DESC: 9199 case (int)ScriptBaseClass.PRIM_DESC:
8528 res.Add(new LSL_String(part.Description)); 9200 res.Add(new LSL_String(part.Description));
8529 break; 9201 break;
8530 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9202 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8531 res.Add(new LSL_Rotation(part.RotationOffset)); 9203 res.Add(new LSL_Rotation(part.RotationOffset));
8532 break; 9204 break;
9205
8533 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9206 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8534 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9207 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8535 break; 9208 break;
@@ -9140,8 +9813,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9140 // The function returns an ordered list 9813 // The function returns an ordered list
9141 // representing the tokens found in the supplied 9814 // representing the tokens found in the supplied
9142 // sources string. If two successive tokenizers 9815 // sources string. If two successive tokenizers
9143 // are encountered, then a NULL entry is added 9816 // are encountered, then a null-string entry is
9144 // to the list. 9817 // added to the list.
9145 // 9818 //
9146 // It is a precondition that the source and 9819 // It is a precondition that the source and
9147 // toekizer lisst are non-null. If they are null, 9820 // toekizer lisst are non-null. If they are null,
@@ -9149,7 +9822,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9149 // while their lengths are being determined. 9822 // while their lengths are being determined.
9150 // 9823 //
9151 // A small amount of working memoryis required 9824 // A small amount of working memoryis required
9152 // of approximately 8*#tokenizers. 9825 // of approximately 8*#tokenizers + 8*srcstrlen.
9153 // 9826 //
9154 // There are many ways in which this function 9827 // There are many ways in which this function
9155 // can be implemented, this implementation is 9828 // can be implemented, this implementation is
@@ -9165,155 +9838,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9165 // and eliminates redundant tokenizers as soon 9838 // and eliminates redundant tokenizers as soon
9166 // as is possible. 9839 // as is possible.
9167 // 9840 //
9168 // The implementation tries to avoid any copying 9841 // The implementation tries to minimize temporary
9169 // of arrays or other objects. 9842 // garbage generation.
9170 // </remarks> 9843 // </remarks>
9171 9844
9172 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9845 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9173 { 9846 {
9174 int beginning = 0; 9847 return ParseString2List(src, separators, spacers, true);
9175 int srclen = src.Length; 9848 }
9176 int seplen = separators.Length;
9177 object[] separray = separators.Data;
9178 int spclen = spacers.Length;
9179 object[] spcarray = spacers.Data;
9180 int mlen = seplen+spclen;
9181
9182 int[] offset = new int[mlen+1];
9183 bool[] active = new bool[mlen];
9184
9185 int best;
9186 int j;
9187
9188 // Initial capacity reduces resize cost
9189 9849
9190 LSL_List tokens = new LSL_List(); 9850 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9851 {
9852 int srclen = src.Length;
9853 int seplen = separators.Length;
9854 object[] separray = separators.Data;
9855 int spclen = spacers.Length;
9856 object[] spcarray = spacers.Data;
9857 int dellen = 0;
9858 string[] delarray = new string[seplen+spclen];
9191 9859
9192 // All entries are initially valid 9860 int outlen = 0;
9861 string[] outarray = new string[srclen*2+1];
9193 9862
9194 for (int i = 0; i < mlen; i++) 9863 int i, j;
9195 active[i] = true; 9864 string d;
9196 9865
9197 offset[mlen] = srclen; 9866 m_host.AddScriptLPS(1);
9198 9867
9199 while (beginning < srclen) 9868 /*
9869 * Convert separator and spacer lists to C# strings.
9870 * Also filter out null strings so we don't hang.
9871 */
9872 for (i = 0; i < seplen; i ++)
9200 { 9873 {
9874 d = separray[i].ToString();
9875 if (d.Length > 0)
9876 {
9877 delarray[dellen++] = d;
9878 }
9879 }
9880 seplen = dellen;
9201 9881
9202 best = mlen; // as bad as it gets 9882 for (i = 0; i < spclen; i ++)
9883 {
9884 d = spcarray[i].ToString();
9885 if (d.Length > 0)
9886 {
9887 delarray[dellen++] = d;
9888 }
9889 }
9203 9890
9204 // Scan for separators 9891 /*
9892 * Scan through source string from beginning to end.
9893 */
9894 for (i = 0;;)
9895 {
9205 9896
9206 for (j = 0; j < seplen; j++) 9897 /*
9898 * Find earliest delimeter in src starting at i (if any).
9899 */
9900 int earliestDel = -1;
9901 int earliestSrc = srclen;
9902 string earliestStr = null;
9903 for (j = 0; j < dellen; j ++)
9207 { 9904 {
9208 if (separray[j].ToString() == String.Empty) 9905 d = delarray[j];
9209 active[j] = false; 9906 if (d != null)
9210
9211 if (active[j])
9212 { 9907 {
9213 // scan all of the markers 9908 int index = src.IndexOf(d, i);
9214 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9909 if (index < 0)
9215 { 9910 {
9216 // not present at all 9911 delarray[j] = null; // delim nowhere in src, don't check it anymore
9217 active[j] = false;
9218 } 9912 }
9219 else 9913 else if (index < earliestSrc)
9220 { 9914 {
9221 // present and correct 9915 earliestSrc = index; // where delimeter starts in source string
9222 if (offset[j] < offset[best]) 9916 earliestDel = j; // where delimeter is in delarray[]
9223 { 9917 earliestStr = d; // the delimeter string from delarray[]
9224 // closest so far 9918 if (index == i) break; // can't do any better than found at beg of string
9225 best = j;
9226 if (offset[best] == beginning)
9227 break;
9228 }
9229 } 9919 }
9230 } 9920 }
9231 } 9921 }
9232 9922
9233 // Scan for spacers 9923 /*
9234 9924 * Output source string starting at i through start of earliest delimeter.
9235 if (offset[best] != beginning) 9925 */
9926 if (keepNulls || (earliestSrc > i))
9236 { 9927 {
9237 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9928 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9238 {
9239 if (spcarray[j-seplen].ToString() == String.Empty)
9240 active[j] = false;
9241
9242 if (active[j])
9243 {
9244 // scan all of the markers
9245 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9246 {
9247 // not present at all
9248 active[j] = false;
9249 }
9250 else
9251 {
9252 // present and correct
9253 if (offset[j] < offset[best])
9254 {
9255 // closest so far
9256 best = j;
9257 }
9258 }
9259 }
9260 }
9261 } 9929 }
9262 9930
9263 // This is the normal exit from the scanning loop 9931 /*
9932 * If no delimeter found at or after i, we're done scanning.
9933 */
9934 if (earliestDel < 0) break;
9264 9935
9265 if (best == mlen) 9936 /*
9937 * If delimeter was a spacer, output the spacer.
9938 */
9939 if (earliestDel >= seplen)
9266 { 9940 {
9267 // no markers were found on this pass 9941 outarray[outlen++] = earliestStr;
9268 // so we're pretty much done
9269 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9270 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9271 break;
9272 } 9942 }
9273 9943
9274 // Otherwise we just add the newly delimited token 9944 /*
9275 // and recalculate where the search should continue. 9945 * Look at rest of src string following delimeter.
9276 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9946 */
9277 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9947 i = earliestSrc + earliestStr.Length;
9278
9279 if (best < seplen)
9280 {
9281 beginning = offset[best] + (separray[best].ToString()).Length;
9282 }
9283 else
9284 {
9285 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9286 string str = spcarray[best - seplen].ToString();
9287 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9288 tokens.Add(new LSL_String(str));
9289 }
9290 } 9948 }
9291 9949
9292 // This an awkward an not very intuitive boundary case. If the 9950 /*
9293 // last substring is a tokenizer, then there is an implied trailing 9951 * Make up an exact-sized output array suitable for an LSL_List object.
9294 // null list entry. Hopefully the single comparison will not be too 9952 */
9295 // arduous. Alternatively the 'break' could be replced with a return 9953 object[] outlist = new object[outlen];
9296 // but that's shabby programming. 9954 for (i = 0; i < outlen; i ++)
9297
9298 if ((beginning == srclen) && (keepNulls))
9299 { 9955 {
9300 if (srclen != 0) 9956 outlist[i] = new LSL_String(outarray[i]);
9301 tokens.Add(new LSL_String(""));
9302 } 9957 }
9303 9958 return new LSL_List(outlist);
9304 return tokens;
9305 }
9306
9307 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9308 {
9309 m_host.AddScriptLPS(1);
9310 return this.ParseString(src, separators, spacers, false);
9311 }
9312
9313 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9314 {
9315 m_host.AddScriptLPS(1);
9316 return this.ParseString(src, separators, spacers, true);
9317 } 9959 }
9318 9960
9319 public LSL_Integer llGetObjectPermMask(int mask) 9961 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9408,6 +10050,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9408 case 4: 10050 case 4:
9409 return (int)item.NextPermissions; 10051 return (int)item.NextPermissions;
9410 } 10052 }
10053 m_host.TaskInventory.LockItemsForRead(false);
9411 10054
9412 return -1; 10055 return -1;
9413 } 10056 }
@@ -9611,31 +10254,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9611 UUID key = new UUID(); 10254 UUID key = new UUID();
9612 if (UUID.TryParse(id, out key)) 10255 if (UUID.TryParse(id, out key))
9613 { 10256 {
9614 try 10257 // return total object mass
9615 { 10258 SceneObjectPart part = World.GetSceneObjectPart(key);
9616 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10259 if (part != null)
9617 if (obj != null) 10260 return part.ParentGroup.GetMass();
9618 return (double)obj.GetMass(); 10261
9619 // the object is null so the key is for an avatar 10262 // the object is null so the key is for an avatar
9620 ScenePresence avatar = World.GetScenePresence(key); 10263 ScenePresence avatar = World.GetScenePresence(key);
9621 if (avatar != null) 10264 if (avatar != null)
9622 if (avatar.IsChildAgent)
9623 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9624 // child agents have a mass of 1.0
9625 return 1;
9626 else
9627 return (double)avatar.GetMass();
9628 }
9629 catch (KeyNotFoundException)
9630 { 10265 {
9631 return 0; // The Object/Agent not in the region so just return zero 10266 if (avatar.IsChildAgent)
10267 {
10268 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10269 // child agents have a mass of 1.0
10270 return 1;
10271 }
10272 else
10273 {
10274 return (double)avatar.GetMass();
10275 }
9632 } 10276 }
9633 } 10277 }
9634 return 0; 10278 return 0;
9635 } 10279 }
9636 10280
9637 /// <summary> 10281 /// <summary>
9638 /// illListReplaceList removes the sub-list defined by the inclusive indices 10282 /// llListReplaceList removes the sub-list defined by the inclusive indices
9639 /// start and end and inserts the src list in its place. The inclusive 10283 /// start and end and inserts the src list in its place. The inclusive
9640 /// nature of the indices means that at least one element must be deleted 10284 /// nature of the indices means that at least one element must be deleted
9641 /// if the indices are within the bounds of the existing list. I.e. 2,2 10285 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9692,16 +10336,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9692 // based upon end. Note that if end exceeds the upper 10336 // based upon end. Note that if end exceeds the upper
9693 // bound in this case, the entire destination list 10337 // bound in this case, the entire destination list
9694 // is removed. 10338 // is removed.
9695 else 10339 else if (start == 0)
9696 { 10340 {
9697 if (end + 1 < dest.Length) 10341 if (end + 1 < dest.Length)
9698 {
9699 return src + dest.GetSublist(end + 1, -1); 10342 return src + dest.GetSublist(end + 1, -1);
9700 }
9701 else 10343 else
9702 {
9703 return src; 10344 return src;
9704 } 10345 }
10346 else // Start < 0
10347 {
10348 if (end + 1 < dest.Length)
10349 return dest.GetSublist(end + 1, -1);
10350 else
10351 return new LSL_List();
9705 } 10352 }
9706 } 10353 }
9707 // Finally, if start > end, we strip away a prefix and 10354 // Finally, if start > end, we strip away a prefix and
@@ -9752,17 +10399,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9752 int width = 0; 10399 int width = 0;
9753 int height = 0; 10400 int height = 0;
9754 10401
9755 ParcelMediaCommandEnum? commandToSend = null; 10402 uint commandToSend = 0;
9756 float time = 0.0f; // default is from start 10403 float time = 0.0f; // default is from start
9757 10404
9758 ScenePresence presence = null; 10405 ScenePresence presence = null;
9759 10406
9760 for (int i = 0; i < commandList.Data.Length; i++) 10407 for (int i = 0; i < commandList.Data.Length; i++)
9761 { 10408 {
9762 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10409 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9763 switch (command) 10410 switch (command)
9764 { 10411 {
9765 case ParcelMediaCommandEnum.Agent: 10412 case (uint)ParcelMediaCommandEnum.Agent:
9766 // we send only to one agent 10413 // we send only to one agent
9767 if ((i + 1) < commandList.Length) 10414 if ((i + 1) < commandList.Length)
9768 { 10415 {
@@ -9779,25 +10426,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9779 } 10426 }
9780 break; 10427 break;
9781 10428
9782 case ParcelMediaCommandEnum.Loop: 10429 case (uint)ParcelMediaCommandEnum.Loop:
9783 loop = 1; 10430 loop = 1;
9784 commandToSend = command; 10431 commandToSend = command;
9785 update = true; //need to send the media update packet to set looping 10432 update = true; //need to send the media update packet to set looping
9786 break; 10433 break;
9787 10434
9788 case ParcelMediaCommandEnum.Play: 10435 case (uint)ParcelMediaCommandEnum.Play:
9789 loop = 0; 10436 loop = 0;
9790 commandToSend = command; 10437 commandToSend = command;
9791 update = true; //need to send the media update packet to make sure it doesn't loop 10438 update = true; //need to send the media update packet to make sure it doesn't loop
9792 break; 10439 break;
9793 10440
9794 case ParcelMediaCommandEnum.Pause: 10441 case (uint)ParcelMediaCommandEnum.Pause:
9795 case ParcelMediaCommandEnum.Stop: 10442 case (uint)ParcelMediaCommandEnum.Stop:
9796 case ParcelMediaCommandEnum.Unload: 10443 case (uint)ParcelMediaCommandEnum.Unload:
9797 commandToSend = command; 10444 commandToSend = command;
9798 break; 10445 break;
9799 10446
9800 case ParcelMediaCommandEnum.Url: 10447 case (uint)ParcelMediaCommandEnum.Url:
9801 if ((i + 1) < commandList.Length) 10448 if ((i + 1) < commandList.Length)
9802 { 10449 {
9803 if (commandList.Data[i + 1] is LSL_String) 10450 if (commandList.Data[i + 1] is LSL_String)
@@ -9810,7 +10457,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9810 } 10457 }
9811 break; 10458 break;
9812 10459
9813 case ParcelMediaCommandEnum.Texture: 10460 case (uint)ParcelMediaCommandEnum.Texture:
9814 if ((i + 1) < commandList.Length) 10461 if ((i + 1) < commandList.Length)
9815 { 10462 {
9816 if (commandList.Data[i + 1] is LSL_String) 10463 if (commandList.Data[i + 1] is LSL_String)
@@ -9823,7 +10470,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9823 } 10470 }
9824 break; 10471 break;
9825 10472
9826 case ParcelMediaCommandEnum.Time: 10473 case (uint)ParcelMediaCommandEnum.Time:
9827 if ((i + 1) < commandList.Length) 10474 if ((i + 1) < commandList.Length)
9828 { 10475 {
9829 if (commandList.Data[i + 1] is LSL_Float) 10476 if (commandList.Data[i + 1] is LSL_Float)
@@ -9835,7 +10482,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9835 } 10482 }
9836 break; 10483 break;
9837 10484
9838 case ParcelMediaCommandEnum.AutoAlign: 10485 case (uint)ParcelMediaCommandEnum.AutoAlign:
9839 if ((i + 1) < commandList.Length) 10486 if ((i + 1) < commandList.Length)
9840 { 10487 {
9841 if (commandList.Data[i + 1] is LSL_Integer) 10488 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9849,7 +10496,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9849 } 10496 }
9850 break; 10497 break;
9851 10498
9852 case ParcelMediaCommandEnum.Type: 10499 case (uint)ParcelMediaCommandEnum.Type:
9853 if ((i + 1) < commandList.Length) 10500 if ((i + 1) < commandList.Length)
9854 { 10501 {
9855 if (commandList.Data[i + 1] is LSL_String) 10502 if (commandList.Data[i + 1] is LSL_String)
@@ -9862,7 +10509,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9862 } 10509 }
9863 break; 10510 break;
9864 10511
9865 case ParcelMediaCommandEnum.Desc: 10512 case (uint)ParcelMediaCommandEnum.Desc:
9866 if ((i + 1) < commandList.Length) 10513 if ((i + 1) < commandList.Length)
9867 { 10514 {
9868 if (commandList.Data[i + 1] is LSL_String) 10515 if (commandList.Data[i + 1] is LSL_String)
@@ -9875,7 +10522,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9875 } 10522 }
9876 break; 10523 break;
9877 10524
9878 case ParcelMediaCommandEnum.Size: 10525 case (uint)ParcelMediaCommandEnum.Size:
9879 if ((i + 2) < commandList.Length) 10526 if ((i + 2) < commandList.Length)
9880 { 10527 {
9881 if (commandList.Data[i + 1] is LSL_Integer) 10528 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9945,7 +10592,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9945 } 10592 }
9946 } 10593 }
9947 10594
9948 if (commandToSend != null) 10595 if (commandToSend != 0)
9949 { 10596 {
9950 // the commandList contained a start/stop/... command, too 10597 // the commandList contained a start/stop/... command, too
9951 if (presence == null) 10598 if (presence == null)
@@ -9982,7 +10629,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9982 10629
9983 if (aList.Data[i] != null) 10630 if (aList.Data[i] != null)
9984 { 10631 {
9985 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10632 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9986 { 10633 {
9987 case ParcelMediaCommandEnum.Url: 10634 case ParcelMediaCommandEnum.Url:
9988 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10635 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -10039,15 +10686,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10039 10686
10040 if (quick_pay_buttons.Data.Length < 4) 10687 if (quick_pay_buttons.Data.Length < 4)
10041 { 10688 {
10042 LSLError("List must have at least 4 elements"); 10689 int x;
10043 return; 10690 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10691 {
10692 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10693 }
10044 } 10694 }
10045 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10695 int[] nPrice = new int[5];
10046 10696 nPrice[0] = price;
10047 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10697 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
10048 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10698 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
10049 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10699 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
10050 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10700 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10701 m_host.ParentGroup.RootPart.PayPrice = nPrice;
10051 m_host.ParentGroup.HasGroupChanged = true; 10702 m_host.ParentGroup.HasGroupChanged = true;
10052 } 10703 }
10053 10704
@@ -10064,7 +10715,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10064 return Vector3.Zero; 10715 return Vector3.Zero;
10065 } 10716 }
10066 10717
10067 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10718// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10719 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10068 if (presence != null) 10720 if (presence != null)
10069 { 10721 {
10070 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 10722 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
@@ -10087,7 +10739,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10087 return Quaternion.Identity; 10739 return Quaternion.Identity;
10088 } 10740 }
10089 10741
10090 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10742// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10743 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10091 if (presence != null) 10744 if (presence != null)
10092 { 10745 {
10093 return new LSL_Rotation(presence.CameraRotation); 10746 return new LSL_Rotation(presence.CameraRotation);
@@ -10147,14 +10800,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10147 { 10800 {
10148 m_host.AddScriptLPS(1); 10801 m_host.AddScriptLPS(1);
10149 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10802 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10150 if (detectedParams == null) return; // only works on the first detected avatar 10803 if (detectedParams == null)
10151 10804 {
10805 if (m_host.ParentGroup.IsAttachment == true)
10806 {
10807 detectedParams = new DetectParams();
10808 detectedParams.Key = m_host.OwnerID;
10809 }
10810 else
10811 {
10812 return;
10813 }
10814 }
10815
10152 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10816 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10153 if (avatar != null) 10817 if (avatar != null)
10154 { 10818 {
10155 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10819 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10156 simname, pos, lookAt); 10820 simname, pos, lookAt);
10157 } 10821 }
10822
10158 ScriptSleep(1000); 10823 ScriptSleep(1000);
10159 } 10824 }
10160 10825
@@ -10278,12 +10943,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10278 10943
10279 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10944 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10280 object[] data = rules.Data; 10945 object[] data = rules.Data;
10281 for (int i = 0; i < data.Length; ++i) { 10946 for (int i = 0; i < data.Length; ++i)
10947 {
10282 int type = Convert.ToInt32(data[i++].ToString()); 10948 int type = Convert.ToInt32(data[i++].ToString());
10283 if (i >= data.Length) break; // odd number of entries => ignore the last 10949 if (i >= data.Length) break; // odd number of entries => ignore the last
10284 10950
10285 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10951 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10286 switch (type) { 10952 switch (type)
10953 {
10287 case ScriptBaseClass.CAMERA_FOCUS: 10954 case ScriptBaseClass.CAMERA_FOCUS:
10288 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10955 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10289 case ScriptBaseClass.CAMERA_POSITION: 10956 case ScriptBaseClass.CAMERA_POSITION:
@@ -10388,19 +11055,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10388 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11055 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10389 { 11056 {
10390 m_host.AddScriptLPS(1); 11057 m_host.AddScriptLPS(1);
10391 string ret = String.Empty; 11058
10392 string src1 = llBase64ToString(str1); 11059 if (str1 == String.Empty)
10393 string src2 = llBase64ToString(str2); 11060 return String.Empty;
10394 int c = 0; 11061 if (str2 == String.Empty)
10395 for (int i = 0; i < src1.Length; i++) 11062 return str1;
11063
11064 int len = str2.Length;
11065 if ((len % 4) != 0) // LL is EVIL!!!!
11066 {
11067 while (str2.EndsWith("="))
11068 str2 = str2.Substring(0, str2.Length - 1);
11069
11070 len = str2.Length;
11071 int mod = len % 4;
11072
11073 if (mod == 1)
11074 str2 = str2.Substring(0, str2.Length - 1);
11075 else if (mod == 2)
11076 str2 += "==";
11077 else if (mod == 3)
11078 str2 += "=";
11079 }
11080
11081 byte[] data1;
11082 byte[] data2;
11083 try
11084 {
11085 data1 = Convert.FromBase64String(str1);
11086 data2 = Convert.FromBase64String(str2);
11087 }
11088 catch (Exception)
11089 {
11090 return new LSL_String(String.Empty);
11091 }
11092
11093 byte[] d2 = new Byte[data1.Length];
11094 int pos = 0;
11095
11096 if (data1.Length <= data2.Length)
11097 {
11098 Array.Copy(data2, 0, d2, 0, data1.Length);
11099 }
11100 else
10396 { 11101 {
10397 ret += (char) (src1[i] ^ src2[c]); 11102 while (pos < data1.Length)
11103 {
11104 len = data1.Length - pos;
11105 if (len > data2.Length)
11106 len = data2.Length;
10398 11107
10399 c++; 11108 Array.Copy(data2, 0, d2, pos, len);
10400 if (c >= src2.Length) 11109 pos += len;
10401 c = 0; 11110 }
10402 } 11111 }
10403 return llStringToBase64(ret); 11112
11113 for (pos = 0 ; pos < data1.Length ; pos++ )
11114 data1[pos] ^= d2[pos];
11115
11116 return Convert.ToBase64String(data1);
10404 } 11117 }
10405 11118
10406 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11119 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10453,16 +11166,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10453 if (userAgent != null) 11166 if (userAgent != null)
10454 httpHeaders["User-Agent"] = userAgent; 11167 httpHeaders["User-Agent"] = userAgent;
10455 11168
11169 // See if the URL contains any header hacks
11170 string[] urlParts = url.Split(new char[] {'\n'});
11171 if (urlParts.Length > 1)
11172 {
11173 // Iterate the passed headers and parse them
11174 for (int i = 1 ; i < urlParts.Length ; i++ )
11175 {
11176 // The rest of those would be added to the body in SL.
11177 // Let's not do that.
11178 if (urlParts[i] == String.Empty)
11179 break;
11180
11181 // See if this could be a valid header
11182 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11183 if (headerParts.Length != 2)
11184 continue;
11185
11186 string headerName = headerParts[0].Trim();
11187 string headerValue = headerParts[1].Trim();
11188
11189 // Filter out headers that could be used to abuse
11190 // another system or cloak the request
11191 if (headerName.ToLower() == "x-secondlife-shard" ||
11192 headerName.ToLower() == "x-secondlife-object-name" ||
11193 headerName.ToLower() == "x-secondlife-object-key" ||
11194 headerName.ToLower() == "x-secondlife-region" ||
11195 headerName.ToLower() == "x-secondlife-local-position" ||
11196 headerName.ToLower() == "x-secondlife-local-velocity" ||
11197 headerName.ToLower() == "x-secondlife-local-rotation" ||
11198 headerName.ToLower() == "x-secondlife-owner-name" ||
11199 headerName.ToLower() == "x-secondlife-owner-key" ||
11200 headerName.ToLower() == "connection" ||
11201 headerName.ToLower() == "content-length" ||
11202 headerName.ToLower() == "from" ||
11203 headerName.ToLower() == "host" ||
11204 headerName.ToLower() == "proxy-authorization" ||
11205 headerName.ToLower() == "referer" ||
11206 headerName.ToLower() == "trailer" ||
11207 headerName.ToLower() == "transfer-encoding" ||
11208 headerName.ToLower() == "via" ||
11209 headerName.ToLower() == "authorization")
11210 continue;
11211
11212 httpHeaders[headerName] = headerValue;
11213 }
11214
11215 // Finally, strip any protocol specifier from the URL
11216 url = urlParts[0].Trim();
11217 int idx = url.IndexOf(" HTTP/");
11218 if (idx != -1)
11219 url = url.Substring(0, idx);
11220 }
11221
10456 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11222 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10457 Regex r = new Regex(authregex); 11223 Regex r = new Regex(authregex);
10458 int[] gnums = r.GetGroupNumbers(); 11224 int[] gnums = r.GetGroupNumbers();
10459 Match m = r.Match(url); 11225 Match m = r.Match(url);
10460 if (m.Success) { 11226 if (m.Success)
10461 for (int i = 1; i < gnums.Length; i++) { 11227 {
11228 for (int i = 1; i < gnums.Length; i++)
11229 {
10462 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11230 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10463 //CaptureCollection cc = g.Captures; 11231 //CaptureCollection cc = g.Captures;
10464 } 11232 }
10465 if (m.Groups.Count == 5) { 11233 if (m.Groups.Count == 5)
11234 {
10466 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11235 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10467 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11236 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10468 } 11237 }
@@ -10665,6 +11434,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10665 11434
10666 LSL_List ret = new LSL_List(); 11435 LSL_List ret = new LSL_List();
10667 UUID key = new UUID(); 11436 UUID key = new UUID();
11437
11438
10668 if (UUID.TryParse(id, out key)) 11439 if (UUID.TryParse(id, out key))
10669 { 11440 {
10670 ScenePresence av = World.GetScenePresence(key); 11441 ScenePresence av = World.GetScenePresence(key);
@@ -10682,13 +11453,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10682 ret.Add(new LSL_String("")); 11453 ret.Add(new LSL_String(""));
10683 break; 11454 break;
10684 case ScriptBaseClass.OBJECT_POS: 11455 case ScriptBaseClass.OBJECT_POS:
10685 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11456 Vector3 avpos;
11457
11458 if (av.ParentID != 0 && av.ParentPart != null)
11459 {
11460 avpos = av.OffsetPosition;
11461
11462 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11463 avpos -= sitOffset;
11464
11465 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11466 }
11467 else
11468 avpos = av.AbsolutePosition;
11469
11470 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10686 break; 11471 break;
10687 case ScriptBaseClass.OBJECT_ROT: 11472 case ScriptBaseClass.OBJECT_ROT:
10688 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 11473 Quaternion avrot = av.Rotation;
11474 if (av.ParentID != 0 && av.ParentPart != null)
11475 {
11476 avrot = av.ParentPart.GetWorldRotation() * avrot;
11477 }
11478 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10689 break; 11479 break;
10690 case ScriptBaseClass.OBJECT_VELOCITY: 11480 case ScriptBaseClass.OBJECT_VELOCITY:
10691 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11481 Vector3 avvel = av.Velocity;
11482 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10692 break; 11483 break;
10693 case ScriptBaseClass.OBJECT_OWNER: 11484 case ScriptBaseClass.OBJECT_OWNER:
10694 ret.Add(new LSL_String(id)); 11485 ret.Add(new LSL_String(id));
@@ -10773,11 +11564,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10773 case ScriptBaseClass.OBJECT_NAME: 11564 case ScriptBaseClass.OBJECT_NAME:
10774 ret.Add(new LSL_String(obj.Name)); 11565 ret.Add(new LSL_String(obj.Name));
10775 break; 11566 break;
10776 case ScriptBaseClass.OBJECT_DESC: 11567 case ScriptBaseClass.OBJECT_DESC:
10777 ret.Add(new LSL_String(obj.Description)); 11568 ret.Add(new LSL_String(obj.Description));
10778 break; 11569 break;
10779 case ScriptBaseClass.OBJECT_POS: 11570 case ScriptBaseClass.OBJECT_POS:
10780 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11571 Vector3 opos = obj.AbsolutePosition;
11572 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10781 break; 11573 break;
10782 case ScriptBaseClass.OBJECT_ROT: 11574 case ScriptBaseClass.OBJECT_ROT:
10783 { 11575 {
@@ -10827,9 +11619,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10827 // The value returned in SL for normal prims is prim count 11619 // The value returned in SL for normal prims is prim count
10828 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11620 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10829 break; 11621 break;
10830 // The following 3 costs I have intentionaly coded to return zero. They are part of 11622
10831 // "Land Impact" calculations. These calculations are probably not applicable 11623 // costs below may need to be diferent for root parts, need to check
10832 // to OpenSim and are not yet complete in SL
10833 case ScriptBaseClass.OBJECT_SERVER_COST: 11624 case ScriptBaseClass.OBJECT_SERVER_COST:
10834 // The linden calculation is here 11625 // The linden calculation is here
10835 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11626 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10837,16 +11628,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10837 ret.Add(new LSL_Float(0)); 11628 ret.Add(new LSL_Float(0));
10838 break; 11629 break;
10839 case ScriptBaseClass.OBJECT_STREAMING_COST: 11630 case ScriptBaseClass.OBJECT_STREAMING_COST:
10840 // The linden calculation is here 11631 // The value returned in SL for normal prims is prim count * 0.06
10841 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11632 ret.Add(new LSL_Float(obj.StreamingCost));
10842 // The value returned in SL for normal prims looks like the prim count * 0.06
10843 ret.Add(new LSL_Float(0));
10844 break; 11633 break;
10845 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11634 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10846 // The linden calculation is here 11635 // The value returned in SL for normal prims is prim count
10847 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11636 ret.Add(new LSL_Float(obj.PhysicsCost));
10848 // The value returned in SL for normal prims looks like the prim count
10849 ret.Add(new LSL_Float(0));
10850 break; 11637 break;
10851 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11638 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
10852 ret.Add(new LSL_Float(0)); 11639 ret.Add(new LSL_Float(0));
@@ -11105,15 +11892,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11105 return result; 11892 return result;
11106 } 11893 }
11107 11894
11108 public void print(string str) 11895 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
11109 { 11896 {
11110 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11897 List<SceneObjectPart> parts = GetLinkParts(link);
11111 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11898 if (parts.Count < 1)
11112 if (ossl != null) 11899 return 0;
11113 { 11900
11114 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11901 return GetNumberOfSides(parts[0]);
11115 m_log.Info("LSL print():" + str);
11116 }
11117 } 11902 }
11118 11903
11119 private string Name2Username(string name) 11904 private string Name2Username(string name)
@@ -11158,7 +11943,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11158 11943
11159 return rq.ToString(); 11944 return rq.ToString();
11160 } 11945 }
11161 11946/*
11947 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11948 {
11949 m_SayShoutCount = 0;
11950 }
11951*/
11162 private struct Tri 11952 private struct Tri
11163 { 11953 {
11164 public Vector3 p1; 11954 public Vector3 p1;
@@ -11307,9 +12097,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11307 12097
11308 ContactResult result = new ContactResult (); 12098 ContactResult result = new ContactResult ();
11309 result.ConsumerID = group.LocalId; 12099 result.ConsumerID = group.LocalId;
11310 result.Depth = intersection.distance; 12100// result.Depth = intersection.distance;
11311 result.Normal = intersection.normal; 12101 result.Normal = intersection.normal;
11312 result.Pos = intersection.ipoint; 12102 result.Pos = intersection.ipoint;
12103 result.Depth = Vector3.Mag(rayStart - result.Pos);
11313 12104
11314 contacts.Add(result); 12105 contacts.Add(result);
11315 }); 12106 });
@@ -11442,6 +12233,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11442 12233
11443 return contacts[0]; 12234 return contacts[0];
11444 } 12235 }
12236/*
12237 // not done:
12238 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12239 {
12240 ContactResult[] contacts = null;
12241 World.ForEachSOG(delegate(SceneObjectGroup group)
12242 {
12243 if (m_host.ParentGroup == group)
12244 return;
12245
12246 if (group.IsAttachment)
12247 return;
12248
12249 if(group.RootPart.PhysActor != null)
12250 return;
12251
12252 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12253 });
12254 return contacts;
12255 }
12256*/
11445 12257
11446 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12258 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11447 { 12259 {
@@ -11565,18 +12377,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11565 } 12377 }
11566 } 12378 }
11567 12379
12380 // Double check this
11568 if (checkTerrain) 12381 if (checkTerrain)
11569 { 12382 {
11570 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12383 bool skipGroundCheck = false;
11571 if (groundContact != null) 12384
11572 results.Add((ContactResult)groundContact); 12385 foreach (ContactResult c in results)
12386 {
12387 if (c.ConsumerID == 0) // Physics gave us a ground collision
12388 skipGroundCheck = true;
12389 }
12390
12391 if (!skipGroundCheck)
12392 {
12393 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12394 if (groundContact != null)
12395 results.Add((ContactResult)groundContact);
12396 }
11573 } 12397 }
11574 12398
11575 results.Sort(delegate(ContactResult a, ContactResult b) 12399 results.Sort(delegate(ContactResult a, ContactResult b)
11576 { 12400 {
11577 return a.Depth.CompareTo(b.Depth); 12401 return a.Depth.CompareTo(b.Depth);
11578 }); 12402 });
11579 12403
11580 int values = 0; 12404 int values = 0;
11581 SceneObjectGroup thisgrp = m_host.ParentGroup; 12405 SceneObjectGroup thisgrp = m_host.ParentGroup;
11582 12406
@@ -11669,7 +12493,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11669 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12493 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11670 if (!isAccount) return 0; 12494 if (!isAccount) return 0;
11671 if (estate.HasAccess(id)) return 1; 12495 if (estate.HasAccess(id)) return 1;
11672 if (estate.IsBanned(id)) 12496 if (estate.IsBanned(id, World.GetUserFlags(id)))
11673 estate.RemoveBan(id); 12497 estate.RemoveBan(id);
11674 estate.AddEstateUser(id); 12498 estate.AddEstateUser(id);
11675 break; 12499 break;
@@ -11688,14 +12512,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11688 break; 12512 break;
11689 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12513 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11690 if (!isAccount) return 0; 12514 if (!isAccount) return 0;
11691 if (estate.IsBanned(id)) return 1; 12515 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11692 EstateBan ban = new EstateBan(); 12516 EstateBan ban = new EstateBan();
11693 ban.EstateID = estate.EstateID; 12517 ban.EstateID = estate.EstateID;
11694 ban.BannedUserID = id; 12518 ban.BannedUserID = id;
11695 estate.AddBan(ban); 12519 estate.AddBan(ban);
11696 break; 12520 break;
11697 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12521 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11698 if (!isAccount || !estate.IsBanned(id)) return 0; 12522 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11699 estate.RemoveBan(id); 12523 estate.RemoveBan(id);
11700 break; 12524 break;
11701 default: return 0; 12525 default: return 0;
@@ -11752,19 +12576,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11752 public void llSetSoundQueueing(int queue) 12576 public void llSetSoundQueueing(int queue)
11753 { 12577 {
11754 m_host.AddScriptLPS(1); 12578 m_host.AddScriptLPS(1);
11755 NotImplemented("llSetSoundQueueing");
11756 } 12579 }
11757 12580
11758 public void llCollisionSprite(string impact_sprite) 12581 public void llCollisionSprite(string impact_sprite)
11759 { 12582 {
11760 m_host.AddScriptLPS(1); 12583 m_host.AddScriptLPS(1);
11761 NotImplemented("llCollisionSprite"); 12584 // Viewer 2.0 broke this and it's likely LL has no intention
12585 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11762 } 12586 }
11763 12587
11764 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12588 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11765 { 12589 {
11766 m_host.AddScriptLPS(1); 12590 m_host.AddScriptLPS(1);
11767 NotImplemented("llGodLikeRezObject"); 12591
12592 if (!World.Permissions.IsGod(m_host.OwnerID))
12593 NotImplemented("llGodLikeRezObject");
12594
12595 AssetBase rezAsset = World.AssetService.Get(inventory);
12596 if (rezAsset == null)
12597 {
12598 llSay(0, "Asset not found");
12599 return;
12600 }
12601
12602 SceneObjectGroup group = null;
12603
12604 try
12605 {
12606 string xmlData = Utils.BytesToString(rezAsset.Data);
12607 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12608 }
12609 catch
12610 {
12611 llSay(0, "Asset not found");
12612 return;
12613 }
12614
12615 if (group == null)
12616 {
12617 llSay(0, "Asset not found");
12618 return;
12619 }
12620
12621 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12622 group.RootPart.AttachOffset = group.AbsolutePosition;
12623
12624 group.ResetIDs();
12625
12626 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12627 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12628 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12629 group.ScheduleGroupForFullUpdate();
12630
12631 // objects rezzed with this method are die_at_edge by default.
12632 group.RootPart.SetDieAtEdge(true);
12633
12634 group.ResumeScripts();
12635
12636 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12637 "object_rez", new Object[] {
12638 new LSL_String(
12639 group.RootPart.UUID.ToString()) },
12640 new DetectParams[0]));
11768 } 12641 }
11769 12642
11770 public LSL_String llTransferLindenDollars(string destination, int amount) 12643 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -11816,7 +12689,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11816 } 12689 }
11817 12690
11818 bool result = money.ObjectGiveMoney( 12691 bool result = money.ObjectGiveMoney(
11819 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12692 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn);
11820 12693
11821 if (result) 12694 if (result)
11822 { 12695 {
@@ -11841,6 +12714,598 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11841 } 12714 }
11842 12715
11843 #endregion 12716 #endregion
12717
12718 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12719 {
12720 SceneObjectGroup group = m_host.ParentGroup;
12721
12722 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12723 return;
12724 if (group.IsAttachment)
12725 return;
12726
12727 if (frames.Data.Length > 0) // We are getting a new motion
12728 {
12729 if (group.RootPart.KeyframeMotion != null)
12730 group.RootPart.KeyframeMotion.Delete();
12731 group.RootPart.KeyframeMotion = null;
12732
12733 int idx = 0;
12734
12735 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12736 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12737
12738 while (idx < options.Data.Length)
12739 {
12740 int option = (int)options.GetLSLIntegerItem(idx++);
12741 int remain = options.Data.Length - idx;
12742
12743 switch (option)
12744 {
12745 case ScriptBaseClass.KFM_MODE:
12746 if (remain < 1)
12747 break;
12748 int modeval = (int)options.GetLSLIntegerItem(idx++);
12749 switch(modeval)
12750 {
12751 case ScriptBaseClass.KFM_FORWARD:
12752 mode = KeyframeMotion.PlayMode.Forward;
12753 break;
12754 case ScriptBaseClass.KFM_REVERSE:
12755 mode = KeyframeMotion.PlayMode.Reverse;
12756 break;
12757 case ScriptBaseClass.KFM_LOOP:
12758 mode = KeyframeMotion.PlayMode.Loop;
12759 break;
12760 case ScriptBaseClass.KFM_PING_PONG:
12761 mode = KeyframeMotion.PlayMode.PingPong;
12762 break;
12763 }
12764 break;
12765 case ScriptBaseClass.KFM_DATA:
12766 if (remain < 1)
12767 break;
12768 int dataval = (int)options.GetLSLIntegerItem(idx++);
12769 data = (KeyframeMotion.DataFormat)dataval;
12770 break;
12771 }
12772 }
12773
12774 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12775
12776 idx = 0;
12777
12778 int elemLength = 2;
12779 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12780 elemLength = 3;
12781
12782 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12783 while (idx < frames.Data.Length)
12784 {
12785 int remain = frames.Data.Length - idx;
12786
12787 if (remain < elemLength)
12788 break;
12789
12790 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12791 frame.Position = null;
12792 frame.Rotation = null;
12793
12794 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12795 {
12796 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12797 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12798 }
12799 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12800 {
12801 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12802 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12803 q.Normalize();
12804 frame.Rotation = q;
12805 }
12806
12807 float tempf = (float)frames.GetLSLFloatItem(idx++);
12808 frame.TimeMS = (int)(tempf * 1000.0f);
12809
12810 keyframes.Add(frame);
12811 }
12812
12813 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12814 group.RootPart.KeyframeMotion.Start();
12815 }
12816 else
12817 {
12818 if (group.RootPart.KeyframeMotion == null)
12819 return;
12820
12821 if (options.Data.Length == 0)
12822 {
12823 group.RootPart.KeyframeMotion.Stop();
12824 return;
12825 }
12826
12827 int code = (int)options.GetLSLIntegerItem(0);
12828
12829 int idx = 0;
12830
12831 while (idx < options.Data.Length)
12832 {
12833 int option = (int)options.GetLSLIntegerItem(idx++);
12834 int remain = options.Data.Length - idx;
12835
12836 switch (option)
12837 {
12838 case ScriptBaseClass.KFM_COMMAND:
12839 int cmd = (int)options.GetLSLIntegerItem(idx++);
12840 switch (cmd)
12841 {
12842 case ScriptBaseClass.KFM_CMD_PLAY:
12843 group.RootPart.KeyframeMotion.Start();
12844 break;
12845 case ScriptBaseClass.KFM_CMD_STOP:
12846 group.RootPart.KeyframeMotion.Stop();
12847 break;
12848 case ScriptBaseClass.KFM_CMD_PAUSE:
12849 group.RootPart.KeyframeMotion.Pause();
12850 break;
12851 }
12852 break;
12853 }
12854 }
12855 }
12856 }
12857
12858 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12859 {
12860 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12861
12862 int idx = 0;
12863 int idxStart = 0;
12864
12865 bool positionChanged = false;
12866 Vector3 finalPos = Vector3.Zero;
12867
12868 try
12869 {
12870 while (idx < rules.Length)
12871 {
12872 ++rulesParsed;
12873 int code = rules.GetLSLIntegerItem(idx++);
12874
12875 int remain = rules.Length - idx;
12876 idxStart = idx;
12877
12878 switch (code)
12879 {
12880 case (int)ScriptBaseClass.PRIM_POSITION:
12881 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12882 {
12883 if (remain < 1)
12884 return null;
12885
12886 LSL_Vector v;
12887 v = rules.GetVector3Item(idx++);
12888
12889 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12890 if (part == null)
12891 break;
12892
12893 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12894 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12895 if (part.LinkNum > 1)
12896 {
12897 localRot = GetPartLocalRot(part);
12898 localPos = GetPartLocalPos(part);
12899 }
12900
12901 v -= localPos;
12902 v /= localRot;
12903
12904 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12905
12906 v = v + 2 * sitOffset;
12907
12908 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12909 av.SendAvatarDataToAllAgents();
12910
12911 }
12912 break;
12913
12914 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12915 case (int)ScriptBaseClass.PRIM_ROTATION:
12916 {
12917 if (remain < 1)
12918 return null;
12919
12920 LSL_Rotation r;
12921 r = rules.GetQuaternionItem(idx++);
12922
12923 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12924 if (part == null)
12925 break;
12926
12927 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12928 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12929
12930 if (part.LinkNum > 1)
12931 localRot = GetPartLocalRot(part);
12932
12933 r = r * llGetRootRotation() / localRot;
12934 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12935 av.SendAvatarDataToAllAgents();
12936 }
12937 break;
12938
12939 // parse rest doing nothing but number of parameters error check
12940 case (int)ScriptBaseClass.PRIM_SIZE:
12941 case (int)ScriptBaseClass.PRIM_MATERIAL:
12942 case (int)ScriptBaseClass.PRIM_PHANTOM:
12943 case (int)ScriptBaseClass.PRIM_PHYSICS:
12944 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12945 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12946 case (int)ScriptBaseClass.PRIM_NAME:
12947 case (int)ScriptBaseClass.PRIM_DESC:
12948 if (remain < 1)
12949 return null;
12950 idx++;
12951 break;
12952
12953 case (int)ScriptBaseClass.PRIM_GLOW:
12954 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12955 case (int)ScriptBaseClass.PRIM_TEXGEN:
12956 if (remain < 2)
12957 return null;
12958 idx += 2;
12959 break;
12960
12961 case (int)ScriptBaseClass.PRIM_TYPE:
12962 if (remain < 3)
12963 return null;
12964 code = (int)rules.GetLSLIntegerItem(idx++);
12965 remain = rules.Length - idx;
12966 switch (code)
12967 {
12968 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12969 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12970 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12971 if (remain < 6)
12972 return null;
12973 idx += 6;
12974 break;
12975
12976 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12977 if (remain < 5)
12978 return null;
12979 idx += 5;
12980 break;
12981
12982 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12983 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12984 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12985 if (remain < 11)
12986 return null;
12987 idx += 11;
12988 break;
12989
12990 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12991 if (remain < 2)
12992 return null;
12993 idx += 2;
12994 break;
12995 }
12996 break;
12997
12998 case (int)ScriptBaseClass.PRIM_COLOR:
12999 case (int)ScriptBaseClass.PRIM_TEXT:
13000 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13001 case (int)ScriptBaseClass.PRIM_OMEGA:
13002 if (remain < 3)
13003 return null;
13004 idx += 3;
13005 break;
13006
13007 case (int)ScriptBaseClass.PRIM_TEXTURE:
13008 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13009 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
13010 if (remain < 5)
13011 return null;
13012 idx += 5;
13013 break;
13014
13015 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13016 if (remain < 7)
13017 return null;
13018
13019 idx += 7;
13020 break;
13021
13022 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13023 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13024 return null;
13025
13026 return rules.GetSublist(idx, -1);
13027 }
13028 }
13029 }
13030 catch (InvalidCastException e)
13031 {
13032 ShoutError(string.Format(
13033 "{0} error running rule #{1}: arg #{2} ",
13034 originFunc, rulesParsed, idx - idxStart) + e.Message);
13035 }
13036 finally
13037 {
13038 if (positionChanged)
13039 {
13040 av.OffsetPosition = finalPos;
13041// av.SendAvatarDataToAllAgents();
13042 av.SendTerseUpdateToAllClients();
13043 positionChanged = false;
13044 }
13045 }
13046 return null;
13047 }
13048
13049 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13050 {
13051 // avatars case
13052 // replies as SL wiki
13053
13054// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13055 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13056
13057 int idx = 0;
13058 while (idx < rules.Length)
13059 {
13060 int code = (int)rules.GetLSLIntegerItem(idx++);
13061 int remain = rules.Length - idx;
13062
13063 switch (code)
13064 {
13065 case (int)ScriptBaseClass.PRIM_MATERIAL:
13066 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13067 break;
13068
13069 case (int)ScriptBaseClass.PRIM_PHYSICS:
13070 res.Add(new LSL_Integer(0));
13071 break;
13072
13073 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13074 res.Add(new LSL_Integer(0));
13075 break;
13076
13077 case (int)ScriptBaseClass.PRIM_PHANTOM:
13078 res.Add(new LSL_Integer(0));
13079 break;
13080
13081 case (int)ScriptBaseClass.PRIM_POSITION:
13082
13083 Vector3 pos = avatar.OffsetPosition;
13084
13085 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13086 pos -= sitOffset;
13087
13088 if( sitPart != null)
13089 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13090
13091 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13092 break;
13093
13094 case (int)ScriptBaseClass.PRIM_SIZE:
13095 // as in llGetAgentSize above
13096// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13097 Vector3 s = avatar.Appearance.AvatarSize;
13098 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13099
13100 break;
13101
13102 case (int)ScriptBaseClass.PRIM_ROTATION:
13103 Quaternion rot = avatar.Rotation;
13104 if (sitPart != null)
13105 {
13106 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13107 }
13108
13109 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13110 break;
13111
13112 case (int)ScriptBaseClass.PRIM_TYPE:
13113 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13114 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13115 res.Add(new LSL_Vector(0f,1.0f,0f));
13116 res.Add(new LSL_Float(0.0f));
13117 res.Add(new LSL_Vector(0, 0, 0));
13118 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13119 res.Add(new LSL_Vector(0, 0, 0));
13120 break;
13121
13122 case (int)ScriptBaseClass.PRIM_TEXTURE:
13123 if (remain < 1)
13124 return null;
13125
13126 int face = (int)rules.GetLSLIntegerItem(idx++);
13127 if (face == ScriptBaseClass.ALL_SIDES)
13128 {
13129 for (face = 0; face < 21; face++)
13130 {
13131 res.Add(new LSL_String(""));
13132 res.Add(new LSL_Vector(0,0,0));
13133 res.Add(new LSL_Vector(0,0,0));
13134 res.Add(new LSL_Float(0.0));
13135 }
13136 }
13137 else
13138 {
13139 if (face >= 0 && face < 21)
13140 {
13141 res.Add(new LSL_String(""));
13142 res.Add(new LSL_Vector(0,0,0));
13143 res.Add(new LSL_Vector(0,0,0));
13144 res.Add(new LSL_Float(0.0));
13145 }
13146 }
13147 break;
13148
13149 case (int)ScriptBaseClass.PRIM_COLOR:
13150 if (remain < 1)
13151 return null;
13152
13153 face = (int)rules.GetLSLIntegerItem(idx++);
13154
13155 if (face == ScriptBaseClass.ALL_SIDES)
13156 {
13157 for (face = 0; face < 21; face++)
13158 {
13159 res.Add(new LSL_Vector(0,0,0));
13160 res.Add(new LSL_Float(0));
13161 }
13162 }
13163 else
13164 {
13165 res.Add(new LSL_Vector(0,0,0));
13166 res.Add(new LSL_Float(0));
13167 }
13168 break;
13169
13170 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13171 if (remain < 1)
13172 return null;
13173 face = (int)rules.GetLSLIntegerItem(idx++);
13174
13175 if (face == ScriptBaseClass.ALL_SIDES)
13176 {
13177 for (face = 0; face < 21; face++)
13178 {
13179 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13180 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13181 }
13182 }
13183 else
13184 {
13185 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13186 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13187 }
13188 break;
13189
13190 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13191 if (remain < 1)
13192 return null;
13193 face = (int)rules.GetLSLIntegerItem(idx++);
13194
13195 if (face == ScriptBaseClass.ALL_SIDES)
13196 {
13197 for (face = 0; face < 21; face++)
13198 {
13199 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13200 }
13201 }
13202 else
13203 {
13204 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13205 }
13206 break;
13207
13208 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13209 res.Add(new LSL_Integer(0));
13210 res.Add(new LSL_Integer(0));// softness
13211 res.Add(new LSL_Float(0.0f)); // gravity
13212 res.Add(new LSL_Float(0.0f)); // friction
13213 res.Add(new LSL_Float(0.0f)); // wind
13214 res.Add(new LSL_Float(0.0f)); // tension
13215 res.Add(new LSL_Vector(0f,0f,0f));
13216 break;
13217
13218 case (int)ScriptBaseClass.PRIM_TEXGEN:
13219 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13220 if (remain < 1)
13221 return null;
13222 face = (int)rules.GetLSLIntegerItem(idx++);
13223
13224 if (face == ScriptBaseClass.ALL_SIDES)
13225 {
13226 for (face = 0; face < 21; face++)
13227 {
13228 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13229 }
13230 }
13231 else
13232 {
13233 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13234 }
13235 break;
13236
13237 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13238 res.Add(new LSL_Integer(0));
13239 res.Add(new LSL_Vector(0f,0f,0f));
13240 res.Add(new LSL_Float(0f)); // intensity
13241 res.Add(new LSL_Float(0f)); // radius
13242 res.Add(new LSL_Float(0f)); // falloff
13243 break;
13244
13245 case (int)ScriptBaseClass.PRIM_GLOW:
13246 if (remain < 1)
13247 return null;
13248 face = (int)rules.GetLSLIntegerItem(idx++);
13249
13250 if (face == ScriptBaseClass.ALL_SIDES)
13251 {
13252 for (face = 0; face < 21; face++)
13253 {
13254 res.Add(new LSL_Float(0f));
13255 }
13256 }
13257 else
13258 {
13259 res.Add(new LSL_Float(0f));
13260 }
13261 break;
13262
13263 case (int)ScriptBaseClass.PRIM_TEXT:
13264 res.Add(new LSL_String(""));
13265 res.Add(new LSL_Vector(0f,0f,0f));
13266 res.Add(new LSL_Float(1.0f));
13267 break;
13268
13269 case (int)ScriptBaseClass.PRIM_NAME:
13270 res.Add(new LSL_String(avatar.Name));
13271 break;
13272
13273 case (int)ScriptBaseClass.PRIM_DESC:
13274 res.Add(new LSL_String(""));
13275 break;
13276
13277 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13278 Quaternion lrot = avatar.Rotation;
13279
13280 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13281 {
13282 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13283 }
13284 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13285 break;
13286
13287 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13288 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13289 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13290 lpos -= lsitOffset;
13291
13292 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13293 {
13294 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13295 }
13296 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13297 break;
13298
13299 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13300 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13301 return null;
13302
13303 return rules.GetSublist(idx, -1);
13304 }
13305 }
13306
13307 return null;
13308 }
11844 } 13309 }
11845 13310
11846 public class NotecardCache 13311 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 21bae27..bd776b6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -136,7 +136,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
137 137
138 Type returntype = m_comms.LookupReturnType(fname); 138 Type returntype = m_comms.LookupReturnType(fname);
139 if (returntype != typeof(string)) 139 if (returntype != typeof(void))
140 MODError(String.Format("return type mismatch for {0}",fname)); 140 MODError(String.Format("return type mismatch for {0}",fname));
141 141
142 modInvoke(fname,parms); 142 modInvoke(fname,parms);
@@ -329,6 +329,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 if (result != null) 329 if (result != null)
330 return result; 330 return result;
331 331
332 Type returntype = m_comms.LookupReturnType(fname);
333 if (returntype == typeof(void))
334 return null;
335
332 MODError(String.Format("Invocation of {0} failed; null return value",fname)); 336 MODError(String.Format("Invocation of {0} failed; null return value",fname));
333 } 337 }
334 catch (Exception e) 338 catch (Exception e)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index bf1b45b..f4e4f44 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -62,6 +62,7 @@ using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
62using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; 62using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
63using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 63using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
64using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 64using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
65using PermissionMask = OpenSim.Framework.PermissionMask;
65 66
66namespace OpenSim.Region.ScriptEngine.Shared.Api 67namespace OpenSim.Region.ScriptEngine.Shared.Api
67{ 68{
@@ -138,6 +139,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 139 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
139 internal float m_ScriptDelayFactor = 1.0f; 140 internal float m_ScriptDelayFactor = 1.0f;
140 internal float m_ScriptDistanceFactor = 1.0f; 141 internal float m_ScriptDistanceFactor = 1.0f;
142 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 143 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 144
143 protected IUrlModule m_UrlModule = null; 145 protected IUrlModule m_UrlModule = null;
@@ -148,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
148 m_ScriptEngine = scriptEngine; 150 m_ScriptEngine = scriptEngine;
149 m_host = host; 151 m_host = host;
150 m_item = item; 152 m_item = item;
153 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
151 154
152 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 155 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
153 156
@@ -211,7 +214,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
211 214
212 internal void OSSLError(string msg) 215 internal void OSSLError(string msg)
213 { 216 {
214 throw new ScriptException("OSSL Runtime Error: " + msg); 217 if (m_debuggerSafe)
218 {
219 OSSLShoutError(msg);
220 }
221 else
222 {
223 throw new ScriptException("OSSL Runtime Error: " + msg);
224 }
215 } 225 }
216 226
217 /// <summary> 227 /// <summary>
@@ -930,18 +940,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
930 if (target != null) 940 if (target != null)
931 { 941 {
932 UUID animID=UUID.Zero; 942 UUID animID=UUID.Zero;
933 lock (m_host.TaskInventory) 943 m_host.TaskInventory.LockItemsForRead(true);
944 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
934 { 945 {
935 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 946 if (inv.Value.Name == animation)
936 { 947 {
937 if (inv.Value.Name == animation) 948 if (inv.Value.Type == (int)AssetType.Animation)
938 { 949 animID = inv.Value.AssetID;
939 if (inv.Value.Type == (int)AssetType.Animation) 950 continue;
940 animID = inv.Value.AssetID;
941 continue;
942 }
943 } 951 }
944 } 952 }
953 m_host.TaskInventory.LockItemsForRead(false);
945 if (animID == UUID.Zero) 954 if (animID == UUID.Zero)
946 target.Animator.AddAnimation(animation, m_host.UUID); 955 target.Animator.AddAnimation(animation, m_host.UUID);
947 else 956 else
@@ -982,6 +991,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
982 else 991 else
983 animID = UUID.Zero; 992 animID = UUID.Zero;
984 } 993 }
994 m_host.TaskInventory.LockItemsForRead(false);
985 995
986 if (animID == UUID.Zero) 996 if (animID == UUID.Zero)
987 target.Animator.RemoveAnimation(animation); 997 target.Animator.RemoveAnimation(animation);
@@ -1644,7 +1654,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1644 } 1654 }
1645 } 1655 }
1646 1656
1647 public Object osParseJSONNew(string JSON) 1657 private Object osParseJSONNew(string JSON)
1648 { 1658 {
1649 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew"); 1659 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew");
1650 1660
@@ -1787,8 +1797,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1787 taskItem.InvType = (int)InventoryType.Notecard; 1797 taskItem.InvType = (int)InventoryType.Notecard;
1788 taskItem.OwnerID = m_host.OwnerID; 1798 taskItem.OwnerID = m_host.OwnerID;
1789 taskItem.CreatorID = m_host.OwnerID; 1799 taskItem.CreatorID = m_host.OwnerID;
1790 taskItem.BasePermissions = (uint)PermissionMask.All; 1800 taskItem.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
1791 taskItem.CurrentPermissions = (uint)PermissionMask.All; 1801 taskItem.CurrentPermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
1792 taskItem.EveryonePermissions = 0; 1802 taskItem.EveryonePermissions = 0;
1793 taskItem.NextPermissions = (uint)PermissionMask.All; 1803 taskItem.NextPermissions = (uint)PermissionMask.All;
1794 taskItem.GroupID = m_host.GroupID; 1804 taskItem.GroupID = m_host.GroupID;
@@ -1846,15 +1856,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1846 { 1856 {
1847 UUID assetID = UUID.Zero; 1857 UUID assetID = UUID.Zero;
1848 1858
1849 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1859 bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID);
1860
1861 if (!notecardNameIsUUID)
1850 { 1862 {
1851 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1863 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1852 {
1853 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1854 {
1855 assetID = item.AssetID;
1856 }
1857 }
1858 } 1864 }
1859 1865
1860 if (assetID == UUID.Zero) 1866 if (assetID == UUID.Zero)
@@ -1865,7 +1871,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1865 AssetBase a = World.AssetService.Get(assetID.ToString()); 1871 AssetBase a = World.AssetService.Get(assetID.ToString());
1866 1872
1867 if (a == null) 1873 if (a == null)
1868 return UUID.Zero; 1874 {
1875 // Whoops, it's still possible here that the notecard name was properly
1876 // formatted like a UUID but isn't an asset UUID so lets look it up by name after all
1877 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1878 if (assetID == UUID.Zero)
1879 return UUID.Zero;
1880
1881 if (!NotecardCache.IsCached(assetID))
1882 {
1883 a = World.AssetService.Get(assetID.ToString());
1884
1885 if (a == null)
1886 {
1887 return UUID.Zero;
1888 }
1889 }
1890 }
1869 1891
1870 string data = Encoding.UTF8.GetString(a.Data); 1892 string data = Encoding.UTF8.GetString(a.Data);
1871 NotecardCache.Cache(assetID, data); 1893 NotecardCache.Cache(assetID, data);
@@ -1873,6 +1895,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1873 1895
1874 return assetID; 1896 return assetID;
1875 } 1897 }
1898 protected UUID SearchTaskInventoryForAssetId(string name)
1899 {
1900 UUID assetId = UUID.Zero;
1901 m_host.TaskInventory.LockItemsForRead(true);
1902 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1903 {
1904 if (item.Type == 7 && item.Name == name)
1905 {
1906 assetId = item.AssetID;
1907 }
1908 }
1909 m_host.TaskInventory.LockItemsForRead(false);
1910 return assetId;
1911 }
1876 1912
1877 /// <summary> 1913 /// <summary>
1878 /// Directly get an entire notecard at once. 1914 /// Directly get an entire notecard at once.
@@ -2350,7 +2386,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2350 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2386 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2351 m_host.AddScriptLPS(1); 2387 m_host.AddScriptLPS(1);
2352 2388
2353 return NpcCreate(firstname, lastname, position, notecard, false, false); 2389 return NpcCreate(firstname, lastname, position, notecard, true, false);
2354 } 2390 }
2355 2391
2356 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2392 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2361,24 +2397,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2361 return NpcCreate( 2397 return NpcCreate(
2362 firstname, lastname, position, notecard, 2398 firstname, lastname, position, notecard,
2363 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2399 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2364 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2400 false);
2401// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2365 } 2402 }
2366 2403
2367 private LSL_Key NpcCreate( 2404 private LSL_Key NpcCreate(
2368 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2405 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2369 { 2406 {
2407 if (!owned)
2408 OSSLError("Unowned NPCs are unsupported");
2409
2410 string groupTitle = String.Empty;
2411
2412 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2413 return new LSL_Key(UUID.Zero.ToString());
2414
2415 if (firstname != String.Empty || lastname != String.Empty)
2416 {
2417 if (firstname != "Shown outfit:")
2418 groupTitle = "- NPC -";
2419 }
2420
2370 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2421 INPCModule module = World.RequestModuleInterface<INPCModule>();
2371 if (module != null) 2422 if (module != null)
2372 { 2423 {
2373 AvatarAppearance appearance = null; 2424 AvatarAppearance appearance = null;
2374 2425
2375 UUID id; 2426// UUID id;
2376 if (UUID.TryParse(notecard, out id)) 2427// if (UUID.TryParse(notecard, out id))
2377 { 2428// {
2378 ScenePresence clonePresence = World.GetScenePresence(id); 2429// ScenePresence clonePresence = World.GetScenePresence(id);
2379 if (clonePresence != null) 2430// if (clonePresence != null)
2380 appearance = clonePresence.Appearance; 2431// appearance = clonePresence.Appearance;
2381 } 2432// }
2382 2433
2383 if (appearance == null) 2434 if (appearance == null)
2384 { 2435 {
@@ -2386,9 +2437,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2386 2437
2387 if (appearanceSerialized != null) 2438 if (appearanceSerialized != null)
2388 { 2439 {
2389 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2440 try
2390 appearance = new AvatarAppearance(); 2441 {
2391 appearance.Unpack(appearanceOsd); 2442 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2443 appearance = new AvatarAppearance();
2444 appearance.Unpack(appearanceOsd);
2445 }
2446 catch
2447 {
2448 return UUID.Zero.ToString();
2449 }
2392 } 2450 }
2393 else 2451 else
2394 { 2452 {
@@ -2407,6 +2465,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2407 World, 2465 World,
2408 appearance); 2466 appearance);
2409 2467
2468 ScenePresence sp;
2469 if (World.TryGetScenePresence(x, out sp))
2470 {
2471 sp.Grouptitle = groupTitle;
2472 sp.SendAvatarDataToAllAgents();
2473 }
2410 return new LSL_Key(x.ToString()); 2474 return new LSL_Key(x.ToString());
2411 } 2475 }
2412 2476
@@ -2704,16 +2768,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2704 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2768 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2705 m_host.AddScriptLPS(1); 2769 m_host.AddScriptLPS(1);
2706 2770
2707 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2771 ManualResetEvent ev = new ManualResetEvent(false);
2708 if (module != null)
2709 {
2710 UUID npcId = new UUID(npc.m_string);
2711 2772
2712 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2773 Util.FireAndForget(delegate(object x) {
2713 return; 2774 try
2775 {
2776 INPCModule module = World.RequestModuleInterface<INPCModule>();
2777 if (module != null)
2778 {
2779 UUID npcId = new UUID(npc.m_string);
2714 2780
2715 module.DeleteNPC(npcId, World); 2781 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2716 } 2782 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2783 {
2784 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2785 return;
2786 }
2787
2788 module.DeleteNPC(npcId, World);
2789 }
2790 }
2791 finally
2792 {
2793 ev.Set();
2794 }
2795 });
2796 ev.WaitOne();
2717 } 2797 }
2718 2798
2719 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2799 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 88ab515..884f07c 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.GetWorldRotation() * 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.GetWorldRotation() * 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)
@@ -696,4 +700,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
696 return retList; 700 return retList;
697 } 701 }
698 } 702 }
699} \ No newline at end of file 703}
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 4ac179a..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,11 @@ 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 void llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
211 LSL_String llTransferLindenDollars(string destination, int amount); 212 LSL_String llTransferLindenDollars(string destination, int amount);
212 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
213 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
@@ -331,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
331 void llSensorRemove(); 332 void llSensorRemove();
332 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);
333 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
334 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
335 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
336 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -357,11 +359,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
357 void llSetParcelMusicURL(string url); 359 void llSetParcelMusicURL(string url);
358 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 360 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
359 void llSetPos(LSL_Vector pos); 361 void llSetPos(LSL_Vector pos);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
360 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 363 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
361 void llSetPrimitiveParams(LSL_List rules); 364 void llSetPrimitiveParams(LSL_List rules);
362 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 365 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
363 void llSetPrimURL(string url); 366 void llSetPrimURL(string url);
364 LSL_Integer llSetRegionPos(LSL_Vector pos);
365 void llSetRemoteScriptAccessPin(int pin); 367 void llSetRemoteScriptAccessPin(int pin);
366 void llSetRot(LSL_Rotation rot); 368 void llSetRot(LSL_Rotation rot);
367 void llSetScale(LSL_Vector scale); 369 void llSetScale(LSL_Vector scale);
@@ -381,6 +383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
381 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 383 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
382 void llSetVehicleType(int type); 384 void llSetVehicleType(int type);
383 void llSetVehicleVectorParam(int param, LSL_Vector vec); 385 void llSetVehicleVectorParam(int param, LSL_Vector vec);
386 void llSetVelocity(LSL_Vector velocity, int local);
384 void llShout(int channelID, string text); 387 void llShout(int channelID, string text);
385 LSL_Float llSin(double f); 388 LSL_Float llSin(double f);
386 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 389 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -424,9 +427,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
424 LSL_Vector llWind(LSL_Vector offset); 427 LSL_Vector llWind(LSL_Vector offset);
425 LSL_String llXorBase64Strings(string str1, string str2); 428 LSL_String llXorBase64Strings(string str1, string str2);
426 LSL_String llXorBase64StringsCorrect(string str1, string str2); 429 LSL_String llXorBase64StringsCorrect(string str1, string str2);
427 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);
428 432
429 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);
430 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 435 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
431 } 436 }
432} 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..a652cb8 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);
@@ -260,7 +260,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
260 string osGetScriptEngineName(); 260 string osGetScriptEngineName();
261 string osGetSimulatorVersion(); 261 string osGetSimulatorVersion();
262 string osGetPhysicsEngineType(); 262 string osGetPhysicsEngineType();
263 Object osParseJSONNew(string JSON);
264 Hashtable osParseJSON(string JSON); 263 Hashtable osParseJSON(string JSON);
265 264
266 void osMessageObject(key objectUUID,string message); 265 void osMessageObject(key objectUUID,string message);
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 bd66ba3..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,7 +661,7 @@ 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;
663 664
664 public const int PRIM_PHYSICS_SHAPE_TYPE = 30; 665 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
665 public const int PRIM_PHYSICS_SHAPE_PRIM = 0; 666 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
666 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2; 667 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
@@ -671,7 +672,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
671 public const int FRICTION = 2; 672 public const int FRICTION = 2;
672 public const int RESTITUTION = 4; 673 public const int RESTITUTION = 4;
673 public const int GRAVITY_MULTIPLIER = 8; 674 public const int GRAVITY_MULTIPLIER = 8;
674 675
675 // extra constants for llSetPrimMediaParams 676 // extra constants for llSetPrimMediaParams
676 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 677 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
677 public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000); 678 public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000);
@@ -743,7 +744,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
743 744
744 public static readonly LSLInteger RCERR_UNKNOWN = -1; 745 public static readonly LSLInteger RCERR_UNKNOWN = -1;
745 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 746 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
746 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;
747 761
748 /// <summary> 762 /// <summary>
749 /// 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 c7a7cf6..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();
@@ -869,9 +876,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
869 m_LSL_Functions.llGiveInventoryList(destination, category, inventory); 876 m_LSL_Functions.llGiveInventoryList(destination, category, inventory);
870 } 877 }
871 878
872 public void llGiveMoney(string destination, int amount) 879 public LSL_Integer llGiveMoney(string destination, int amount)
873 { 880 {
874 m_LSL_Functions.llGiveMoney(destination, amount); 881 return m_LSL_Functions.llGiveMoney(destination, amount);
875 } 882 }
876 883
877 public LSL_String llTransferLindenDollars(string destination, int amount) 884 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -1488,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1488 m_LSL_Functions.llSetAlpha(alpha, face); 1495 m_LSL_Functions.llSetAlpha(alpha, face);
1489 } 1496 }
1490 1497
1498 public void llSetAngularVelocity(LSL_Vector angvelocity, int local)
1499 {
1500 m_LSL_Functions.llSetAngularVelocity(angvelocity, local);
1501 }
1502
1491 public void llSetBuoyancy(double buoyancy) 1503 public void llSetBuoyancy(double buoyancy)
1492 { 1504 {
1493 m_LSL_Functions.llSetBuoyancy(buoyancy); 1505 m_LSL_Functions.llSetBuoyancy(buoyancy);
@@ -1613,6 +1625,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1613 m_LSL_Functions.llSetPos(pos); 1625 m_LSL_Functions.llSetPos(pos);
1614 } 1626 }
1615 1627
1628 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1629 {
1630 return m_LSL_Functions.llSetRegionPos(pos);
1631 }
1632
1616 public void llSetPrimitiveParams(LSL_List rules) 1633 public void llSetPrimitiveParams(LSL_List rules)
1617 { 1634 {
1618 m_LSL_Functions.llSetPrimitiveParams(rules); 1635 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1628,11 +1645,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1628 m_LSL_Functions.llSetPrimURL(url); 1645 m_LSL_Functions.llSetPrimURL(url);
1629 } 1646 }
1630 1647
1631 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1632 {
1633 return m_LSL_Functions.llSetRegionPos(pos);
1634 }
1635
1636 public void llSetRemoteScriptAccessPin(int pin) 1648 public void llSetRemoteScriptAccessPin(int pin)
1637 { 1649 {
1638 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1650 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1728,6 +1740,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1728 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1740 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1729 } 1741 }
1730 1742
1743 public void llSetVelocity(LSL_Vector velocity, int local)
1744 {
1745 m_LSL_Functions.llSetVelocity(velocity, local);
1746 }
1747
1731 public void llShout(int channelID, string text) 1748 public void llShout(int channelID, string text)
1732 { 1749 {
1733 m_LSL_Functions.llShout(channelID, text); 1750 m_LSL_Functions.llShout(channelID, text);
@@ -1978,9 +1995,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1978 return m_LSL_Functions.llClearLinkMedia(link, face); 1995 return m_LSL_Functions.llClearLinkMedia(link, face);
1979 } 1996 }
1980 1997
1981 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)
1982 { 2009 {
1983 m_LSL_Functions.print(str); 2010 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1984 } 2011 }
1985 } 2012 }
1986} 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/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index c9902e4..b63773b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -435,11 +435,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
435 return m_OSSL_Functions.osParseJSON(JSON); 435 return m_OSSL_Functions.osParseJSON(JSON);
436 } 436 }
437 437
438 public Object osParseJSONNew(string JSON)
439 {
440 return m_OSSL_Functions.osParseJSONNew(JSON);
441 }
442
443 public void osMessageObject(key objectUUID,string message) 438 public void osMessageObject(key objectUUID,string message)
444 { 439 {
445 m_OSSL_Functions.osMessageObject(objectUUID,message); 440 m_OSSL_Functions.osMessageObject(objectUUID,message);
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 bf19a42..26850c4 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 {
@@ -481,27 +482,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
481 PostEvent(new EventParams("attach", 482 PostEvent(new EventParams("attach",
482 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); 483 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0]));
483 } 484 }
485
484 } 486 }
485 } 487 }
486 488
487 private void ReleaseControls() 489 private void ReleaseControls()
488 { 490 {
489 int permsMask; 491 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
490 UUID permsGranter; 492
491 lock (Part.TaskInventory) 493 if (part != null)
492 { 494 {
493 if (!Part.TaskInventory.ContainsKey(ItemID)) 495 int permsMask;
496 UUID permsGranter;
497 part.TaskInventory.LockItemsForRead(true);
498 if (!part.TaskInventory.ContainsKey(ItemID))
499 {
500 part.TaskInventory.LockItemsForRead(false);
494 return; 501 return;
502 }
503 permsGranter = part.TaskInventory[ItemID].PermsGranter;
504 permsMask = part.TaskInventory[ItemID].PermsMask;
505 part.TaskInventory.LockItemsForRead(false);
495 506
496 permsGranter = Part.TaskInventory[ItemID].PermsGranter; 507 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
497 permsMask = Part.TaskInventory[ItemID].PermsMask; 508 {
498 } 509 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
499 510 if (presence != null)
500 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 511 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
501 { 512 }
502 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
503 if (presence != null)
504 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
505 } 513 }
506 } 514 }
507 515
@@ -650,6 +658,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
650 return true; 658 return true;
651 } 659 }
652 660
661 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
653 public void SetState(string state) 662 public void SetState(string state)
654 { 663 {
655 if (state == State) 664 if (state == State)
@@ -661,7 +670,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
661 new DetectParams[0])); 670 new DetectParams[0]));
662 PostEvent(new EventParams("state_entry", new Object[0], 671 PostEvent(new EventParams("state_entry", new Object[0],
663 new DetectParams[0])); 672 new DetectParams[0]));
664 673
665 throw new EventAbortException(); 674 throw new EventAbortException();
666 } 675 }
667 676
@@ -751,57 +760,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
751 /// <returns></returns> 760 /// <returns></returns>
752 public object EventProcessor() 761 public object EventProcessor()
753 { 762 {
763 EventParams data = null;
754 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 764 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
755 if (!Running) 765 if (!Running)
756 return 0; 766 return 0;
757 767
758 lock (m_Script)
759 {
760// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 768// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
761 769
762 if (Suspended) 770 if (Suspended)
763 return 0; 771 return 0;
764
765 EventParams data = null;
766 772
767 lock (EventQueue) 773 lock (EventQueue)
774 {
775 data = (EventParams) EventQueue.Dequeue();
776 if (data == null) // Shouldn't happen
768 { 777 {
769 data = (EventParams)EventQueue.Dequeue(); 778 if (EventQueue.Count > 0 && Running && !ShuttingDown)
770 if (data == null) // Shouldn't happen
771 { 779 {
772 if (EventQueue.Count > 0 && Running && !ShuttingDown) 780 m_CurrentWorkItem = Engine.QueueEventHandler(this);
773 {
774 m_CurrentWorkItem = Engine.QueueEventHandler(this);
775 }
776 else
777 {
778 m_CurrentWorkItem = null;
779 }
780 return 0;
781 } 781 }
782 782 else
783 if (data.EventName == "timer")
784 m_TimerQueued = false;
785 if (data.EventName == "control")
786 { 783 {
787 if (m_ControlEventsInQueue > 0) 784 m_CurrentWorkItem = null;
788 m_ControlEventsInQueue--;
789 } 785 }
790 if (data.EventName == "collision") 786 return 0;
791 m_CollisionInQueue = false;
792 } 787 }
793 788
789 if (data.EventName == "timer")
790 m_TimerQueued = false;
791 if (data.EventName == "control")
792 {
793 if (m_ControlEventsInQueue > 0)
794 m_ControlEventsInQueue--;
795 }
796 if (data.EventName == "collision")
797 m_CollisionInQueue = false;
798 }
799
800 lock(m_Script)
801 {
802
803// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
804 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
805
794 if (DebugLevel >= 2) 806 if (DebugLevel >= 2)
795 m_log.DebugFormat( 807 m_log.DebugFormat(
796 "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", 808 "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}",
797 data.EventName, 809 data.EventName,
798 ScriptName, 810 ScriptName,
799 Part.Name, 811 part.Name,
800 Part.LocalId, 812 part.LocalId,
801 Part.ParentGroup.Name, 813 part.ParentGroup.Name,
802 Part.ParentGroup.UUID, 814 part.ParentGroup.UUID,
803 Part.AbsolutePosition, 815 part.AbsolutePosition,
804 Part.ParentGroup.Scene.Name); 816 part.ParentGroup.Scene.Name);
805 817
806 m_DetectParams = data.DetectParams; 818 m_DetectParams = data.DetectParams;
807 819
@@ -814,17 +826,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
814 "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", 826 "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}",
815 State, 827 State,
816 ScriptName, 828 ScriptName,
817 Part.Name, 829 part.Name,
818 Part.LocalId, 830 part.LocalId,
819 Part.ParentGroup.Name, 831 part.ParentGroup.Name,
820 Part.ParentGroup.UUID, 832 part.ParentGroup.UUID,
821 Part.AbsolutePosition, 833 part.AbsolutePosition,
822 Part.ParentGroup.Scene.Name); 834 part.ParentGroup.Scene.Name);
823 835
824 AsyncCommandManager.RemoveScript(Engine, 836 AsyncCommandManager.RemoveScript(Engine,
825 LocalID, ItemID); 837 LocalID, ItemID);
826 838
827 Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); 839 if (part != null)
840 {
841 part.SetScriptEvents(ItemID,
842 (int)m_Script.GetStateEventFlags(State));
843 }
828 } 844 }
829 else 845 else
830 { 846 {
@@ -887,17 +903,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
887 text = text.Substring(0, 1000); 903 text = text.Substring(0, 1000);
888 Engine.World.SimChat(Utils.StringToBytes(text), 904 Engine.World.SimChat(Utils.StringToBytes(text),
889 ChatTypeEnum.DebugChannel, 2147483647, 905 ChatTypeEnum.DebugChannel, 2147483647,
890 Part.AbsolutePosition, 906 part.AbsolutePosition,
891 Part.Name, Part.UUID, false); 907 part.Name, part.UUID, false);
892 908
893 909
894 m_log.DebugFormat( 910 m_log.DebugFormat(
895 "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", 911 "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}",
896 ScriptName, 912 ScriptName,
897 PrimName, 913 PrimName,
898 Part.UUID, 914 part.UUID,
899 Part.AbsolutePosition, 915 part.AbsolutePosition,
900 Part.ParentGroup.Scene.Name, 916 part.ParentGroup.Scene.Name,
901 text.Replace("\n", "\\n"), 917 text.Replace("\n", "\\n"),
902 e.InnerException); 918 e.InnerException);
903 } 919 }
@@ -917,12 +933,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
917 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) 933 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
918 { 934 {
919 m_InSelfDelete = true; 935 m_InSelfDelete = true;
920 Engine.World.DeleteSceneObject(Part.ParentGroup, false); 936 if (part != null)
937 Engine.World.DeleteSceneObject(part.ParentGroup, false);
921 } 938 }
922 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) 939 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
923 { 940 {
924 m_InSelfDelete = true; 941 m_InSelfDelete = true;
925 Part.Inventory.RemoveInventoryItem(ItemID); 942 if (part != null)
943 part.Inventory.RemoveInventoryItem(ItemID);
926 } 944 }
927 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) 945 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException))
928 { 946 {
@@ -976,14 +994,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
976 ReleaseControls(); 994 ReleaseControls();
977 995
978 Stop(timeout); 996 Stop(timeout);
979 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 997 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
980 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 998 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
999 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
1000 part.CollisionSound = UUID.Zero;
981 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 1001 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
982 EventQueue.Clear(); 1002 EventQueue.Clear();
983 m_Script.ResetVars(); 1003 m_Script.ResetVars();
984 State = "default"; 1004 State = "default";
985 1005
986 Part.SetScriptEvents(ItemID, 1006 part.SetScriptEvents(ItemID,
987 (int)m_Script.GetStateEventFlags(State)); 1007 (int)m_Script.GetStateEventFlags(State));
988 if (running) 1008 if (running)
989 Start(); 1009 Start();
@@ -992,6 +1012,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
992 new Object[0], new DetectParams[0])); 1012 new Object[0], new DetectParams[0]));
993 } 1013 }
994 1014
1015 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
995 public void ApiResetScript() 1016 public void ApiResetScript()
996 { 1017 {
997 // bool running = Running; 1018 // bool running = Running;
@@ -1000,15 +1021,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1000 ReleaseControls(); 1021 ReleaseControls();
1001 1022
1002 m_Script.ResetVars(); 1023 m_Script.ResetVars();
1003 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 1024 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
1004 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 1025 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
1026 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
1027 part.CollisionSound = UUID.Zero;
1005 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 1028 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
1006 1029
1007 EventQueue.Clear(); 1030 EventQueue.Clear();
1008 m_Script.ResetVars(); 1031 m_Script.ResetVars();
1009 State = "default"; 1032 State = "default";
1010 1033
1011 Part.SetScriptEvents(ItemID, 1034 part.SetScriptEvents(ItemID,
1012 (int)m_Script.GetStateEventFlags(State)); 1035 (int)m_Script.GetStateEventFlags(State));
1013 1036
1014 if (m_CurrentEvent != "state_entry") 1037 if (m_CurrentEvent != "state_entry")
@@ -1022,10 +1045,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1022 1045
1023 public Dictionary<string, object> GetVars() 1046 public Dictionary<string, object> GetVars()
1024 { 1047 {
1025 if (m_Script != null) 1048 return m_Script.GetVars();
1026 return m_Script.GetVars();
1027 else
1028 return new Dictionary<string, object>();
1029 } 1049 }
1030 1050
1031 public void SetVars(Dictionary<string, object> vars) 1051 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..b524a18 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
@@ -512,7 +512,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
512 else if (o is LSL_Types.LSLFloat) 512 else if (o is LSL_Types.LSLFloat)
513 size += 8; 513 size += 8;
514 else if (o is LSL_Types.LSLString) 514 else if (o is LSL_Types.LSLString)
515 size += ((LSL_Types.LSLString)o).m_string.Length; 515 size += ((LSL_Types.LSLString)o).m_string == null ? 0 : ((LSL_Types.LSLString)o).m_string.Length;
516 else if (o is LSL_Types.key) 516 else if (o is LSL_Types.key)
517 size += ((LSL_Types.key)o).value.Length; 517 size += ((LSL_Types.key)o).value.Length;
518 else if (o is LSL_Types.Vector3) 518 else if (o is LSL_Types.Vector3)
@@ -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 8931be4..17243ab 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;
@@ -148,6 +149,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
148 private Dictionary<UUID, IScriptInstance> m_Scripts = 149 private Dictionary<UUID, IScriptInstance> m_Scripts =
149 new Dictionary<UUID, IScriptInstance>(); 150 new Dictionary<UUID, IScriptInstance>();
150 151
152 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
153
151 // Maps the asset ID to the assembly 154 // Maps the asset ID to the assembly
152 155
153 private Dictionary<UUID, string> m_Assemblies = 156 private Dictionary<UUID, string> m_Assemblies =
@@ -170,6 +173,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
170 IWorkItemResult m_CurrentCompile = null; 173 IWorkItemResult m_CurrentCompile = null;
171 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 174 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
172 175
176 private void lockScriptsForRead(bool locked)
177 {
178 if (locked)
179 {
180 if (m_scriptsLock.RecursiveReadCount > 0)
181 {
182 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.");
183 m_scriptsLock.ExitReadLock();
184 }
185 if (m_scriptsLock.RecursiveWriteCount > 0)
186 {
187 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
188 m_scriptsLock.ExitWriteLock();
189 }
190
191 while (!m_scriptsLock.TryEnterReadLock(60000))
192 {
193 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.");
194 if (m_scriptsLock.IsWriteLockHeld)
195 {
196 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
197 }
198 }
199 }
200 else
201 {
202 if (m_scriptsLock.RecursiveReadCount > 0)
203 {
204 m_scriptsLock.ExitReadLock();
205 }
206 }
207 }
208 private void lockScriptsForWrite(bool locked)
209 {
210 if (locked)
211 {
212 if (m_scriptsLock.RecursiveReadCount > 0)
213 {
214 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.");
215 m_scriptsLock.ExitReadLock();
216 }
217 if (m_scriptsLock.RecursiveWriteCount > 0)
218 {
219 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
220 m_scriptsLock.ExitWriteLock();
221 }
222
223 while (!m_scriptsLock.TryEnterWriteLock(60000))
224 {
225 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.");
226 if (m_scriptsLock.IsWriteLockHeld)
227 {
228 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
229 }
230 }
231 }
232 else
233 {
234 if (m_scriptsLock.RecursiveWriteCount > 0)
235 {
236 m_scriptsLock.ExitWriteLock();
237 }
238 }
239 }
240
173 private ScriptEngineConsoleCommands m_consoleCommands; 241 private ScriptEngineConsoleCommands m_consoleCommands;
174 242
175 public string ScriptEngineName 243 public string ScriptEngineName
@@ -699,64 +767,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine
699 { 767 {
700 if (!m_Enabled) 768 if (!m_Enabled)
701 return; 769 return;
770 lockScriptsForRead(true);
702 771
703 lock (m_Scripts) 772 List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values);
704 {
705 m_log.InfoFormat(
706 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName);
707 773
708 foreach (IScriptInstance instance in m_Scripts.Values) 774// foreach (IScriptInstance instance in m_Scripts.Values)
775 foreach (IScriptInstance instance in instancesToDel)
776 {
777 // Force a final state save
778 //
779 if (m_Assemblies.ContainsKey(instance.AssetID))
709 { 780 {
710 // Force a final state save 781 string assembly = m_Assemblies[instance.AssetID];
711 //
712 if (m_Assemblies.ContainsKey(instance.AssetID))
713 {
714 string assembly = m_Assemblies[instance.AssetID];
715 782
716 try 783 try
717 { 784 {
718 instance.SaveState(assembly); 785 instance.SaveState(assembly);
719 }
720 catch (Exception e)
721 {
722 m_log.Error(
723 string.Format(
724 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
725 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
726 , e);
727 }
728 } 786 }
787 catch (Exception e)
788 {
789 m_log.Error(
790 string.Format(
791 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
792 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
793 , e);
794 }
795 }
729 796
730 // Clear the event queue and abort the instance thread 797 // Clear the event queue and abort the instance thread
731 // 798 //
732 instance.ClearQueue(); 799 instance.ClearQueue();
733 instance.Stop(0); 800 instance.Stop(0);
734 801
735 // Release events, timer, etc 802 // Release events, timer, etc
736 // 803 //
737 instance.DestroyScriptInstance(); 804 instance.DestroyScriptInstance();
738 805
739 // Unload scripts and app domains. 806 // Unload scripts and app domains
740 // Must be done explicitly because they have infinite 807 // Must be done explicitly because they have infinite
741 // lifetime. 808 // lifetime
742 // However, don't bother to do this if the simulator is shutting 809 //
743 // down since it takes a long time with many scripts. 810// if (!m_SimulatorShuttingDown)
744 if (!m_SimulatorShuttingDown) 811 {
812 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
813 if (m_DomainScripts[instance.AppDomain].Count == 0)
745 { 814 {
746 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 815 m_DomainScripts.Remove(instance.AppDomain);
747 if (m_DomainScripts[instance.AppDomain].Count == 0) 816 UnloadAppDomain(instance.AppDomain);
748 {
749 m_DomainScripts.Remove(instance.AppDomain);
750 UnloadAppDomain(instance.AppDomain);
751 }
752 } 817 }
753 } 818 }
754 819
755 m_Scripts.Clear(); 820// m_Scripts.Clear();
756 m_PrimObjects.Clear(); 821// m_PrimObjects.Clear();
757 m_Assemblies.Clear(); 822// m_Assemblies.Clear();
758 m_DomainScripts.Clear(); 823// m_DomainScripts.Clear();
759 } 824 }
825 lockScriptsForRead(false);
826 lockScriptsForWrite(true);
827 m_Scripts.Clear();
828 lockScriptsForWrite(false);
829 m_PrimObjects.Clear();
830 m_Assemblies.Clear();
831 m_DomainScripts.Clear();
832
760 lock (m_ScriptEngines) 833 lock (m_ScriptEngines)
761 { 834 {
762 m_ScriptEngines.Remove(this); 835 m_ScriptEngines.Remove(this);
@@ -825,22 +898,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
825 898
826 List<IScriptInstance> instances = new List<IScriptInstance>(); 899 List<IScriptInstance> instances = new List<IScriptInstance>();
827 900
828 lock (m_Scripts) 901 lockScriptsForRead(true);
829 { 902 foreach (IScriptInstance instance in m_Scripts.Values)
830 foreach (IScriptInstance instance in m_Scripts.Values)
831 instances.Add(instance); 903 instances.Add(instance);
832 } 904 lockScriptsForRead(false);
833 905
834 foreach (IScriptInstance i in instances) 906 foreach (IScriptInstance i in instances)
835 { 907 {
836 string assembly = String.Empty; 908 string assembly = String.Empty;
837 909
838 lock (m_Scripts) 910
839 {
840 if (!m_Assemblies.ContainsKey(i.AssetID)) 911 if (!m_Assemblies.ContainsKey(i.AssetID))
841 continue; 912 continue;
842 assembly = m_Assemblies[i.AssetID]; 913 assembly = m_Assemblies[i.AssetID];
843 } 914
844 915
845 try 916 try
846 { 917 {
@@ -1244,97 +1315,93 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1244 } 1315 }
1245 1316
1246 ScriptInstance instance = null; 1317 ScriptInstance instance = null;
1247 lock (m_Scripts) 1318 // Create the object record
1319 lockScriptsForRead(true);
1320 if ((!m_Scripts.ContainsKey(itemID)) ||
1321 (m_Scripts[itemID].AssetID != assetID))
1248 { 1322 {
1249 // Create the object record 1323 lockScriptsForRead(false);
1250 if ((!m_Scripts.ContainsKey(itemID)) ||
1251 (m_Scripts[itemID].AssetID != assetID))
1252 {
1253 UUID appDomain = assetID;
1254 1324
1255 if (part.ParentGroup.IsAttachment) 1325 UUID appDomain = assetID;
1256 appDomain = part.ParentGroup.RootPart.UUID;
1257 1326
1258 if (!m_AppDomains.ContainsKey(appDomain)) 1327 if (part.ParentGroup.IsAttachment)
1259 { 1328 appDomain = part.ParentGroup.RootPart.UUID;
1260 try
1261 {
1262 AppDomainSetup appSetup = new AppDomainSetup();
1263 appSetup.PrivateBinPath = Path.Combine(
1264 m_ScriptEnginesPath,
1265 m_Scene.RegionInfo.RegionID.ToString());
1266 1329
1267 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1330 if (!m_AppDomains.ContainsKey(appDomain))
1268 Evidence evidence = new Evidence(baseEvidence); 1331 {
1332 try
1333 {
1334 AppDomainSetup appSetup = new AppDomainSetup();
1335 appSetup.PrivateBinPath = Path.Combine(
1336 m_ScriptEnginesPath,
1337 m_Scene.RegionInfo.RegionID.ToString());
1269 1338
1270 AppDomain sandbox; 1339 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1271 if (m_AppDomainLoading) 1340 Evidence evidence = new Evidence(baseEvidence);
1272 {
1273 sandbox = AppDomain.CreateDomain(
1274 m_Scene.RegionInfo.RegionID.ToString(),
1275 evidence, appSetup);
1276 sandbox.AssemblyResolve +=
1277 new ResolveEventHandler(
1278 AssemblyResolver.OnAssemblyResolve);
1279 }
1280 else
1281 {
1282 sandbox = AppDomain.CurrentDomain;
1283 }
1284
1285 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1286 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1287 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1288 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1289 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1290 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1291 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1292
1293 m_AppDomains[appDomain] = sandbox;
1294 1341
1295 m_DomainScripts[appDomain] = new List<UUID>(); 1342 AppDomain sandbox;
1343 if (m_AppDomainLoading)
1344 {
1345 sandbox = AppDomain.CreateDomain(
1346 m_Scene.RegionInfo.RegionID.ToString(),
1347 evidence, appSetup);
1348 m_AppDomains[appDomain].AssemblyResolve +=
1349 new ResolveEventHandler(
1350 AssemblyResolver.OnAssemblyResolve);
1296 } 1351 }
1297 catch (Exception e) 1352 else
1298 { 1353 {
1299 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1354 sandbox = AppDomain.CurrentDomain;
1300 m_ScriptErrorMessage += "Exception creating app domain:\n";
1301 m_ScriptFailCount++;
1302 lock (m_AddingAssemblies)
1303 {
1304 m_AddingAssemblies[assembly]--;
1305 }
1306 return false;
1307 } 1355 }
1308 }
1309 m_DomainScripts[appDomain].Add(itemID);
1310
1311 instance = new ScriptInstance(this, part,
1312 item,
1313 startParam, postOnRez,
1314 m_MaxScriptQueue);
1315 1356
1316 if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) 1357 if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource))
1317 return false; 1358 return false;
1318 1359
1319// if (DebugLevel >= 1) 1360 m_AppDomains[appDomain] = sandbox;
1320// m_log.DebugFormat(
1321// "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1322// part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1323// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1324 1361
1325 if (presence != null) 1362 m_DomainScripts[appDomain] = new List<UUID>();
1363 }
1364 catch (Exception e)
1326 { 1365 {
1327 ShowScriptSaveResponse(item.OwnerID, 1366 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1328 assetID, "Compile successful", true); 1367 m_ScriptErrorMessage += "Exception creating app domain:\n";
1368 m_ScriptFailCount++;
1369 lock (m_AddingAssemblies)
1370 {
1371 m_AddingAssemblies[assembly]--;
1372 }
1373 return false;
1329 } 1374 }
1375 }
1376 m_DomainScripts[appDomain].Add(itemID);
1377
1378 instance = new ScriptInstance(this, part,
1379 item,
1380 startParam, postOnRez,
1381 m_MaxScriptQueue);
1330 1382
1331 instance.AppDomain = appDomain; 1383 instance.Load(m_AppDomains[appDomain], assembly, stateSource);
1332 instance.LineMap = linemap; 1384// m_log.DebugFormat(
1385// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1386// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1387// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1333 1388
1334 m_Scripts[itemID] = instance; 1389 if (presence != null)
1390 {
1391 ShowScriptSaveResponse(item.OwnerID,
1392 assetID, "Compile successful", true);
1335 } 1393 }
1336 }
1337 1394
1395 instance.AppDomain = appDomain;
1396 instance.LineMap = linemap;
1397 lockScriptsForWrite(true);
1398 m_Scripts[itemID] = instance;
1399 lockScriptsForWrite(false);
1400 }
1401 else
1402 {
1403 lockScriptsForRead(false);
1404 }
1338 lock (m_PrimObjects) 1405 lock (m_PrimObjects)
1339 { 1406 {
1340 if (!m_PrimObjects.ContainsKey(localID)) 1407 if (!m_PrimObjects.ContainsKey(localID))
@@ -1352,7 +1419,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1352 m_AddingAssemblies[assembly]--; 1419 m_AddingAssemblies[assembly]--;
1353 } 1420 }
1354 1421
1355 if (instance != null) 1422 if (instance!=null)
1356 instance.Init(); 1423 instance.Init();
1357 1424
1358 bool runIt; 1425 bool runIt;
@@ -1375,18 +1442,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1375 m_CompileDict.Remove(itemID); 1442 m_CompileDict.Remove(itemID);
1376 } 1443 }
1377 1444
1378 IScriptInstance instance = null; 1445 lockScriptsForRead(true);
1379 1446 // Do we even have it?
1380 lock (m_Scripts) 1447 if (!m_Scripts.ContainsKey(itemID))
1381 { 1448 {
1382 // Do we even have it? 1449 // Do we even have it?
1383 if (!m_Scripts.ContainsKey(itemID)) 1450 if (!m_Scripts.ContainsKey(itemID))
1384 return; 1451 return;
1385 1452
1386 instance = m_Scripts[itemID]; 1453 lockScriptsForRead(false);
1454 lockScriptsForWrite(true);
1387 m_Scripts.Remove(itemID); 1455 m_Scripts.Remove(itemID);
1456 lockScriptsForWrite(false);
1457
1458 return;
1388 } 1459 }
1460
1389 1461
1462 IScriptInstance instance=m_Scripts[itemID];
1463 lockScriptsForRead(false);
1464 lockScriptsForWrite(true);
1465 m_Scripts.Remove(itemID);
1466 lockScriptsForWrite(false);
1390 instance.ClearQueue(); 1467 instance.ClearQueue();
1391 1468
1392 instance.Stop(m_WaitForEventCompletionOnScriptStop); 1469 instance.Stop(m_WaitForEventCompletionOnScriptStop);
@@ -1423,8 +1500,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1423 1500
1424 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1501 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1425 if (handlerObjectRemoved != null) 1502 if (handlerObjectRemoved != null)
1426 handlerObjectRemoved(instance.ObjectID); 1503 {
1504 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1505 handlerObjectRemoved(part.UUID);
1506 }
1427 1507
1508 CleanAssemblies();
1509
1428 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1510 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1429 if (handlerScriptRemoved != null) 1511 if (handlerScriptRemoved != null)
1430 handlerScriptRemoved(itemID); 1512 handlerScriptRemoved(itemID);
@@ -1685,12 +1767,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1685 private IScriptInstance GetInstance(UUID itemID) 1767 private IScriptInstance GetInstance(UUID itemID)
1686 { 1768 {
1687 IScriptInstance instance; 1769 IScriptInstance instance;
1688 lock (m_Scripts) 1770 lockScriptsForRead(true);
1771 if (!m_Scripts.ContainsKey(itemID))
1689 { 1772 {
1690 if (!m_Scripts.ContainsKey(itemID)) 1773 lockScriptsForRead(false);
1691 return null; 1774 return null;
1692 instance = m_Scripts[itemID];
1693 } 1775 }
1776 instance = m_Scripts[itemID];
1777 lockScriptsForRead(false);
1694 return instance; 1778 return instance;
1695 } 1779 }
1696 1780
@@ -1714,6 +1798,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1714 return false; 1798 return false;
1715 } 1799 }
1716 1800
1801 [DebuggerNonUserCode]
1717 public void ApiResetScript(UUID itemID) 1802 public void ApiResetScript(UUID itemID)
1718 { 1803 {
1719 IScriptInstance instance = GetInstance(itemID); 1804 IScriptInstance instance = GetInstance(itemID);
@@ -1775,6 +1860,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1775 return UUID.Zero; 1860 return UUID.Zero;
1776 } 1861 }
1777 1862
1863 [DebuggerNonUserCode]
1778 public void SetState(UUID itemID, string newState) 1864 public void SetState(UUID itemID, string newState)
1779 { 1865 {
1780 IScriptInstance instance = GetInstance(itemID); 1866 IScriptInstance instance = GetInstance(itemID);
@@ -1797,11 +1883,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1797 1883
1798 List<IScriptInstance> instances = new List<IScriptInstance>(); 1884 List<IScriptInstance> instances = new List<IScriptInstance>();
1799 1885
1800 lock (m_Scripts) 1886 lockScriptsForRead(true);
1801 { 1887 foreach (IScriptInstance instance in m_Scripts.Values)
1802 foreach (IScriptInstance instance in m_Scripts.Values)
1803 instances.Add(instance); 1888 instances.Add(instance);
1804 } 1889 lockScriptsForRead(false);
1805 1890
1806 foreach (IScriptInstance i in instances) 1891 foreach (IScriptInstance i in instances)
1807 { 1892 {