aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs117
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3934
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs167
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs32
-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.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs17
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs91
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp48
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
18 files changed, 3193 insertions, 1430 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 036cb5d..84d44a1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -28,9 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection;
32using System.Threading; 31using System.Threading;
33using log4net;
34using OpenMetaverse; 32using OpenMetaverse;
35using OpenSim.Framework; 33using OpenSim.Framework;
36using OpenSim.Framework.Monitoring; 34using OpenSim.Framework.Monitoring;
@@ -39,6 +37,8 @@ using OpenSim.Region.ScriptEngine.Interfaces;
39using OpenSim.Region.ScriptEngine.Shared; 37using OpenSim.Region.ScriptEngine.Shared;
40using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; 38using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
41using Timer=OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; 39using Timer=OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer;
40using System.Reflection;
41using log4net;
42 42
43namespace OpenSim.Region.ScriptEngine.Shared.Api 43namespace OpenSim.Region.ScriptEngine.Shared.Api
44{ 44{
@@ -269,6 +269,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
269 /// <param name="itemID"></param> 269 /// <param name="itemID"></param>
270 public static void RemoveScript(IScriptEngine engine, uint localID, UUID itemID) 270 public static void RemoveScript(IScriptEngine engine, uint localID, UUID itemID)
271 { 271 {
272 // Remove a specific script
272// m_log.DebugFormat("[ASYNC COMMAND MANAGER]: Removing facilities for script {0}", itemID); 273// m_log.DebugFormat("[ASYNC COMMAND MANAGER]: Removing facilities for script {0}", itemID);
273 274
274 lock (staticLock) 275 lock (staticLock)
@@ -282,7 +283,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
282 // Remove from: HttpRequest 283 // Remove from: HttpRequest
283 IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface<IHttpRequestModule>(); 284 IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface<IHttpRequestModule>();
284 if (iHttpReq != null) 285 if (iHttpReq != null)
285 iHttpReq.StopHttpRequestsForScript(itemID); 286 iHttpReq.StopHttpRequest(localID, itemID);
286 287
287 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>(); 288 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
288 if (comms != null) 289 if (comms != null)
@@ -386,6 +387,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
386 } 387 }
387 } 388 }
388 389
390
391
389 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 392 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
390 { 393 {
391 List<Object> data = new List<Object>(); 394 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..81e30c9
--- /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)
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 4eda443..33e34fb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -35,10 +35,12 @@ using System.Runtime.Remoting.Lifetime;
35using System.Text; 35using System.Text;
36using System.Threading; 36using System.Threading;
37using System.Text.RegularExpressions; 37using System.Text.RegularExpressions;
38using System.Timers;
38using Nini.Config; 39using Nini.Config;
39using log4net; 40using log4net;
40using OpenMetaverse; 41using OpenMetaverse;
41using OpenMetaverse.Assets; 42using OpenMetaverse.Assets;
43using OpenMetaverse.StructuredData;
42using OpenMetaverse.Packets; 44using OpenMetaverse.Packets;
43using OpenMetaverse.Rendering; 45using OpenMetaverse.Rendering;
44using OpenSim; 46using OpenSim;
@@ -49,6 +51,7 @@ using OpenSim.Region.CoreModules.World.Land;
49using OpenSim.Region.CoreModules.World.Terrain; 51using OpenSim.Region.CoreModules.World.Terrain;
50using OpenSim.Region.Framework.Interfaces; 52using OpenSim.Region.Framework.Interfaces;
51using OpenSim.Region.Framework.Scenes; 53using OpenSim.Region.Framework.Scenes;
54using OpenSim.Region.Framework.Scenes.Serialization;
52using OpenSim.Region.Framework.Scenes.Animation; 55using OpenSim.Region.Framework.Scenes.Animation;
53using OpenSim.Region.Framework.Scenes.Scripting; 56using OpenSim.Region.Framework.Scenes.Scripting;
54using OpenSim.Region.PhysicsModules.SharedBase; 57using OpenSim.Region.PhysicsModules.SharedBase;
@@ -72,6 +75,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
72using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 75using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
73using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 76using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
74using System.Reflection; 77using System.Reflection;
78using Timer = System.Timers.Timer;
75using System.Linq; 79using System.Linq;
76using PermissionMask = OpenSim.Framework.PermissionMask; 80using PermissionMask = OpenSim.Framework.PermissionMask;
77 81
@@ -120,7 +124,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
120 protected int m_notecardLineReadCharsMax = 255; 124 protected int m_notecardLineReadCharsMax = 255;
121 protected int m_scriptConsoleChannel = 0; 125 protected int m_scriptConsoleChannel = 0;
122 protected bool m_scriptConsoleChannelEnabled = false; 126 protected bool m_scriptConsoleChannelEnabled = false;
127 protected bool m_debuggerSafe = false;
123 protected IUrlModule m_UrlModule = null; 128 protected IUrlModule m_UrlModule = null;
129
124 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 130 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>();
125 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 131 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
126 protected int m_sleepMsOnSetTexture = 200; 132 protected int m_sleepMsOnSetTexture = 200;
@@ -242,6 +248,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
242 protected bool m_useMeshCacheInCastRay = true; 248 protected bool m_useMeshCacheInCastRay = true;
243 protected static Dictionary<ulong, FacetedMesh> m_cachedMeshes = new Dictionary<ulong, FacetedMesh>(); 249 protected static Dictionary<ulong, FacetedMesh> m_cachedMeshes = new Dictionary<ulong, FacetedMesh>();
244 250
251// protected Timer m_ShoutSayTimer;
252 protected int m_SayShoutCount = 0;
253 DateTime m_lastSayShoutCheck;
254
255 private Dictionary<string, string> MovementAnimationsForLSL =
256 new Dictionary<string, string> {
257 {"CROUCH", "Crouching"},
258 {"CROUCHWALK", "CrouchWalking"},
259 {"FALLDOWN", "Falling Down"},
260 {"FLY", "Flying"},
261 {"FLYSLOW", "FlyingSlow"},
262 {"HOVER", "Hovering"},
263 {"HOVER_UP", "Hovering Up"},
264 {"HOVER_DOWN", "Hovering Down"},
265 {"JUMP", "Jumping"},
266 {"LAND", "Landing"},
267 {"PREJUMP", "PreJumping"},
268 {"RUN", "Running"},
269 {"SIT","Sitting"},
270 {"SITGROUND","Sitting on Ground"},
271 {"STAND", "Standing"},
272 {"STANDUP", "Standing Up"},
273 {"STRIDE","Striding"},
274 {"SOFT_LAND", "Soft Landing"},
275 {"TURNLEFT", "Turning Left"},
276 {"TURNRIGHT", "Turning Right"},
277 {"WALK", "Walking"}
278 };
279
245 //An array of HTTP/1.1 headers that are not allowed to be used 280 //An array of HTTP/1.1 headers that are not allowed to be used
246 //as custom headers by llHTTPRequest. 281 //as custom headers by llHTTPRequest.
247 private string[] HttpStandardHeaders = 282 private string[] HttpStandardHeaders =
@@ -262,10 +297,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
262 public void Initialize( 297 public void Initialize(
263 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item) 298 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item)
264 { 299 {
300 m_lastSayShoutCheck = DateTime.UtcNow;
301
265 m_ScriptEngine = scriptEngine; 302 m_ScriptEngine = scriptEngine;
266 m_host = host; 303 m_host = host;
267 m_item = item; 304 m_item = item;
268 305 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
306
269 LoadConfig(); 307 LoadConfig();
270 308
271 m_TransferModule = 309 m_TransferModule =
@@ -422,6 +460,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
422 get { return m_ScriptEngine.World; } 460 get { return m_ScriptEngine.World; }
423 } 461 }
424 462
463 [DebuggerNonUserCode]
425 public void state(string newState) 464 public void state(string newState)
426 { 465 {
427 m_ScriptEngine.SetState(m_item.ItemID, newState); 466 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -431,6 +470,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
431 /// Reset the named script. The script must be present 470 /// Reset the named script. The script must be present
432 /// in the same prim. 471 /// in the same prim.
433 /// </summary> 472 /// </summary>
473 [DebuggerNonUserCode]
434 public void llResetScript() 474 public void llResetScript()
435 { 475 {
436 m_host.AddScriptLPS(1); 476 m_host.AddScriptLPS(1);
@@ -493,6 +533,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
493 } 533 }
494 } 534 }
495 535
536 public List<ScenePresence> GetLinkAvatars(int linkType)
537 {
538 List<ScenePresence> ret = new List<ScenePresence>();
539 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
540 return ret;
541
542 // List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
543 // this needs check
544 List<ScenePresence> avs = m_host.ParentGroup.GetSittingAvatars();
545 switch (linkType)
546 {
547 case ScriptBaseClass.LINK_SET:
548 return avs;
549
550 case ScriptBaseClass.LINK_ROOT:
551 return ret;
552
553 case ScriptBaseClass.LINK_ALL_OTHERS:
554 return avs;
555
556 case ScriptBaseClass.LINK_ALL_CHILDREN:
557 return avs;
558
559 case ScriptBaseClass.LINK_THIS:
560 return ret;
561
562 default:
563 if (linkType < 0)
564 return ret;
565
566 int partCount = m_host.ParentGroup.GetPartCount();
567
568 if (linkType <= partCount)
569 {
570 return ret;
571 }
572 else
573 {
574 linkType = linkType - partCount;
575 if (linkType > avs.Count)
576 {
577 return ret;
578 }
579 else
580 {
581 ret.Add(avs[linkType-1]);
582 return ret;
583 }
584 }
585 }
586 }
587
496 /// <summary> 588 /// <summary>
497 /// Get a given link entity from a linkset (linked objects and any sitting avatars). 589 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
498 /// </summary> 590 /// </summary>
@@ -572,6 +664,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
572 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 664 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
573 { 665 {
574 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 666 List<SceneObjectPart> ret = new List<SceneObjectPart>();
667 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
668 return ret;
575 ret.Add(part); 669 ret.Add(part);
576 670
577 switch (linkType) 671 switch (linkType)
@@ -719,8 +813,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
719 public LSL_Float llFrand(double mag) 813 public LSL_Float llFrand(double mag)
720 { 814 {
721 m_host.AddScriptLPS(1); 815 m_host.AddScriptLPS(1);
722 816 lock (Util.RandomClass)
723 return Util.RandomClass.NextDouble() * mag; 817 {
818 return Util.RandomClass.NextDouble() * mag;
819 }
724 } 820 }
725 821
726 public LSL_Integer llFloor(double f) 822 public LSL_Integer llFloor(double f)
@@ -771,31 +867,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
771 867
772 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 868 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
773 869
774 /// <summary> 870 // Utility function for llRot2Euler
775 /// Convert an LSL rotation to a Euler vector. 871
776 /// </summary> 872 public LSL_Vector llRot2Euler(LSL_Rotation q1)
777 /// <remarks>
778 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
779 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
780 /// </remarks>
781 /// <param name="r"></param>
782 /// <returns></returns>
783 public LSL_Vector llRot2Euler(LSL_Rotation r)
784 { 873 {
785 m_host.AddScriptLPS(1); 874 m_host.AddScriptLPS(1);
875 LSL_Vector eul = new LSL_Vector();
786 876
787 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 877 double sqw = q1.s*q1.s;
788 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 878 double sqx = q1.x*q1.x;
789 if (m == 0.0) return new LSL_Vector(); 879 double sqy = q1.z*q1.z;
790 double x = Math.Atan2(-v.y, v.z); 880 double sqz = q1.y*q1.y;
791 double sin = v.x / m; 881 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
792 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 882 double test = q1.x*q1.z + q1.y*q1.s;
793 double y = Math.Asin(sin); 883 if (test > 0.4999*unit) { // singularity at north pole
794 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation 884 eul.z = 2 * Math.Atan2(q1.x,q1.s);
795 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))); 885 eul.y = Math.PI/2;
796 double z = Math.Atan2(v.y, v.x); 886 eul.x = 0;
797 887 return eul;
798 return new LSL_Vector(x, y, z); 888 }
889 if (test < -0.4999*unit) { // singularity at south pole
890 eul.z = -2 * Math.Atan2(q1.x,q1.s);
891 eul.y = -Math.PI/2;
892 eul.x = 0;
893 return eul;
894 }
895 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
896 eul.y = Math.Asin(2*test/unit);
897 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
898 return eul;
799 } 899 }
800 900
801 /* From wiki: 901 /* From wiki:
@@ -848,18 +948,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
848 m_host.AddScriptLPS(1); 948 m_host.AddScriptLPS(1);
849 949
850 double x,y,z,s; 950 double x,y,z,s;
851 951 v.x *= 0.5;
852 double c1 = Math.Cos(v.x * 0.5); 952 v.y *= 0.5;
853 double c2 = Math.Cos(v.y * 0.5); 953 v.z *= 0.5;
854 double c3 = Math.Cos(v.z * 0.5); 954 double c1 = Math.Cos(v.x);
855 double s1 = Math.Sin(v.x * 0.5); 955 double c2 = Math.Cos(v.y);
856 double s2 = Math.Sin(v.y * 0.5); 956 double c1c2 = c1 * c2;
857 double s3 = Math.Sin(v.z * 0.5); 957 double s1 = Math.Sin(v.x);
858 958 double s2 = Math.Sin(v.y);
859 x = s1 * c2 * c3 + c1 * s2 * s3; 959 double s1s2 = s1 * s2;
860 y = c1 * s2 * c3 - s1 * c2 * s3; 960 double c1s2 = c1 * s2;
861 z = s1 * s2 * c3 + c1 * c2 * s3; 961 double s1c2 = s1 * c2;
862 s = c1 * c2 * c3 - s1 * s2 * s3; 962 double c3 = Math.Cos(v.z);
963 double s3 = Math.Sin(v.z);
964
965 x = s1c2 * c3 + c1s2 * s3;
966 y = c1s2 * c3 - s1c2 * s3;
967 z = s1s2 * c3 + c1c2 * s3;
968 s = c1c2 * c3 - s1s2 * s3;
863 969
864 return new LSL_Rotation(x, y, z, s); 970 return new LSL_Rotation(x, y, z, s);
865 } 971 }
@@ -997,77 +1103,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
997 { 1103 {
998 //A and B should both be normalized 1104 //A and B should both be normalized
999 m_host.AddScriptLPS(1); 1105 m_host.AddScriptLPS(1);
1000 LSL_Rotation rotBetween; 1106 /* This method is more accurate than the SL one, and thus causes problems
1001 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 1107 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
1002 // continue calculation. 1108
1003 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 1109 double dotProduct = LSL_Vector.Dot(a, b);
1110 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
1111 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
1112 double angle = Math.Acos(dotProduct / magProduct);
1113 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
1114 double s = Math.Sin(angle / 2);
1115
1116 double x = axis.x * s;
1117 double y = axis.y * s;
1118 double z = axis.z * s;
1119 double w = Math.Cos(angle / 2);
1120
1121 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
1122 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
1123
1124 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
1125 */
1126
1127 // This method mimics the 180 errors found in SL
1128 // See www.euclideanspace.com... angleBetween
1129 LSL_Vector vec_a = a;
1130 LSL_Vector vec_b = b;
1131
1132 // Eliminate zero length
1133 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
1134 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
1135 if (vec_a_mag < 0.00001 ||
1136 vec_b_mag < 0.00001)
1004 { 1137 {
1005 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 1138 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
1006 } 1139 }
1007 else 1140
1141 // Normalize
1142 vec_a = llVecNorm(vec_a);
1143 vec_b = llVecNorm(vec_b);
1144
1145 // Calculate axis and rotation angle
1146 LSL_Vector axis = vec_a % vec_b;
1147 LSL_Float cos_theta = vec_a * vec_b;
1148
1149 // Check if parallel
1150 if (cos_theta > 0.99999)
1008 { 1151 {
1009 a = LSL_Vector.Norm(a); 1152 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
1010 b = LSL_Vector.Norm(b); 1153 }
1011 double dotProduct = LSL_Vector.Dot(a, b); 1154
1012 // There are two degenerate cases possible. These are for vectors 180 or 1155 // Check if anti-parallel
1013 // 0 degrees apart. These have to be detected and handled individually. 1156 else if (cos_theta < -0.99999)
1014 // 1157 {
1015 // Check for vectors 180 degrees apart. 1158 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
1016 // A dot product of -1 would mean the angle between vectors is 180 degrees. 1159 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
1017 if (dotProduct < -0.9999999f) 1160 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
1018 { 1161 }
1019 // First assume X axis is orthogonal to the vectors. 1162 else // other rotation
1020 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 1163 {
1021 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 1164 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
1022 // Check for near zero vector. A very small non-zero number here will create 1165 axis = llVecNorm(axis);
1023 // a rotation in an undesired direction. 1166 double x, y, z, s, t;
1024 if (LSL_Vector.Mag(orthoVector) > 0.0001) 1167 s = Math.Cos(theta);
1025 { 1168 t = Math.Sin(theta);
1026 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 1169 x = axis.x * t;
1027 } 1170 y = axis.y * t;
1028 // If the magnitude of the vector was near zero, then assume the X axis is not 1171 z = axis.z * t;
1029 // orthogonal and use the Z axis instead. 1172 return new LSL_Rotation(x,y,z,s);
1030 else
1031 {
1032 // Set 180 z rotation.
1033 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
1034 }
1035 }
1036 // Check for parallel vectors.
1037 // A dot product of 1 would mean the angle between vectors is 0 degrees.
1038 else if (dotProduct > 0.9999999f)
1039 {
1040 // Set zero rotation.
1041 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
1042 }
1043 else
1044 {
1045 // All special checks have been performed so get the axis of rotation.
1046 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
1047 // Quarternion s value is the length of the unit vector + dot product.
1048 double qs = 1.0 + dotProduct;
1049 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
1050 // Normalize the rotation.
1051 double mag = LSL_Rotation.Mag(rotBetween);
1052 // We shouldn't have to worry about a divide by zero here. The qs value will be
1053 // non-zero because we already know if we're here, then the dotProduct is not -1 so
1054 // qs will not be zero. Also, we've already handled the input vectors being zero so the
1055 // crossProduct vector should also not be zero.
1056 rotBetween.x = rotBetween.x / mag;
1057 rotBetween.y = rotBetween.y / mag;
1058 rotBetween.z = rotBetween.z / mag;
1059 rotBetween.s = rotBetween.s / mag;
1060 // Check for undefined values and set zero rotation if any found. This code might not actually be required
1061 // any longer since zero vectors are checked for at the top.
1062 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
1063 {
1064 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
1065 }
1066 }
1067 } 1173 }
1068 return rotBetween;
1069 } 1174 }
1070 1175
1071 public void llWhisper(int channelID, string text) 1176 public void llWhisper(int channelID, string text)
1072 { 1177 {
1073 m_host.AddScriptLPS(1); 1178 m_host.AddScriptLPS(1);
@@ -1083,10 +1188,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1083 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 1188 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
1084 } 1189 }
1085 1190
1191 private void CheckSayShoutTime()
1192 {
1193 DateTime now = DateTime.UtcNow;
1194 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
1195 {
1196 m_lastSayShoutCheck = now;
1197 m_SayShoutCount = 0;
1198 }
1199 else
1200 m_SayShoutCount++;
1201 }
1202
1086 public void llSay(int channelID, string text) 1203 public void llSay(int channelID, string text)
1087 { 1204 {
1088 m_host.AddScriptLPS(1); 1205 m_host.AddScriptLPS(1);
1089 1206
1207 if (channelID == 0)
1208// m_SayShoutCount++;
1209 CheckSayShoutTime();
1210
1211 if (m_SayShoutCount >= 11)
1212 ScriptSleep(2000);
1213
1090 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 1214 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
1091 { 1215 {
1092 Console.WriteLine(text); 1216 Console.WriteLine(text);
@@ -1109,6 +1233,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1109 { 1233 {
1110 m_host.AddScriptLPS(1); 1234 m_host.AddScriptLPS(1);
1111 1235
1236 if (channelID == 0)
1237// m_SayShoutCount++;
1238 CheckSayShoutTime();
1239
1240 if (m_SayShoutCount >= 11)
1241 ScriptSleep(2000);
1242
1112 if (text.Length > 1023) 1243 if (text.Length > 1023)
1113 text = text.Substring(0, 1023); 1244 text = text.Substring(0, 1023);
1114 1245
@@ -1417,10 +1548,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1417 return detectedParams.TouchUV; 1548 return detectedParams.TouchUV;
1418 } 1549 }
1419 1550
1551 [DebuggerNonUserCode]
1420 public virtual void llDie() 1552 public virtual void llDie()
1421 { 1553 {
1422 m_host.AddScriptLPS(1); 1554 m_host.AddScriptLPS(1);
1423 throw new SelfDeleteException(); 1555 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1424 } 1556 }
1425 1557
1426 public LSL_Float llGround(LSL_Vector offset) 1558 public LSL_Float llGround(LSL_Vector offset)
@@ -1491,6 +1623,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1491 1623
1492 public void llSetStatus(int status, int value) 1624 public void llSetStatus(int status, int value)
1493 { 1625 {
1626 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1627 return;
1494 m_host.AddScriptLPS(1); 1628 m_host.AddScriptLPS(1);
1495 1629
1496 int statusrotationaxis = 0; 1630 int statusrotationaxis = 0;
@@ -1502,6 +1636,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1502 SceneObjectGroup group = m_host.ParentGroup; 1636 SceneObjectGroup group = m_host.ParentGroup;
1503 bool allow = true; 1637 bool allow = true;
1504 1638
1639 int maxprims = World.m_linksetPhysCapacity;
1640 bool checkShape = (maxprims > 0 && group.PrimCount > maxprims);
1641
1505 foreach (SceneObjectPart part in group.Parts) 1642 foreach (SceneObjectPart part in group.Parts)
1506 { 1643 {
1507 if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) 1644 if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys)
@@ -1509,11 +1646,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1509 allow = false; 1646 allow = false;
1510 break; 1647 break;
1511 } 1648 }
1649 if (checkShape && part.PhysicsShapeType != (byte)PhysicsShapeType.None)
1650 {
1651 if (--maxprims < 0)
1652 {
1653 allow = false;
1654 break;
1655 }
1656 }
1512 } 1657 }
1513 1658
1514 if (!allow) 1659 if (!allow)
1515 return; 1660 return;
1516 1661
1662 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1663 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1664 return;
1665
1517 m_host.ScriptSetPhysicsStatus(true); 1666 m_host.ScriptSetPhysicsStatus(true);
1518 } 1667 }
1519 else 1668 else
@@ -1712,6 +1861,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1712 { 1861 {
1713 m_host.AddScriptLPS(1); 1862 m_host.AddScriptLPS(1);
1714 1863
1864 SetColor(m_host, color, face);
1865 }
1866
1867 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1868 {
1869 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1870 return;
1871
1872 Primitive.TextureEntry tex = part.Shape.Textures;
1873 Color4 texcolor;
1874 if (face >= 0 && face < GetNumberOfSides(part))
1875 {
1876 texcolor = tex.CreateFace((uint)face).RGBA;
1877 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1878 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1879 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1880 tex.FaceTextures[face].RGBA = texcolor;
1881 part.UpdateTextureEntry(tex.GetBytes());
1882 return;
1883 }
1884 else if (face == ScriptBaseClass.ALL_SIDES)
1885 {
1886 for (uint i = 0; i < GetNumberOfSides(part); i++)
1887 {
1888 if (tex.FaceTextures[i] != null)
1889 {
1890 texcolor = tex.FaceTextures[i].RGBA;
1891 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1892 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1893 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1894 tex.FaceTextures[i].RGBA = texcolor;
1895 }
1896 texcolor = tex.DefaultTexture.RGBA;
1897 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1898 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1899 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1900 tex.DefaultTexture.RGBA = texcolor;
1901 }
1902 part.UpdateTextureEntry(tex.GetBytes());
1903 return;
1904 }
1905
1715 if (face == ScriptBaseClass.ALL_SIDES) 1906 if (face == ScriptBaseClass.ALL_SIDES)
1716 face = SceneObjectPart.ALL_SIDES; 1907 face = SceneObjectPart.ALL_SIDES;
1717 1908
@@ -1737,7 +1928,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1737 string userAgent = m_UrlModule.GetHttpHeader(new UUID(id), "user-agent"); 1928 string userAgent = m_UrlModule.GetHttpHeader(new UUID(id), "user-agent");
1738 if (userAgent.IndexOf("SecondLife") < 0) 1929 if (userAgent.IndexOf("SecondLife") < 0)
1739 return; // Not the embedded browser. Is this check good enough? 1930 return; // Not the embedded browser. Is this check good enough?
1740 1931
1741 // Use the IP address of the client and check against the request 1932 // Use the IP address of the client and check against the request
1742 // seperate logins from the same IP will allow all of them to get non-text/plain as long 1933 // seperate logins from the same IP will allow all of them to get non-text/plain as long
1743 // as the owner is in the region. Same as SL! 1934 // as the owner is in the region. Same as SL!
@@ -1785,8 +1976,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1785 } 1976 }
1786 } 1977 }
1787 1978
1979/*
1980 public void llSetContentType(LSL_Key id, LSL_Integer content_type)
1981 {
1982 if (m_UrlModule != null)
1983 {
1984 string type = "text.plain";
1985 if (content_type == (int)ScriptBaseClass.CONTENT_TYPE_HTML)
1986 type = "text/html";
1987
1988 m_UrlModule.HttpContentType(new UUID(id),type);
1989 }
1990 }
1991*/
1788 public void SetTexGen(SceneObjectPart part, int face,int style) 1992 public void SetTexGen(SceneObjectPart part, int face,int style)
1789 { 1993 {
1994 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1995 return;
1996
1790 Primitive.TextureEntry tex = part.Shape.Textures; 1997 Primitive.TextureEntry tex = part.Shape.Textures;
1791 MappingType textype; 1998 MappingType textype;
1792 textype = MappingType.Default; 1999 textype = MappingType.Default;
@@ -1817,6 +2024,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1817 2024
1818 public void SetGlow(SceneObjectPart part, int face, float glow) 2025 public void SetGlow(SceneObjectPart part, int face, float glow)
1819 { 2026 {
2027 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2028 return;
2029
1820 Primitive.TextureEntry tex = part.Shape.Textures; 2030 Primitive.TextureEntry tex = part.Shape.Textures;
1821 if (face >= 0 && face < GetNumberOfSides(part)) 2031 if (face >= 0 && face < GetNumberOfSides(part))
1822 { 2032 {
@@ -1842,6 +2052,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1842 2052
1843 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 2053 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1844 { 2054 {
2055 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2056 return;
1845 2057
1846 Shininess sval = new Shininess(); 2058 Shininess sval = new Shininess();
1847 2059
@@ -1892,6 +2104,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1892 2104
1893 public void SetFullBright(SceneObjectPart part, int face, bool bright) 2105 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1894 { 2106 {
2107 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2108 return;
2109
1895 Primitive.TextureEntry tex = part.Shape.Textures; 2110 Primitive.TextureEntry tex = part.Shape.Textures;
1896 if (face >= 0 && face < GetNumberOfSides(part)) 2111 if (face >= 0 && face < GetNumberOfSides(part))
1897 { 2112 {
@@ -1952,13 +2167,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1952 m_host.AddScriptLPS(1); 2167 m_host.AddScriptLPS(1);
1953 2168
1954 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2169 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1955 2170 if (parts.Count > 0)
1956 foreach (SceneObjectPart part in parts) 2171 {
1957 SetAlpha(part, alpha, face); 2172 try
2173 {
2174 foreach (SceneObjectPart part in parts)
2175 SetAlpha(part, alpha, face);
2176 }
2177 finally { }
2178 }
1958 } 2179 }
1959 2180
1960 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 2181 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1961 { 2182 {
2183 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2184 return;
2185
1962 Primitive.TextureEntry tex = part.Shape.Textures; 2186 Primitive.TextureEntry tex = part.Shape.Textures;
1963 Color4 texcolor; 2187 Color4 texcolor;
1964 if (face >= 0 && face < GetNumberOfSides(part)) 2188 if (face >= 0 && face < GetNumberOfSides(part))
@@ -2011,7 +2235,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2011 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 2235 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
2012 float wind, float tension, LSL_Vector Force) 2236 float wind, float tension, LSL_Vector Force)
2013 { 2237 {
2014 if (part == null) 2238 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2015 return; 2239 return;
2016 2240
2017 if (flexi) 2241 if (flexi)
@@ -2052,7 +2276,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2052 /// <param name="falloff"></param> 2276 /// <param name="falloff"></param>
2053 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 2277 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
2054 { 2278 {
2055 if (part == null) 2279 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2056 return; 2280 return;
2057 2281
2058 if (light) 2282 if (light)
@@ -2085,11 +2309,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2085 Primitive.TextureEntry tex = part.Shape.Textures; 2309 Primitive.TextureEntry tex = part.Shape.Textures;
2086 Color4 texcolor; 2310 Color4 texcolor;
2087 LSL_Vector rgb = new LSL_Vector(); 2311 LSL_Vector rgb = new LSL_Vector();
2312 int nsides = GetNumberOfSides(part);
2313
2088 if (face == ScriptBaseClass.ALL_SIDES) 2314 if (face == ScriptBaseClass.ALL_SIDES)
2089 { 2315 {
2090 int i; 2316 int i;
2091 2317 for (i = 0; i < nsides; i++)
2092 for (i = 0 ; i < GetNumberOfSides(part); i++)
2093 { 2318 {
2094 texcolor = tex.GetFace((uint)i).RGBA; 2319 texcolor = tex.GetFace((uint)i).RGBA;
2095 rgb.x += texcolor.R; 2320 rgb.x += texcolor.R;
@@ -2097,14 +2322,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2097 rgb.z += texcolor.B; 2322 rgb.z += texcolor.B;
2098 } 2323 }
2099 2324
2100 rgb.x /= (float)GetNumberOfSides(part); 2325 float invnsides = 1.0f / (float)nsides;
2101 rgb.y /= (float)GetNumberOfSides(part); 2326
2102 rgb.z /= (float)GetNumberOfSides(part); 2327 rgb.x *= invnsides;
2328 rgb.y *= invnsides;
2329 rgb.z *= invnsides;
2103 2330
2104 return rgb; 2331 return rgb;
2105 } 2332 }
2106 2333 if (face >= 0 && face < nsides)
2107 if (face >= 0 && face < GetNumberOfSides(part))
2108 { 2334 {
2109 texcolor = tex.GetFace((uint)face).RGBA; 2335 texcolor = tex.GetFace((uint)face).RGBA;
2110 rgb.x = texcolor.R; 2336 rgb.x = texcolor.R;
@@ -2131,15 +2357,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2131 m_host.AddScriptLPS(1); 2357 m_host.AddScriptLPS(1);
2132 2358
2133 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2359 List<SceneObjectPart> parts = GetLinkParts(linknumber);
2134 2360 if (parts.Count > 0)
2135 foreach (SceneObjectPart part in parts) 2361 {
2136 SetTexture(part, texture, face); 2362 try
2137 2363 {
2364 foreach (SceneObjectPart part in parts)
2365 SetTexture(part, texture, face);
2366 }
2367 finally { }
2368 }
2138 ScriptSleep(m_sleepMsOnSetLinkTexture); 2369 ScriptSleep(m_sleepMsOnSetLinkTexture);
2139 } 2370 }
2140 2371
2141 protected void SetTexture(SceneObjectPart part, string texture, int face) 2372 protected void SetTexture(SceneObjectPart part, string texture, int face)
2142 { 2373 {
2374 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2375 return;
2376
2143 UUID textureID = new UUID(); 2377 UUID textureID = new UUID();
2144 2378
2145 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 2379 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
@@ -2184,6 +2418,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2184 2418
2185 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2419 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
2186 { 2420 {
2421 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2422 return;
2423
2187 Primitive.TextureEntry tex = part.Shape.Textures; 2424 Primitive.TextureEntry tex = part.Shape.Textures;
2188 if (face >= 0 && face < GetNumberOfSides(part)) 2425 if (face >= 0 && face < GetNumberOfSides(part))
2189 { 2426 {
@@ -2220,6 +2457,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2220 2457
2221 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2458 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
2222 { 2459 {
2460 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2461 return;
2462
2223 Primitive.TextureEntry tex = part.Shape.Textures; 2463 Primitive.TextureEntry tex = part.Shape.Textures;
2224 if (face >= 0 && face < GetNumberOfSides(part)) 2464 if (face >= 0 && face < GetNumberOfSides(part))
2225 { 2465 {
@@ -2256,6 +2496,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2256 2496
2257 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2497 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
2258 { 2498 {
2499 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2500 return;
2501
2259 Primitive.TextureEntry tex = part.Shape.Textures; 2502 Primitive.TextureEntry tex = part.Shape.Textures;
2260 if (face >= 0 && face < GetNumberOfSides(part)) 2503 if (face >= 0 && face < GetNumberOfSides(part))
2261 { 2504 {
@@ -2397,7 +2640,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2397 return end; 2640 return end;
2398 } 2641 }
2399 2642
2400 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2643 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2401 { 2644 {
2402 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2645 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2403 return fromPos; 2646 return fromPos;
@@ -2413,9 +2656,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2413 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2656 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2414 targetPos.z = ground; 2657 targetPos.z = ground;
2415 } 2658 }
2416 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2659 if (adjust)
2660 return SetPosAdjust(fromPos, targetPos);
2417 2661
2418 return real_vec; 2662 return targetPos;
2419 } 2663 }
2420 2664
2421 /// <summary> 2665 /// <summary>
@@ -2426,27 +2670,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2426 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2670 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2427 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2671 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2428 { 2672 {
2429 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2673 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2674 return;
2675
2430 LSL_Vector currentPos = GetPartLocalPos(part); 2676 LSL_Vector currentPos = GetPartLocalPos(part);
2677 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2431 2678
2432 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2433 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2434 2679
2435 if (part.ParentGroup.RootPart == part) 2680 if (part.ParentGroup.RootPart == part)
2436 { 2681 {
2437 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2438 targetPos.z = ground;
2439 SceneObjectGroup parent = part.ParentGroup; 2682 SceneObjectGroup parent = part.ParentGroup;
2440 parent.UpdateGroupPosition(!adjust ? targetPos : 2683 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2441 SetPosAdjust(currentPos, targetPos)); 2684 return;
2685 parent.UpdateGroupPosition((Vector3)toPos);
2442 } 2686 }
2443 else 2687 else
2444 { 2688 {
2445 part.OffsetPosition = !adjust ? targetPos : 2689 part.OffsetPosition = (Vector3)toPos;
2446 SetPosAdjust(currentPos, targetPos); 2690// SceneObjectGroup parent = part.ParentGroup;
2447 SceneObjectGroup parent = part.ParentGroup; 2691// parent.HasGroupChanged = true;
2448 parent.HasGroupChanged = true; 2692// parent.ScheduleGroupForTerseUpdate();
2449 parent.ScheduleGroupForTerseUpdate(); 2693 part.ScheduleTerseUpdate();
2450 } 2694 }
2451 } 2695 }
2452 2696
@@ -2475,13 +2719,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2475 else 2719 else
2476 { 2720 {
2477 if (part.ParentGroup.IsAttachment) 2721 if (part.ParentGroup.IsAttachment)
2478 {
2479 pos = part.AttachedPos; 2722 pos = part.AttachedPos;
2480 }
2481 else 2723 else
2482 {
2483 pos = part.AbsolutePosition; 2724 pos = part.AbsolutePosition;
2484 }
2485 } 2725 }
2486 2726
2487// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2727// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2492,9 +2732,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2492 public void llSetRot(LSL_Rotation rot) 2732 public void llSetRot(LSL_Rotation rot)
2493 { 2733 {
2494 m_host.AddScriptLPS(1); 2734 m_host.AddScriptLPS(1);
2495 2735
2496 // try to let this work as in SL... 2736 // try to let this work as in SL...
2497 if (m_host.ParentID == 0) 2737 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2498 { 2738 {
2499 // special case: If we are root, rotate complete SOG to new rotation 2739 // special case: If we are root, rotate complete SOG to new rotation
2500 SetRot(m_host, rot); 2740 SetRot(m_host, rot);
@@ -2521,25 +2761,47 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2521 2761
2522 protected void SetRot(SceneObjectPart part, Quaternion rot) 2762 protected void SetRot(SceneObjectPart part, Quaternion rot)
2523 { 2763 {
2524 part.UpdateRotation(rot); 2764 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2525 // Update rotation does not move the object in the physics scene if it's a linkset. 2765 return;
2526 2766
2527//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2767 bool isroot = (part == part.ParentGroup.RootPart);
2528// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2768 bool isphys;
2529 2769
2530 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2531 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2532 // It's perfectly okay when the object is not an active physical body though.
2533 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2534 // but only if the object is not physial and active. This is important for rotating doors.
2535 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2536 // scene
2537 PhysicsActor pa = part.PhysActor; 2770 PhysicsActor pa = part.PhysActor;
2538 2771
2539 if (pa != null && !pa.IsPhysical) 2772 // keep using physactor ideia of isphysical
2773 // it should be SOP ideia of that
2774 // not much of a issue with ubOde
2775 if (pa != null && pa.IsPhysical)
2776 isphys = true;
2777 else
2778 isphys = false;
2779
2780 // SL doesn't let scripts rotate root of physical linksets
2781 if (isroot && isphys)
2782 return;
2783
2784 part.UpdateRotation(rot);
2785
2786 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2787 // so do a nasty update of parts positions if is a root part rotation
2788 if (isroot && pa != null) // with if above implies non physical root part
2540 { 2789 {
2541 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2790 part.ParentGroup.ResetChildPrimPhysicsPositions();
2542 } 2791 }
2792 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2793 {
2794 // List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2795 List<ScenePresence> sittingavas = part.ParentGroup.GetSittingAvatars();
2796 if (sittingavas.Count > 0)
2797 {
2798 foreach (ScenePresence av in sittingavas)
2799 {
2800 if (isroot || part.LocalId == av.ParentID)
2801 av.SendTerseUpdateToAllClients();
2802 }
2803 }
2804 }
2543 } 2805 }
2544 2806
2545 /// <summary> 2807 /// <summary>
@@ -2556,6 +2818,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2556 2818
2557 m_host.AddScriptLPS(1); 2819 m_host.AddScriptLPS(1);
2558 Quaternion q = m_host.GetWorldRotation(); 2820 Quaternion q = m_host.GetWorldRotation();
2821
2822 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2823 {
2824 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2825 if (avatar != null)
2826 {
2827 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2828 q = avatar.CameraRotation * q; // Mouselook
2829 else
2830 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2831 }
2832 }
2833
2559 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2834 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2560 } 2835 }
2561 2836
@@ -2583,14 +2858,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2583 return new LSL_Rotation(q); 2858 return new LSL_Rotation(q);
2584 } 2859 }
2585 2860
2586 return new LSL_Rotation(part.GetWorldRotation()); 2861 q = part.GetWorldRotation();
2862 if (part.ParentGroup.AttachmentPoint != 0)
2863 {
2864 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2865 if (avatar != null)
2866 {
2867 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2868 q = avatar.CameraRotation * q; // Mouselook
2869 else
2870 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2871 }
2872 }
2873
2874 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2587 } 2875 }
2588 2876
2589 public LSL_Rotation llGetLocalRot() 2877 public LSL_Rotation llGetLocalRot()
2590 { 2878 {
2591 m_host.AddScriptLPS(1); 2879 return GetPartLocalRot(m_host);
2880 }
2592 2881
2593 return new LSL_Rotation(m_host.RotationOffset); 2882 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2883 {
2884 m_host.AddScriptLPS(1);
2885 Quaternion rot = part.RotationOffset;
2886 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2594 } 2887 }
2595 2888
2596 public void llSetForce(LSL_Vector force, int local) 2889 public void llSetForce(LSL_Vector force, int local)
@@ -2620,32 +2913,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2620 return force; 2913 return force;
2621 } 2914 }
2622 2915
2623 public void llSetVelocity(LSL_Vector velocity, int local) 2916 public void llSetVelocity(LSL_Vector vel, int local)
2624 { 2917 {
2625 m_host.AddScriptLPS(1); 2918 m_host.AddScriptLPS(1);
2626 2919 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2627 if (!m_host.ParentGroup.IsDeleted)
2628 {
2629 if (local != 0)
2630 velocity *= llGetRot();
2631
2632 m_host.ParentGroup.RootPart.Velocity = velocity;
2633 }
2634 } 2920 }
2635 2921
2636 public void llSetAngularVelocity(LSL_Vector angularVelocity, int local) 2922 public void llSetAngularVelocity(LSL_Vector avel, int local)
2637 { 2923 {
2638 m_host.AddScriptLPS(1); 2924 m_host.AddScriptLPS(1);
2639 2925 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2640 if (!m_host.ParentGroup.IsDeleted)
2641 {
2642 if (local != 0)
2643 angularVelocity *= llGetRot();
2644
2645 m_host.ParentGroup.RootPart.AngularVelocity = angularVelocity;
2646 }
2647 } 2926 }
2648
2649 public LSL_Integer llTarget(LSL_Vector position, double range) 2927 public LSL_Integer llTarget(LSL_Vector position, double range)
2650 { 2928 {
2651 m_host.AddScriptLPS(1); 2929 m_host.AddScriptLPS(1);
@@ -2696,16 +2974,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2696 m_host.ApplyImpulse(v, local != 0); 2974 m_host.ApplyImpulse(v, local != 0);
2697 } 2975 }
2698 2976
2977
2699 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2978 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2700 { 2979 {
2701 m_host.AddScriptLPS(1); 2980 m_host.AddScriptLPS(1);
2702 m_host.ApplyAngularImpulse(force, local != 0); 2981 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2703 } 2982 }
2704 2983
2705 public void llSetTorque(LSL_Vector torque, int local) 2984 public void llSetTorque(LSL_Vector torque, int local)
2706 { 2985 {
2707 m_host.AddScriptLPS(1); 2986 m_host.AddScriptLPS(1);
2708 m_host.SetAngularImpulse(torque, local != 0); 2987 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2709 } 2988 }
2710 2989
2711 public LSL_Vector llGetTorque() 2990 public LSL_Vector llGetTorque()
@@ -2722,20 +3001,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2722 llSetTorque(torque, local); 3001 llSetTorque(torque, local);
2723 } 3002 }
2724 3003
3004
2725 public LSL_Vector llGetVel() 3005 public LSL_Vector llGetVel()
2726 { 3006 {
2727 m_host.AddScriptLPS(1); 3007 m_host.AddScriptLPS(1);
2728 3008
2729 Vector3 vel; 3009 Vector3 vel = Vector3.Zero;
2730 3010
2731 if (m_host.ParentGroup.IsAttachment) 3011 if (m_host.ParentGroup.IsAttachment)
2732 { 3012 {
2733 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 3013 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2734 vel = avatar.GetWorldVelocity(); 3014 if (avatar != null)
3015 vel = avatar.GetWorldVelocity();
2735 } 3016 }
2736 else 3017 else
2737 { 3018 {
2738 vel = m_host.Velocity; 3019 vel = m_host.ParentGroup.RootPart.Velocity;
2739 } 3020 }
2740 3021
2741 return new LSL_Vector(vel); 3022 return new LSL_Vector(vel);
@@ -2751,8 +3032,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2751 public LSL_Vector llGetOmega() 3032 public LSL_Vector llGetOmega()
2752 { 3033 {
2753 m_host.AddScriptLPS(1); 3034 m_host.AddScriptLPS(1);
2754 3035 Vector3 avel = m_host.AngularVelocity;
2755 return new LSL_Vector(m_host.AngularVelocity); 3036 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2756 } 3037 }
2757 3038
2758 public LSL_Float llGetTimeOfDay() 3039 public LSL_Float llGetTimeOfDay()
@@ -2806,7 +3087,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2806 m_SoundModule.SendSound( 3087 m_SoundModule.SendSound(
2807 m_host.UUID, 3088 m_host.UUID,
2808 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), 3089 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound),
2809 volume, false, m_host.SoundQueueing ? (byte)SoundFlags.Queue : (byte)SoundFlags.None, 3090 volume, false, 0,
2810 0, false, false); 3091 0, false, false);
2811 } 3092 }
2812 } 3093 }
@@ -2817,7 +3098,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2817 if (m_SoundModule != null) 3098 if (m_SoundModule != null)
2818 { 3099 {
2819 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 3100 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
2820 volume, 20, false); 3101 volume, 20, false,false);
2821 } 3102 }
2822 } 3103 }
2823 3104
@@ -2827,16 +3108,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2827 if (m_SoundModule != null) 3108 if (m_SoundModule != null)
2828 { 3109 {
2829 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 3110 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
2830 volume, 20, true); 3111 volume, 20, true, false);
2831 } 3112 }
2832 } 3113 }
2833 3114
2834 public void llLoopSoundSlave(string sound, double volume) 3115 public void llLoopSoundSlave(string sound, double volume)
2835 { 3116 {
2836 m_host.AddScriptLPS(1); 3117 m_host.AddScriptLPS(1);
2837 lock (m_host.ParentGroup.LoopSoundSlavePrims) 3118 if (m_SoundModule != null)
2838 { 3119 {
2839 m_host.ParentGroup.LoopSoundSlavePrims.Add(m_host); 3120 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
3121 volume, 20, false, true);
2840 } 3122 }
2841 } 3123 }
2842 3124
@@ -3111,7 +3393,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3111 return src.ToLower(); 3393 return src.ToLower();
3112 } 3394 }
3113 3395
3114 public void llGiveMoney(string destination, int amount) 3396 public LSL_Integer llGiveMoney(string destination, int amount)
3115 { 3397 {
3116 Util.FireAndForget(x => 3398 Util.FireAndForget(x =>
3117 { 3399 {
@@ -3142,9 +3424,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3142 return; 3424 return;
3143 } 3425 }
3144 3426
3427 string reason;
3145 money.ObjectGiveMoney( 3428 money.ObjectGiveMoney(
3146 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3429
3430 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero, out reason);
3147 }, null, "LSL_Api.llGiveMoney"); 3431 }, null, "LSL_Api.llGiveMoney");
3432
3433 return 0;
3148 } 3434 }
3149 3435
3150 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3436 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -3177,6 +3463,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3177 3463
3178 public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) 3464 public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
3179 { 3465 {
3466 doObjectRez(inventory, pos, vel, rot, param, true);
3467 }
3468
3469 public void doObjectRez(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param, bool atRoot)
3470 {
3180 m_host.AddScriptLPS(1); 3471 m_host.AddScriptLPS(1);
3181 3472
3182 Util.FireAndForget(x => 3473 Util.FireAndForget(x =>
@@ -3203,15 +3494,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3203 return; 3494 return;
3204 } 3495 }
3205 3496
3206 // need the magnitude later 3497 List<SceneObjectGroup> new_groups = World.RezObject(m_host, item, pos, rot, vel, param, atRoot);
3207 // float velmag = (float)Util.GetMagnitude(llvel);
3208
3209 List<SceneObjectGroup> new_groups = World.RezObject(m_host, item, pos, rot, vel, param);
3210 3498
3211 // If either of these are null, then there was an unknown error. 3499 // If either of these are null, then there was an unknown error.
3212 if (new_groups == null) 3500 if (new_groups == null)
3213 return; 3501 return;
3214 3502
3503 bool notAttachment = !m_host.ParentGroup.IsAttachment;
3504
3215 foreach (SceneObjectGroup group in new_groups) 3505 foreach (SceneObjectGroup group in new_groups)
3216 { 3506 {
3217 // objects rezzed with this method are die_at_edge by default. 3507 // objects rezzed with this method are die_at_edge by default.
@@ -3225,21 +3515,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3225 group.RootPart.UUID.ToString()) }, 3515 group.RootPart.UUID.ToString()) },
3226 new DetectParams[0])); 3516 new DetectParams[0]));
3227 3517
3228 float groupmass = group.GetMass(); 3518 if (notAttachment)
3519 {
3520 float groupmass = group.GetMass();
3229 3521
3230 PhysicsActor pa = group.RootPart.PhysActor; 3522 PhysicsActor pa = group.RootPart.PhysActor;
3231 3523
3232 //Recoil. 3524 //Recoil.
3233 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3525 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
3234 {
3235 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
3236 if (recoil != Vector3.Zero)
3237 { 3526 {
3238 llApplyImpulse(recoil, 0); 3527 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
3528 if (recoil != Vector3.Zero)
3529 {
3530 llApplyImpulse(recoil, 0);
3531 }
3239 } 3532 }
3240 } 3533 }
3241 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3534 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3242 } 3535 }
3536
3243 }, null, "LSL_Api.llRezAtRoot"); 3537 }, null, "LSL_Api.llRezAtRoot");
3244 3538
3245 //ScriptSleep((int)((groupmass * velmag) / 10)); 3539 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -3248,38 +3542,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3248 3542
3249 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) 3543 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
3250 { 3544 {
3251 llRezAtRoot(inventory, pos, vel, rot, param); 3545 doObjectRez(inventory, pos, vel, rot, param, false);
3252 } 3546 }
3253 3547
3254 public void llLookAt(LSL_Vector target, double strength, double damping) 3548 public void llLookAt(LSL_Vector target, double strength, double damping)
3255 { 3549 {
3256 m_host.AddScriptLPS(1); 3550 m_host.AddScriptLPS(1);
3257 // Determine where we are looking from
3258 LSL_Vector from = llGetPos();
3259 3551
3260 // normalized direction to target 3552 // Get the normalized vector to the target
3261 LSL_Vector dir = llVecNorm(target - from); 3553 LSL_Vector d1 = llVecNorm(target - llGetPos());
3262 // use vertical to help compute left axis
3263 LSL_Vector up = new LSL_Vector(0.0, 0.0, 1.0);
3264 // find normalized left axis parallel to horizon
3265 LSL_Vector left = llVecNorm(LSL_Vector.Cross(up, dir));
3266 // make up orthogonal to left and dir
3267 up = LSL_Vector.Cross(dir, left);
3268 3554
3269 // compute rotation based on orthogonal axes 3555 // Get the bearing (yaw)
3270 LSL_Rotation rot = new LSL_Rotation(0.0, 0.707107, 0.0, 0.707107) * llAxes2Rot(dir, left, up); 3556 LSL_Vector a1 = new LSL_Vector(0,0,0);
3557 a1.z = llAtan2(d1.y, d1.x);
3271 3558
3272 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3559 // Get the elevation (pitch)
3273 // set the rotation of the object, copy that behavior 3560 LSL_Vector a2 = new LSL_Vector(0,0,0);
3274 PhysicsActor pa = m_host.PhysActor; 3561 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
3562
3563 LSL_Rotation r1 = llEuler2Rot(a1);
3564 LSL_Rotation r2 = llEuler2Rot(a2);
3565 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
3275 3566
3276 if (m_host.ParentGroup.IsAttachment || strength == 0 || pa == null || !pa.IsPhysical) 3567 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
3277 { 3568 {
3278 llSetRot(rot); 3569 // Do nothing if either value is 0 (this has been checked in SL)
3570 if (strength <= 0.0 || damping <= 0.0)
3571 return;
3572
3573 llSetRot(r3 * r2 * r1);
3279 } 3574 }
3280 else 3575 else
3281 { 3576 {
3282 m_host.StartLookAt(rot, (float)strength, (float)damping); 3577 if (strength == 0)
3578 {
3579 llSetRot(r3 * r2 * r1);
3580 return;
3581 }
3582
3583 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
3283 } 3584 }
3284 } 3585 }
3285 3586
@@ -3325,22 +3626,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3325 } 3626 }
3326 else 3627 else
3327 { 3628 {
3328 if (m_host.IsRoot) 3629 // new SL always returns object mass
3329 { 3630// if (m_host.IsRoot)
3631// {
3330 return m_host.ParentGroup.GetMass(); 3632 return m_host.ParentGroup.GetMass();
3331 } 3633// }
3332 else 3634// else
3333 { 3635// {
3334 return m_host.GetMass(); 3636// return m_host.GetMass();
3335 } 3637// }
3336 } 3638 }
3337 } 3639 }
3338 3640
3339 public LSL_Float llGetMassMKS() 3641 public LSL_Float llGetMassMKS()
3340 { 3642 {
3341 // this is what the wiki says it does! 3643 return 100f * llGetMass();
3342 // http://wiki.secondlife.com/wiki/LlGetMassMKS
3343 return llGetMass() * 100.0;
3344 } 3644 }
3345 3645
3346 public void llCollisionFilter(string name, string id, int accept) 3646 public void llCollisionFilter(string name, string id, int accept)
@@ -3390,7 +3690,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3390 { 3690 {
3391 // Unregister controls from Presence 3691 // Unregister controls from Presence
3392 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3692 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3393 // Remove Take Control permission. 3693 // Remove Take Control permission.
3394 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3694 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3395 } 3695 }
3396 } 3696 }
@@ -3419,7 +3719,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3419 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3719 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3420 3720
3421 if (attachmentsModule != null) 3721 if (attachmentsModule != null)
3422 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true); 3722 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3423 else 3723 else
3424 return false; 3724 return false;
3425 } 3725 }
@@ -3449,9 +3749,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3449 { 3749 {
3450 m_host.AddScriptLPS(1); 3750 m_host.AddScriptLPS(1);
3451 3751
3452// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3453// return;
3454
3455 if (m_item.PermsGranter != m_host.OwnerID) 3752 if (m_item.PermsGranter != m_host.OwnerID)
3456 return; 3753 return;
3457 3754
@@ -3495,7 +3792,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3495 public void llInstantMessage(string user, string message) 3792 public void llInstantMessage(string user, string message)
3496 { 3793 {
3497 m_host.AddScriptLPS(1); 3794 m_host.AddScriptLPS(1);
3498 3795 UUID result;
3796 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3797 {
3798 Error("llInstantMessage","An invalid key was passed to llInstantMessage");
3799 ScriptSleep(2000);
3800 return;
3801 }
3802
3499 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3803 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
3500 // InstantMessageModule.OnInstantMessage searches through a list of scenes for a client matching the toAgent, 3804 // InstantMessageModule.OnInstantMessage searches through a list of scenes for a client matching the toAgent,
3501 // but I don't think we have a list of scenes available from here. 3805 // but I don't think we have a list of scenes available from here.
@@ -3505,31 +3809,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3505 3809
3506 // TODO: figure out values for client, fromSession, and imSessionID 3810 // TODO: figure out values for client, fromSession, and imSessionID
3507 // client.SendInstantMessage(m_host.UUID, fromSession, message, user, imSessionID, m_host.Name, AgentManager.InstantMessageDialog.MessageFromAgent, (uint)Util.UnixTimeSinceEpoch()); 3811 // client.SendInstantMessage(m_host.UUID, fromSession, message, user, imSessionID, m_host.Name, AgentManager.InstantMessageDialog.MessageFromAgent, (uint)Util.UnixTimeSinceEpoch());
3812 UUID friendTransactionID = UUID.Random();
3508 3813
3814 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3815
3509 GridInstantMessage msg = new GridInstantMessage(); 3816 GridInstantMessage msg = new GridInstantMessage();
3510 msg.fromAgentID = new Guid(m_host.OwnerID.ToString()); // fromAgentID.Guid; 3817 msg.fromAgentID = new Guid(m_host.OwnerID.ToString()); // fromAgentID.Guid;
3511 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3818 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3512 msg.imSessionID = new Guid(m_host.UUID.ToString()); // This is the item we're mucking with here 3819 msg.imSessionID = new Guid(m_host.UUID.ToString()); // This is the item we're mucking with here
3513// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3820 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3514// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3821 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
3515 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3822
3516 //if (client != null)
3517 //{
3518 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
3519 //}
3520 //else
3521 //{
3522 // msg.fromAgentName = "(hippos)";// Added for posterity. This means that we can't figure out who sent it
3523 //}
3524 // Cap the message length at 1024.
3525 if (message != null && message.Length > 1024) 3823 if (message != null && message.Length > 1024)
3526 msg.message = message.Substring(0, 1024); 3824 msg.message = message.Substring(0, 1024);
3527 else 3825 else
3528 msg.message = message; 3826 msg.message = message;
3529 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3827 msg.dialog = (byte)19; // MessageFromObject
3530 msg.fromGroup = false;// fromGroup; 3828 msg.fromGroup = false;// fromGroup;
3531 msg.offline = (byte)0; //offline; 3829 msg.offline = (byte)0; //offline;
3532 msg.ParentEstateID = 0; //ParentEstateID; 3830 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3533 msg.Position = new Vector3(m_host.AbsolutePosition); 3831 msg.Position = new Vector3(m_host.AbsolutePosition);
3534 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3832 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3535 3833
@@ -3648,25 +3946,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3648 { 3946 {
3649 m_host.AddScriptLPS(1); 3947 m_host.AddScriptLPS(1);
3650 3948
3651 if (m_host.PhysActor != null) 3949 PIDHoverType hoverType = PIDHoverType.Ground;
3950 if (water != 0)
3652 { 3951 {
3653 PIDHoverType hoverType = PIDHoverType.Ground; 3952 hoverType = PIDHoverType.GroundAndWater;
3654 if (water != 0)
3655 {
3656 hoverType = PIDHoverType.GroundAndWater;
3657 }
3658
3659 m_host.SetHoverHeight((float)height, hoverType, (float)tau);
3660 } 3953 }
3954 m_host.SetHoverHeight((float)height, hoverType, (float)tau);
3661 } 3955 }
3662 3956
3663 public void llStopHover() 3957 public void llStopHover()
3664 { 3958 {
3665 m_host.AddScriptLPS(1); 3959 m_host.AddScriptLPS(1);
3666 if (m_host.PhysActor != null) 3960 m_host.SetHoverHeight(0f, PIDHoverType.Ground, 0f);
3667 {
3668 m_host.SetHoverHeight(0f, PIDHoverType.Ground, 0f);
3669 }
3670 } 3961 }
3671 3962
3672 public void llMinEventDelay(double delay) 3963 public void llMinEventDelay(double delay)
@@ -3832,7 +4123,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3832 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 4123 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3833 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 4124 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3834 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 4125 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3835 ScriptBaseClass.PERMISSION_ATTACH; 4126 ScriptBaseClass.PERMISSION_ATTACH |
4127 ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS;
3836 } 4128 }
3837 else 4129 else
3838 { 4130 {
@@ -3849,15 +4141,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3849 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 4141 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3850 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 4142 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3851 } 4143 }
4144 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
4145 {
4146 implicitPerms = perm;
4147 }
3852 } 4148 }
3853 4149
3854 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 4150 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3855 { 4151 {
3856 lock (m_host.TaskInventory) 4152 m_host.TaskInventory.LockItemsForWrite(true);
3857 { 4153 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3858 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 4154 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3859 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 4155 m_host.TaskInventory.LockItemsForWrite(false);
3860 }
3861 4156
3862 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 4157 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3863 "run_time_permissions", new Object[] { 4158 "run_time_permissions", new Object[] {
@@ -3901,11 +4196,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3901 4196
3902 if (!m_waitingForScriptAnswer) 4197 if (!m_waitingForScriptAnswer)
3903 { 4198 {
3904 lock (m_host.TaskInventory) 4199 m_host.TaskInventory.LockItemsForWrite(true);
3905 { 4200 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3906 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 4201 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3907 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 4202 m_host.TaskInventory.LockItemsForWrite(false);
3908 }
3909 4203
3910 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 4204 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3911 m_waitingForScriptAnswer=true; 4205 m_waitingForScriptAnswer=true;
@@ -3934,14 +4228,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3934 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 4228 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3935 llReleaseControls(); 4229 llReleaseControls();
3936 4230
3937 lock (m_host.TaskInventory) 4231 m_host.TaskInventory.LockItemsForWrite(true);
3938 { 4232 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3939 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 4233 m_host.TaskInventory.LockItemsForWrite(false);
3940 } 4234
3941 4235 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3942 m_ScriptEngine.PostScriptEvent( 4236 "run_time_permissions", new Object[] {
3943 m_item.ItemID, 4237 new LSL_Integer(answer) },
3944 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 4238 new DetectParams[0]));
3945 } 4239 }
3946 4240
3947 public LSL_String llGetPermissionsKey() 4241 public LSL_String llGetPermissionsKey()
@@ -3980,15 +4274,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3980 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 4274 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3981 { 4275 {
3982 List<SceneObjectPart> parts = GetLinkParts(linknumber); 4276 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3983 4277 if (parts.Count > 0)
3984 foreach (SceneObjectPart part in parts) 4278 {
3985 part.SetFaceColorAlpha(face, color, null); 4279 try
4280 {
4281 foreach (SceneObjectPart part in parts)
4282 part.SetFaceColorAlpha(face, color, null);
4283 }
4284 finally { }
4285 }
3986 } 4286 }
3987 4287
3988 public void llCreateLink(string target, int parent) 4288 public void llCreateLink(string target, int parent)
3989 { 4289 {
3990 m_host.AddScriptLPS(1); 4290 m_host.AddScriptLPS(1);
3991 4291
4292 UUID targetID;
4293
4294 if (!UUID.TryParse(target, out targetID))
4295 return;
4296
3992 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4297 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3993 && !m_automaticLinkPermission) 4298 && !m_automaticLinkPermission)
3994 { 4299 {
@@ -4104,10 +4409,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4104 // Restructuring Multiple Prims. 4409 // Restructuring Multiple Prims.
4105 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4410 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
4106 parts.Remove(parentPrim.RootPart); 4411 parts.Remove(parentPrim.RootPart);
4107 foreach (SceneObjectPart part in parts) 4412 if (parts.Count > 0)
4108 { 4413 {
4109 parentPrim.DelinkFromGroup(part.LocalId, true); 4414 try
4110 } 4415 {
4416 foreach (SceneObjectPart part in parts)
4417 {
4418 parentPrim.DelinkFromGroup(part.LocalId, true);
4419 }
4420 }
4421 finally { }
4422 }
4423
4111 parentPrim.HasGroupChanged = true; 4424 parentPrim.HasGroupChanged = true;
4112 parentPrim.ScheduleGroupForFullUpdate(); 4425 parentPrim.ScheduleGroupForFullUpdate();
4113 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4426 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -4116,12 +4429,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4116 { 4429 {
4117 SceneObjectPart newRoot = parts[0]; 4430 SceneObjectPart newRoot = parts[0];
4118 parts.Remove(newRoot); 4431 parts.Remove(newRoot);
4119 foreach (SceneObjectPart part in parts) 4432
4433 try
4120 { 4434 {
4121 // Required for linking 4435 foreach (SceneObjectPart part in parts)
4122 part.ClearUpdateSchedule(); 4436 {
4123 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4437 part.ClearUpdateSchedule();
4438 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4439 }
4124 } 4440 }
4441 finally { }
4442
4125 newRoot.ParentGroup.HasGroupChanged = true; 4443 newRoot.ParentGroup.HasGroupChanged = true;
4126 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4444 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
4127 } 4445 }
@@ -4142,13 +4460,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4142 { 4460 {
4143 m_host.AddScriptLPS(1); 4461 m_host.AddScriptLPS(1);
4144 4462
4145 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4463 TaskInventoryItem item = m_item;
4464
4465 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4146 && !m_automaticLinkPermission) 4466 && !m_automaticLinkPermission)
4147 { 4467 {
4148 Error("llBreakAllLinks", "PERMISSION_CHANGE_LINKS permission not set"); 4468 Error("llBreakAllLinks","Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4149 return; 4469 return;
4150 } 4470 }
4151
4152 BreakAllLinks(); 4471 BreakAllLinks();
4153 } 4472 }
4154 4473
@@ -4173,13 +4492,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4173 public LSL_String llGetLinkKey(int linknum) 4492 public LSL_String llGetLinkKey(int linknum)
4174 { 4493 {
4175 m_host.AddScriptLPS(1); 4494 m_host.AddScriptLPS(1);
4495 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
4496 if (part != null)
4497 {
4498 return part.UUID.ToString();
4499 }
4500 else
4501 {
4502 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4503 {
4504 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4176 4505
4177 ISceneEntity entity = GetLinkEntity(m_host, linknum); 4506 if (linknum < 0)
4507 return UUID.Zero.ToString();
4178 4508
4179 if (entity != null) 4509 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4180 return entity.UUID.ToString(); 4510 if (avatars.Count > linknum)
4181 else 4511 {
4182 return ScriptBaseClass.NULL_KEY; 4512 return avatars[linknum].UUID.ToString();
4513 }
4514 }
4515 return UUID.Zero.ToString();
4516 }
4183 } 4517 }
4184 4518
4185 /// <summary> 4519 /// <summary>
@@ -4238,17 +4572,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4238 m_host.AddScriptLPS(1); 4572 m_host.AddScriptLPS(1);
4239 int count = 0; 4573 int count = 0;
4240 4574
4241 lock (m_host.TaskInventory) 4575 m_host.TaskInventory.LockItemsForRead(true);
4576 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4242 { 4577 {
4243 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4578 if (inv.Value.Type == type || type == -1)
4244 { 4579 {
4245 if (inv.Value.Type == type || type == -1) 4580 count = count + 1;
4246 {
4247 count = count + 1;
4248 }
4249 } 4581 }
4250 } 4582 }
4251 4583
4584 m_host.TaskInventory.LockItemsForRead(false);
4252 return count; 4585 return count;
4253 } 4586 }
4254 4587
@@ -4257,16 +4590,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4257 m_host.AddScriptLPS(1); 4590 m_host.AddScriptLPS(1);
4258 ArrayList keys = new ArrayList(); 4591 ArrayList keys = new ArrayList();
4259 4592
4260 lock (m_host.TaskInventory) 4593 m_host.TaskInventory.LockItemsForRead(true);
4594 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4261 { 4595 {
4262 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4596 if (inv.Value.Type == type || type == -1)
4263 { 4597 {
4264 if (inv.Value.Type == type || type == -1) 4598 keys.Add(inv.Value.Name);
4265 {
4266 keys.Add(inv.Value.Name);
4267 }
4268 } 4599 }
4269 } 4600 }
4601 m_host.TaskInventory.LockItemsForRead(false);
4270 4602
4271 if (keys.Count == 0) 4603 if (keys.Count == 0)
4272 { 4604 {
@@ -4336,6 +4668,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4336 } 4668 }
4337 } 4669 }
4338 } 4670 }
4671
4339 // destination is an avatar 4672 // destination is an avatar
4340 string message; 4673 string message;
4341 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId, out message); 4674 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId, out message);
@@ -4346,27 +4679,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4346 return; 4679 return;
4347 } 4680 }
4348 4681
4349 if (m_TransferModule != null) 4682 byte[] bucket = new byte[1];
4350 { 4683 bucket[0] = (byte)item.Type;
4351 byte[] bucket = new byte[1]; 4684 //byte[] objBytes = agentItem.ID.GetBytes();
4352 bucket[0] = (byte)item.Type; 4685 //Array.Copy(objBytes, 0, bucket, 1, 16);
4353 4686
4354 GridInstantMessage msg = new GridInstantMessage(World, 4687 GridInstantMessage msg = new GridInstantMessage(World,
4355 m_host.OwnerID, m_host.Name, destId, 4688 m_host.OwnerID, m_host.Name, destId,
4356 (byte)InstantMessageDialog.TaskInventoryOffered, 4689 (byte)InstantMessageDialog.TaskInventoryOffered,
4357 false, item.Name+". "+m_host.Name+" is located at "+ 4690 false, item.Name+". "+m_host.Name+" is located at "+
4358 World.RegionInfo.RegionName+" "+ 4691 World.RegionInfo.RegionName+" "+
4359 m_host.AbsolutePosition.ToString(), 4692 m_host.AbsolutePosition.ToString(),
4360 agentItem.ID, true, m_host.AbsolutePosition, 4693 agentItem.ID, true, m_host.AbsolutePosition,
4361 bucket, true); 4694 bucket, true);
4362 4695
4363 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4696 ScenePresence sp;
4364 }
4365 4697
4698 if (World.TryGetScenePresence(destId, out sp))
4699 {
4700 sp.ControllingClient.SendInstantMessage(msg);
4701 }
4702 else
4703 {
4704 if (m_TransferModule != null)
4705 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4706 }
4707
4708 //This delay should only occur when giving inventory to avatars.
4366 ScriptSleep(m_sleepMsOnGiveInventory); 4709 ScriptSleep(m_sleepMsOnGiveInventory);
4367 } 4710 }
4368 } 4711 }
4369 4712
4713 [DebuggerNonUserCode]
4370 public void llRemoveInventory(string name) 4714 public void llRemoveInventory(string name)
4371 { 4715 {
4372 m_host.AddScriptLPS(1); 4716 m_host.AddScriptLPS(1);
@@ -4421,14 +4765,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4421 { 4765 {
4422 m_host.AddScriptLPS(1); 4766 m_host.AddScriptLPS(1);
4423 4767
4424 UUID uuid = (UUID)id; 4768 UUID uuid;
4425 PresenceInfo pinfo = null; 4769 if (UUID.TryParse(id, out uuid))
4426 UserAccount account;
4427
4428 UserInfoCacheEntry ce;
4429
4430 lock (m_userInfoCache)
4431 { 4770 {
4771 PresenceInfo pinfo = null;
4772 UserAccount account;
4773
4774 UserInfoCacheEntry ce;
4432 if (!m_userInfoCache.TryGetValue(uuid, out ce)) 4775 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4433 { 4776 {
4434 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4777 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
@@ -4454,7 +4797,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4454 ce.time = Util.EnvironmentTickCount(); 4797 ce.time = Util.EnvironmentTickCount();
4455 ce.account = account; 4798 ce.account = account;
4456 ce.pinfo = pinfo; 4799 ce.pinfo = pinfo;
4457
4458 m_userInfoCache[uuid] = ce; 4800 m_userInfoCache[uuid] = ce;
4459 } 4801 }
4460 else 4802 else
@@ -4463,78 +4805,77 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4463 return UUID.Zero.ToString(); 4805 return UUID.Zero.ToString();
4464 4806
4465 account = ce.account; 4807 account = ce.account;
4808 pinfo = ce.pinfo;
4809 }
4466 4810
4467 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) 4811 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4468 >= LlRequestAgentDataCacheTimeoutMs) 4812 {
4813 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4814 if (pinfos != null && pinfos.Length > 0)
4469 { 4815 {
4470 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4816 foreach (PresenceInfo p in pinfos)
4471 if (pinfos != null && pinfos.Length > 0)
4472 { 4817 {
4473 foreach (PresenceInfo p in pinfos) 4818 if (p.RegionID != UUID.Zero)
4474 { 4819 {
4475 if (p.RegionID != UUID.Zero) 4820 pinfo = p;
4476 {
4477 pinfo = p;
4478 }
4479 } 4821 }
4480 } 4822 }
4481 else
4482 {
4483 pinfo = null;
4484 }
4485
4486 ce.time = Util.EnvironmentTickCount();
4487 ce.pinfo = pinfo;
4488 } 4823 }
4489 else 4824 else
4490 { 4825 pinfo = null;
4491 pinfo = ce.pinfo; 4826
4492 } 4827 ce.time = Util.EnvironmentTickCount();
4828 ce.pinfo = pinfo;
4493 } 4829 }
4494 }
4495 4830
4496 string reply = String.Empty; 4831 string reply = String.Empty;
4497 4832
4498 switch (data) 4833 switch (data)
4499 { 4834 {
4500 case ScriptBaseClass.DATA_ONLINE: 4835 case ScriptBaseClass.DATA_ONLINE: // DATA_ONLINE (0|1)
4501 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4836 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4502 reply = "1"; 4837 reply = "1";
4503 else 4838 else
4504 reply = "0"; 4839 reply = "0";
4505 break; 4840 break;
4506 case ScriptBaseClass.DATA_NAME: // (First Last) 4841 case ScriptBaseClass.DATA_NAME: // DATA_NAME (First Last)
4507 reply = account.FirstName + " " + account.LastName; 4842 reply = account.FirstName + " " + account.LastName;
4508 break; 4843 break;
4509 case ScriptBaseClass.DATA_BORN: // (YYYY-MM-DD) 4844 case ScriptBaseClass.DATA_BORN: // DATA_BORN (YYYY-MM-DD)
4510 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4845 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4511 born = born.AddSeconds(account.Created); 4846 born = born.AddSeconds(account.Created);
4512 reply = born.ToString("yyyy-MM-dd"); 4847 reply = born.ToString("yyyy-MM-dd");
4513 break; 4848 break;
4514 case ScriptBaseClass.DATA_RATING: // (0,0,0,0,0,0) 4849 case ScriptBaseClass.DATA_RATING: // DATA_RATING (0,0,0,0,0,0)
4515 reply = "0,0,0,0,0,0"; 4850 reply = "0,0,0,0,0,0";
4516 break; 4851 break;
4517 case 7: // DATA_USERLEVEL (integer). This is not available in LL and so has no constant. 4852 case 7: // DATA_USERLEVEL (integer). This is not available in LL and so has no constant.
4518 reply = account.UserLevel.ToString(); 4853 reply = account.UserLevel.ToString();
4519 break; 4854 break;
4520 case ScriptBaseClass.DATA_PAYINFO: // (0|1|2|3) 4855 case ScriptBaseClass.DATA_PAYINFO: // DATA_PAYINFO (0|1|2|3)
4521 reply = "0"; 4856 reply = "0";
4522 break; 4857 break;
4523 default: 4858 default:
4524 return UUID.Zero.ToString(); // Raise no event 4859 return UUID.Zero.ToString(); // Raise no event
4525 } 4860 }
4526 4861
4527 UUID rq = UUID.Random(); 4862 UUID rq = UUID.Random();
4528 4863
4529 UUID tid = AsyncCommands. 4864 UUID tid = AsyncCommands.
4530 DataserverPlugin.RegisterRequest(m_host.LocalId, 4865 DataserverPlugin.RegisterRequest(m_host.LocalId,
4531 m_item.ItemID, rq.ToString()); 4866 m_item.ItemID, rq.ToString());
4532 4867
4533 AsyncCommands. 4868 AsyncCommands.
4534 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4869 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4535 4870
4536 ScriptSleep(m_sleepMsOnRequestAgentData); 4871 ScriptSleep(m_sleepMsOnRequestAgentData);
4537 return tid.ToString(); 4872 return tid.ToString();
4873 }
4874 else
4875 {
4876 Error("llRequestAgentData","Invalid UUID passed to llRequestAgentData.");
4877 }
4878 return "";
4538 } 4879 }
4539 4880
4540 public LSL_String llRequestInventoryData(string name) 4881 public LSL_String llRequestInventoryData(string name)
@@ -4588,12 +4929,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4588 if (UUID.TryParse(agent, out agentId)) 4929 if (UUID.TryParse(agent, out agentId))
4589 { 4930 {
4590 ScenePresence presence = World.GetScenePresence(agentId); 4931 ScenePresence presence = World.GetScenePresence(agentId);
4591 if (presence != null) 4932 if (presence != null && presence.PresenceType != PresenceType.Npc)
4592 { 4933 {
4934 // agent must not be a god
4935 if (presence.UserLevel >= 200) return;
4936
4593 // agent must be over the owners land 4937 // agent must be over the owners land
4594 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4938 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4595 { 4939 {
4596 World.TeleportClientHome(agentId, presence.ControllingClient); 4940 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4941 {
4942 // They can't be teleported home for some reason
4943 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4944 if (regionInfo != null)
4945 {
4946 World.RequestTeleportLocation(
4947 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4948 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4949 }
4950 }
4597 } 4951 }
4598 } 4952 }
4599 } 4953 }
@@ -4611,20 +4965,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4611 ScenePresence presence = World.GetScenePresence(agentId); 4965 ScenePresence presence = World.GetScenePresence(agentId);
4612 if (presence != null && presence.PresenceType != PresenceType.Npc) 4966 if (presence != null && presence.PresenceType != PresenceType.Npc)
4613 { 4967 {
4614 // agent must not be a god
4615 if (presence.GodLevel >= 200) return;
4616
4617 if (destination == String.Empty) 4968 if (destination == String.Empty)
4618 destination = World.RegionInfo.RegionName; 4969 destination = World.RegionInfo.RegionName;
4619 4970
4620 // agent must be over the owners land 4971 if (m_item.PermsGranter == agentId)
4621 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4972 {
4973 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4974 {
4975 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4976 }
4977 }
4978
4979 // agent must be wearing the object
4980 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4622 { 4981 {
4623 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4982 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4624 } 4983 }
4625 else // or must be wearing the prim 4984 else
4626 { 4985 {
4627 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4986 // agent must not be a god
4987 if (presence.GodLevel >= 200) return;
4988
4989 // agent must be over the owners land
4990 ILandObject agentLand = World.LandChannel.GetLandObject(presence.AbsolutePosition);
4991 ILandObject objectLand = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
4992 if (m_host.OwnerID == objectLand.LandData.OwnerID && m_host.OwnerID == agentLand.LandData.OwnerID)
4628 { 4993 {
4629 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4994 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4630 } 4995 }
@@ -4642,23 +5007,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4642 5007
4643 if (UUID.TryParse(agent, out agentId)) 5008 if (UUID.TryParse(agent, out agentId))
4644 { 5009 {
5010 // This function is owner only!
5011 if (m_host.OwnerID != agentId)
5012 return;
5013
4645 ScenePresence presence = World.GetScenePresence(agentId); 5014 ScenePresence presence = World.GetScenePresence(agentId);
4646 if (presence != null && presence.PresenceType != PresenceType.Npc) 5015
5016 if (presence == null || presence.PresenceType == PresenceType.Npc)
5017 return;
5018
5019 // Can't TP sitting avatars
5020 if (presence.ParentID != 0) // Sitting
5021 return;
5022
5023 if (m_item.PermsGranter == agentId)
4647 { 5024 {
4648 // agent must not be a god 5025 // If attached using llAttachToAvatarTemp, cowardly refuse
4649 if (presence.GodLevel >= 200) return; 5026 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.ParentGroup.FromItemID == UUID.Zero)
5027 return;
4650 5028
4651 // agent must be over the owners land 5029 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4652 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4653 { 5030 {
4654 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 5031 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4655 }
4656 else // or must be wearing the prim
4657 {
4658 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4659 {
4660 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4661 }
4662 } 5032 }
4663 } 5033 }
4664 } 5034 }
@@ -4732,9 +5102,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4732 { 5102 {
4733 m_host.AddScriptLPS(1); 5103 m_host.AddScriptLPS(1);
4734 5104
5105 if(impact_sound == "")
5106 {
5107 m_host.CollisionSoundVolume = (float)impact_volume;
5108 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
5109 m_host.CollisionSoundType = 0;
5110 return;
5111 }
4735 // TODO: Parameter check logic required. 5112 // TODO: Parameter check logic required.
4736 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 5113 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4737 m_host.CollisionSoundVolume = (float)impact_volume; 5114 m_host.CollisionSoundVolume = (float)impact_volume;
5115 m_host.CollisionSoundType = 1;
4738 } 5116 }
4739 5117
4740 public LSL_String llGetAnimation(string id) 5118 public LSL_String llGetAnimation(string id)
@@ -4748,14 +5126,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4748 5126
4749 if (m_host.RegionHandle == presence.RegionHandle) 5127 if (m_host.RegionHandle == presence.RegionHandle)
4750 { 5128 {
4751 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4752
4753 if (presence != null) 5129 if (presence != null)
4754 { 5130 {
4755 AnimationSet currentAnims = presence.Animator.Animations; 5131// if (presence.SitGround)
4756 string currentAnimationState = String.Empty; 5132// return "Sitting on Ground";
4757 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 5133// if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4758 return currentAnimationState; 5134// return "Sitting";
5135
5136 string movementAnimation = presence.Animator.CurrentMovementAnimation;
5137 string lslMovementAnimation;
5138
5139 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
5140 return lslMovementAnimation;
4759 } 5141 }
4760 } 5142 }
4761 5143
@@ -4903,7 +5285,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4903 { 5285 {
4904 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 5286 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4905 float distance_term = distance * distance * distance; // Script Energy 5287 float distance_term = distance * distance * distance; // Script Energy
4906 float pusher_mass = m_host.GetMass(); 5288 // use total object mass and not part
5289 float pusher_mass = m_host.ParentGroup.GetMass();
4907 5290
4908 float PUSH_ATTENUATION_DISTANCE = 17f; 5291 float PUSH_ATTENUATION_DISTANCE = 17f;
4909 float PUSH_ATTENUATION_SCALE = 5f; 5292 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4938,7 +5321,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4938 { 5321 {
4939 if (local != 0) 5322 if (local != 0)
4940 { 5323 {
4941 applied_linear_impulse *= m_host.GetWorldRotation(); 5324// applied_linear_impulse *= m_host.GetWorldRotation();
5325 applied_linear_impulse *= pusheeav.GetWorldRotation();
4942 } 5326 }
4943 5327
4944 pa.AddForce(applied_linear_impulse, true); 5328 pa.AddForce(applied_linear_impulse, true);
@@ -5292,14 +5676,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5292 { 5676 {
5293 m_host.AddScriptLPS(1); 5677 m_host.AddScriptLPS(1);
5294 5678
5295 if (src == null) 5679 return src.Length;
5296 {
5297 return 0;
5298 }
5299 else
5300 {
5301 return src.Length;
5302 }
5303 } 5680 }
5304 5681
5305 public LSL_Integer llList2Integer(LSL_List src, int index) 5682 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5370,7 +5747,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5370 else if (src.Data[index] is LSL_Float) 5747 else if (src.Data[index] is LSL_Float)
5371 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5748 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5372 else if (src.Data[index] is LSL_String) 5749 else if (src.Data[index] is LSL_String)
5373 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5750 {
5751 string str = ((LSL_String) src.Data[index]).m_string;
5752 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5753 if (m != Match.Empty)
5754 {
5755 str = m.Value;
5756 double d = 0.0;
5757 if (!Double.TryParse(str, out d))
5758 return 0.0;
5759
5760 return d;
5761 }
5762 return 0.0;
5763 }
5374 return Convert.ToDouble(src.Data[index]); 5764 return Convert.ToDouble(src.Data[index]);
5375 } 5765 }
5376 catch (FormatException) 5766 catch (FormatException)
@@ -5674,7 +6064,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5674 } 6064 }
5675 } 6065 }
5676 } 6066 }
5677 else { 6067 else
6068 {
5678 object[] array = new object[src.Length]; 6069 object[] array = new object[src.Length];
5679 Array.Copy(src.Data, 0, array, 0, src.Length); 6070 Array.Copy(src.Data, 0, array, 0, src.Length);
5680 result = new LSL_List(array); 6071 result = new LSL_List(array);
@@ -5781,7 +6172,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5781 public LSL_Integer llGetRegionAgentCount() 6172 public LSL_Integer llGetRegionAgentCount()
5782 { 6173 {
5783 m_host.AddScriptLPS(1); 6174 m_host.AddScriptLPS(1);
5784 return new LSL_Integer(World.GetRootAgentCount()); 6175
6176 int count = 0;
6177 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
6178 count++;
6179 });
6180
6181 return new LSL_Integer(count);
5785 } 6182 }
5786 6183
5787 public LSL_Vector llGetRegionCorner() 6184 public LSL_Vector llGetRegionCorner()
@@ -5853,6 +6250,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5853 { 6250 {
5854 return ""; 6251 return "";
5855 } 6252 }
6253
5856 } 6254 }
5857 6255
5858 /// <summary> 6256 /// <summary>
@@ -5928,17 +6326,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5928 { 6326 {
5929 for (int i = 0; i < length; i++) 6327 for (int i = 0; i < length; i++)
5930 { 6328 {
6329 int needle = llGetListEntryType(test, 0).value;
6330 int haystack = llGetListEntryType(src, i).value;
6331
5931 // Why this piece of insanity? This is because most script constants are C# value types (e.g. int) 6332 // Why this piece of insanity? This is because most script constants are C# value types (e.g. int)
5932 // rather than wrapped LSL types. Such a script constant does not have int.Equal(LSL_Integer) code 6333 // rather than wrapped LSL types. Such a script constant does not have int.Equal(LSL_Integer) code
5933 // and so the comparison fails even if the LSL_Integer conceptually has the same value. 6334 // and so the comparison fails even if the LSL_Integer conceptually has the same value.
5934 // Therefore, here we test Equals on both the source and destination objects. 6335 // Therefore, here we test Equals on both the source and destination objects.
5935 // However, a future better approach may be use LSL struct script constants (e.g. LSL_Integer(1)). 6336 // However, a future better approach may be use LSL struct script constants (e.g. LSL_Integer(1)).
5936 if (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i])) 6337 if ((needle == haystack) && (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i])))
5937 { 6338 {
5938 int j; 6339 int j;
5939 for (j = 1; j < test.Length; j++) 6340 for (j = 1; j < test.Length; j++)
5940 if (!(src.Data[i+j].Equals(test.Data[j]) || test.Data[j].Equals(src.Data[i+j]))) 6341 {
6342 needle = llGetListEntryType(test, j).value;
6343 haystack = llGetListEntryType(src, i+j).value;
6344
6345 if ((needle != haystack) || (!(src.Data[i+j].Equals(test.Data[j]) || test.Data[j].Equals(src.Data[i+j]))))
5941 break; 6346 break;
6347 }
5942 6348
5943 if (j == test.Length) 6349 if (j == test.Length)
5944 { 6350 {
@@ -6087,6 +6493,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6087 flags |= ScriptBaseClass.AGENT_AWAY; 6493 flags |= ScriptBaseClass.AGENT_AWAY;
6088 } 6494 }
6089 6495
6496 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6497 UUID[] anims = agent.Animator.GetAnimationArray();
6498 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6499 {
6500 flags |= ScriptBaseClass.AGENT_BUSY;
6501 }
6502
6090 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6503 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
6091 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6504 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
6092 { 6505 {
@@ -6134,6 +6547,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6134 flags |= ScriptBaseClass.AGENT_SITTING; 6547 flags |= ScriptBaseClass.AGENT_SITTING;
6135 } 6548 }
6136 6549
6550 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6551 {
6552 flags |= ScriptBaseClass.AGENT_MALE;
6553 }
6554
6137 return flags; 6555 return flags;
6138 } 6556 }
6139 6557
@@ -6288,9 +6706,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6288 6706
6289 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6707 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6290 6708
6291 foreach (SceneObjectPart part in parts) 6709 try
6710 {
6711 foreach (SceneObjectPart part in parts)
6712 {
6713 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6714 }
6715 }
6716 finally
6292 { 6717 {
6293 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6294 } 6718 }
6295 } 6719 }
6296 6720
@@ -6344,13 +6768,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6344 6768
6345 if (m_host.OwnerID == land.LandData.OwnerID) 6769 if (m_host.OwnerID == land.LandData.OwnerID)
6346 { 6770 {
6347 World.TeleportClientHome(agentID, presence.ControllingClient); 6771 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6772 presence.TeleportWithMomentum(p, null);
6773 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
6348 } 6774 }
6349 } 6775 }
6350 } 6776 }
6351 ScriptSleep(m_sleepMsOnEjectFromLand); 6777 ScriptSleep(m_sleepMsOnEjectFromLand);
6352 } 6778 }
6353 6779
6780 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6781 {
6782 return ParseString2List(str, separators, in_spacers, false);
6783 }
6784
6354 public LSL_Integer llOverMyLand(string id) 6785 public LSL_Integer llOverMyLand(string id)
6355 { 6786 {
6356 m_host.AddScriptLPS(1); 6787 m_host.AddScriptLPS(1);
@@ -6403,26 +6834,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6403 } 6834 }
6404 else 6835 else
6405 { 6836 {
6406 agentSize = GetAgentSize(avatar); 6837// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6838 Vector3 s = avatar.Appearance.AvatarSize;
6839 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
6407 } 6840 }
6408
6409 return agentSize; 6841 return agentSize;
6410 } 6842 }
6411 6843
6412 public LSL_Integer llSameGroup(string agent) 6844 public LSL_Integer llSameGroup(string id)
6413 { 6845 {
6414 m_host.AddScriptLPS(1); 6846 m_host.AddScriptLPS(1);
6415 UUID agentId = new UUID(); 6847 UUID uuid = new UUID();
6416 if (!UUID.TryParse(agent, out agentId)) 6848 if (!UUID.TryParse(id, out uuid))
6417 return new LSL_Integer(0);
6418 ScenePresence presence = World.GetScenePresence(agentId);
6419 if (presence == null || presence.IsChildAgent) // Return flase for child agents
6420 return new LSL_Integer(0); 6849 return new LSL_Integer(0);
6421 IClientAPI client = presence.ControllingClient; 6850
6422 if (m_host.GroupID == client.ActiveGroupId) 6851 // Check if it's a group key
6852 if (uuid == m_host.ParentGroup.RootPart.GroupID)
6423 return new LSL_Integer(1); 6853 return new LSL_Integer(1);
6424 else 6854
6855 // We got passed a UUID.Zero
6856 if (uuid == UUID.Zero)
6857 return new LSL_Integer(0);
6858
6859 // Handle the case where id names an avatar
6860 ScenePresence presence = World.GetScenePresence(uuid);
6861 if (presence != null)
6862 {
6863 if (presence.IsChildAgent)
6864 return new LSL_Integer(0);
6865
6866 IClientAPI client = presence.ControllingClient;
6867 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6868 return new LSL_Integer(1);
6869
6870 return new LSL_Integer(0);
6871 }
6872
6873 // Handle object case
6874 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6875 if (part != null)
6876 {
6877 // This will handle both deed and non-deed and also the no
6878 // group case
6879 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6880 return new LSL_Integer(1);
6881
6425 return new LSL_Integer(0); 6882 return new LSL_Integer(0);
6883 }
6884
6885 return new LSL_Integer(0);
6426 } 6886 }
6427 6887
6428 public void llUnSit(string id) 6888 public void llUnSit(string id)
@@ -7236,6 +7696,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7236 7696
7237 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7697 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
7238 { 7698 {
7699 // LSL quaternions can normalize to 0, normal Quaternions can't.
7700 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7701 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7702
7239 part.SitTargetPosition = offset; 7703 part.SitTargetPosition = offset;
7240 part.SitTargetOrientation = rot; 7704 part.SitTargetOrientation = rot;
7241 part.ParentGroup.HasGroupChanged = true; 7705 part.ParentGroup.HasGroupChanged = true;
@@ -7290,7 +7754,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7290 UUID key; 7754 UUID key;
7291 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 7755 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
7292 7756
7293 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 7757 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false))
7294 { 7758 {
7295 int expires = 0; 7759 int expires = 0;
7296 if (hours != 0) 7760 if (hours != 0)
@@ -7431,18 +7895,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7431 Error("llDialog", "First parameter must be a key"); 7895 Error("llDialog", "First parameter must be a key");
7432 return; 7896 return;
7433 } 7897 }
7434 if (buttons.Length < 1) 7898
7899 int length = buttons.Length;
7900 if (length < 1)
7435 { 7901 {
7436 Error("llDialog", "At least 1 button must be shown"); 7902 Error("llDialog", "At least 1 button must be shown");
7437 return; 7903 return;
7438 } 7904 }
7439 if (buttons.Length > 12) 7905 if (length > 12)
7440 { 7906 {
7441 Error("llDialog", "No more than 12 buttons can be shown"); 7907 Error("llDialog", "No more than 12 buttons can be shown");
7442 return; 7908 return;
7443 } 7909 }
7444 string[] buts = new string[buttons.Length]; 7910
7445 for (int i = 0; i < buttons.Length; i++) 7911 string[] buts = new string[length];
7912 for (int i = 0; i < length; i++)
7446 { 7913 {
7447 if (buttons.Data[i].ToString() == String.Empty) 7914 if (buttons.Data[i].ToString() == String.Empty)
7448 { 7915 {
@@ -7513,9 +7980,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7513 return; 7980 return;
7514 } 7981 }
7515 7982
7516 // the rest of the permission checks are done in RezScript, so check the pin there as well 7983 SceneObjectPart dest = World.GetSceneObjectPart(destId);
7517 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7984 if (dest != null)
7985 {
7986 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7987 {
7988 // the rest of the permission checks are done in RezScript, so check the pin there as well
7989 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
7518 7990
7991 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7992 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7993 }
7994 }
7519 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7995 // this will cause the delay even if the script pin or permissions were wrong - seems ok
7520 ScriptSleep(m_sleepMsOnRemoteLoadScriptPin); 7996 ScriptSleep(m_sleepMsOnRemoteLoadScriptPin);
7521 } 7997 }
@@ -7589,19 +8065,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7589 public LSL_String llMD5String(string src, int nonce) 8065 public LSL_String llMD5String(string src, int nonce)
7590 { 8066 {
7591 m_host.AddScriptLPS(1); 8067 m_host.AddScriptLPS(1);
7592 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 8068 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
7593 } 8069 }
7594 8070
7595 public LSL_String llSHA1String(string src) 8071 public LSL_String llSHA1String(string src)
7596 { 8072 {
7597 m_host.AddScriptLPS(1); 8073 m_host.AddScriptLPS(1);
7598 return Util.SHA1Hash(src).ToLower(); 8074 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
7599 } 8075 }
7600 8076
7601 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 8077 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
7602 { 8078 {
7603 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 8079 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7604 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 8080 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
8081 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8082 return shapeBlock;
7605 8083
7606 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 8084 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
7607 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 8085 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -7706,6 +8184,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7706 // Prim type box, cylinder and prism. 8184 // Prim type box, cylinder and prism.
7707 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) 8185 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)
7708 { 8186 {
8187 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8188 return;
8189
7709 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 8190 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7710 ObjectShapePacket.ObjectDataBlock shapeBlock; 8191 ObjectShapePacket.ObjectDataBlock shapeBlock;
7711 8192
@@ -7759,6 +8240,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7759 // Prim type sphere. 8240 // Prim type sphere.
7760 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 8241 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7761 { 8242 {
8243 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8244 return;
8245
7762 ObjectShapePacket.ObjectDataBlock shapeBlock; 8246 ObjectShapePacket.ObjectDataBlock shapeBlock;
7763 8247
7764 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 8248 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7805,6 +8289,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7805 // Prim type torus, tube and ring. 8289 // Prim type torus, tube and ring.
7806 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) 8290 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)
7807 { 8291 {
8292 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8293 return;
8294
7808 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 8295 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7809 ObjectShapePacket.ObjectDataBlock shapeBlock; 8296 ObjectShapePacket.ObjectDataBlock shapeBlock;
7810 8297
@@ -7940,6 +8427,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7940 // Prim type sculpt. 8427 // Prim type sculpt.
7941 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 8428 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7942 { 8429 {
8430 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8431 return;
8432
7943 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 8433 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7944 UUID sculptId; 8434 UUID sculptId;
7945 8435
@@ -7962,7 +8452,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7962 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 8452 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7963 { 8453 {
7964 // default 8454 // default
7965 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 8455 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7966 } 8456 }
7967 8457
7968 part.Shape.SetSculptProperties((byte)type, sculptId); 8458 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7995,9 +8485,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7995 SetLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 8485 SetLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7996 } 8486 }
7997 8487
7998 protected void SetLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 8488 private void SetLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7999 { 8489 {
8000 SetEntityParams(GetLinkEntities(linknumber), rules, originFunc); 8490 List<object> parts = new List<object>();
8491 List<SceneObjectPart> prims = GetLinkParts(linknumber);
8492 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
8493 foreach (SceneObjectPart p in prims)
8494 parts.Add(p);
8495 foreach (ScenePresence p in avatars)
8496 parts.Add(p);
8497
8498 LSL_List remaining = new LSL_List();
8499 uint rulesParsed = 0;
8500
8501 if (parts.Count > 0)
8502 {
8503 foreach (object part in parts)
8504 {
8505 if (part is SceneObjectPart)
8506 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
8507 else
8508 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
8509 }
8510
8511 while (remaining.Length > 2)
8512 {
8513 linknumber = remaining.GetLSLIntegerItem(0);
8514 rules = remaining.GetSublist(1, -1);
8515 parts.Clear();
8516 prims = GetLinkParts(linknumber);
8517 avatars = GetLinkAvatars(linknumber);
8518 foreach (SceneObjectPart p in prims)
8519 parts.Add(p);
8520 foreach (ScenePresence p in avatars)
8521 parts.Add(p);
8522
8523 remaining = new LSL_List();
8524 foreach (object part in parts)
8525 {
8526 if (part is SceneObjectPart)
8527 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
8528 else
8529 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
8530 }
8531 }
8532 }
8001 } 8533 }
8002 8534
8003 protected void SetEntityParams(List<ISceneEntity> entities, LSL_List rules, string originFunc) 8535 protected void SetEntityParams(List<ISceneEntity> entities, LSL_List rules, string originFunc)
@@ -8176,11 +8708,81 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8176 } 8708 }
8177 } 8709 }
8178 8710
8711 public LSL_List llGetPhysicsMaterial()
8712 {
8713 LSL_List result = new LSL_List();
8714
8715 result.Add(new LSL_Float(m_host.GravityModifier));
8716 result.Add(new LSL_Float(m_host.Restitution));
8717 result.Add(new LSL_Float(m_host.Friction));
8718 result.Add(new LSL_Float(m_host.Density));
8719
8720 return result;
8721 }
8722
8723 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
8724 float material_density, float material_friction,
8725 float material_restitution, float material_gravity_modifier)
8726 {
8727 ExtraPhysicsData physdata = new ExtraPhysicsData();
8728 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
8729 physdata.Density = part.Density;
8730 physdata.Friction = part.Friction;
8731 physdata.Bounce = part.Restitution;
8732 physdata.GravitationModifier = part.GravityModifier;
8733
8734 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
8735 physdata.Density = material_density;
8736 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
8737 physdata.Friction = material_friction;
8738 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
8739 physdata.Bounce = material_restitution;
8740 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
8741 physdata.GravitationModifier = material_gravity_modifier;
8742
8743 part.UpdateExtraPhysics(physdata);
8744 }
8745
8746 public void llSetPhysicsMaterial(int material_bits,
8747 float material_gravity_modifier, float material_restitution,
8748 float material_friction, float material_density)
8749 {
8750 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8751 }
8752
8753 // vector up using libomv (c&p from sop )
8754 // vector up rotated by r
8755 private Vector3 Zrot(Quaternion r)
8756 {
8757 double x, y, z, m;
8758
8759 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
8760 if (Math.Abs(1.0 - m) > 0.000001)
8761 {
8762 m = 1.0 / Math.Sqrt(m);
8763 r.X *= (float)m;
8764 r.Y *= (float)m;
8765 r.Z *= (float)m;
8766 r.W *= (float)m;
8767 }
8768
8769 x = 2 * (r.X * r.Z + r.Y * r.W);
8770 y = 2 * (-r.X * r.W + r.Y * r.Z);
8771 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
8772
8773 return new Vector3((float)x, (float)y, (float)z);
8774 }
8775
8179 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 8776 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
8180 { 8777 {
8778 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8779 return new LSL_List();
8780
8181 int idx = 0; 8781 int idx = 0;
8182 int idxStart = 0; 8782 int idxStart = 0;
8183 8783
8784 SceneObjectGroup parentgrp = part.ParentGroup;
8785
8184 bool positionChanged = false; 8786 bool positionChanged = false;
8185 LSL_Vector currentPosition = GetPartLocalPos(part); 8787 LSL_Vector currentPosition = GetPartLocalPos(part);
8186 8788
@@ -8216,8 +8818,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8216 Error(originFunc, string.Format("Error running rule #{0} -> PRIM_POS_LOCAL: arg #{1} - parameter 1 must be vector", rulesParsed, idx - idxStart - 1)); 8818 Error(originFunc, string.Format("Error running rule #{0} -> PRIM_POS_LOCAL: arg #{1} - parameter 1 must be vector", rulesParsed, idx - idxStart - 1));
8217 return new LSL_List(); 8819 return new LSL_List();
8218 } 8820 }
8821 if (part.IsRoot && !part.ParentGroup.IsAttachment)
8822 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
8823 else
8824 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
8219 positionChanged = true; 8825 positionChanged = true;
8220 currentPosition = GetSetPosTarget(part, v, currentPosition);
8221 8826
8222 break; 8827 break;
8223 case ScriptBaseClass.PRIM_SIZE: 8828 case ScriptBaseClass.PRIM_SIZE:
@@ -8242,7 +8847,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8242 return new LSL_List(); 8847 return new LSL_List();
8243 } 8848 }
8244 // try to let this work as in SL... 8849 // try to let this work as in SL...
8245 if (part.ParentID == 0) 8850 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
8246 { 8851 {
8247 // special case: If we are root, rotate complete SOG to new rotation 8852 // special case: If we are root, rotate complete SOG to new rotation
8248 SetRot(part, q); 8853 SetRot(part, q);
@@ -9243,7 +9848,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9243 9848
9244 break; 9849 break;
9245 9850
9246 case ScriptBaseClass.PRIM_TEMP_ON_REZ: 9851 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
9852 if (remain < 5)
9853 return new LSL_List();
9854
9855 int material_bits = rules.GetLSLIntegerItem(idx++);
9856 float material_density = (float)rules.GetLSLFloatItem(idx++);
9857 float material_friction = (float)rules.GetLSLFloatItem(idx++);
9858 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
9859 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
9860
9861 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
9862
9863 break;
9864
9865 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
9247 if (remain < 1) 9866 if (remain < 1)
9248 return new LSL_List(); 9867 return new LSL_List();
9249 string temp = rules.Data[idx++].ToString(); 9868 string temp = rules.Data[idx++].ToString();
@@ -9437,14 +10056,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9437 if (part.ParentGroup.RootPart == part) 10056 if (part.ParentGroup.RootPart == part)
9438 { 10057 {
9439 SceneObjectGroup parent = part.ParentGroup; 10058 SceneObjectGroup parent = part.ParentGroup;
9440 parent.UpdateGroupPosition(currentPosition); 10059// Util.FireAndForget(delegate(object x) {
10060 parent.UpdateGroupPosition(currentPosition);
10061// });
9441 } 10062 }
9442 else 10063 else
9443 { 10064 {
9444 part.OffsetPosition = currentPosition; 10065 part.OffsetPosition = currentPosition;
9445 SceneObjectGroup parent = part.ParentGroup; 10066// SceneObjectGroup parent = part.ParentGroup;
9446 parent.HasGroupChanged = true; 10067// parent.HasGroupChanged = true;
9447 parent.ScheduleGroupForTerseUpdate(); 10068// parent.ScheduleGroupForTerseUpdate();
10069 part.ScheduleTerseUpdate();
9448 } 10070 }
9449 } 10071 }
9450 } 10072 }
@@ -9596,10 +10218,104 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9596 10218
9597 public LSL_String llXorBase64Strings(string str1, string str2) 10219 public LSL_String llXorBase64Strings(string str1, string str2)
9598 { 10220 {
10221 int padding = 0;
10222
10223 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
10224
10225 ScriptSleep(300);
9599 m_host.AddScriptLPS(1); 10226 m_host.AddScriptLPS(1);
9600 Deprecated("llXorBase64Strings", "Use llXorBase64 instead"); 10227
9601 ScriptSleep(m_sleepMsOnXorBase64Strings); 10228 if (str1 == String.Empty)
9602 return String.Empty; 10229 return String.Empty;
10230 if (str2 == String.Empty)
10231 return str1;
10232
10233 int len = str2.Length;
10234 if ((len % 4) != 0) // LL is EVIL!!!!
10235 {
10236 while (str2.EndsWith("="))
10237 str2 = str2.Substring(0, str2.Length - 1);
10238
10239 len = str2.Length;
10240 int mod = len % 4;
10241
10242 if (mod == 1)
10243 str2 = str2.Substring(0, str2.Length - 1);
10244 else if (mod == 2)
10245 str2 += "==";
10246 else if (mod == 3)
10247 str2 += "=";
10248 }
10249
10250 byte[] data1;
10251 byte[] data2;
10252 try
10253 {
10254 data1 = Convert.FromBase64String(str1);
10255 data2 = Convert.FromBase64String(str2);
10256 }
10257 catch (Exception)
10258 {
10259 return new LSL_String(String.Empty);
10260 }
10261
10262 // For cases where the decoded length of s2 is greater
10263 // than the decoded length of s1, simply perform a normal
10264 // decode and XOR
10265 //
10266 /*
10267 if (data2.Length >= data1.Length)
10268 {
10269 for (int pos = 0 ; pos < data1.Length ; pos++ )
10270 data1[pos] ^= data2[pos];
10271
10272 return Convert.ToBase64String(data1);
10273 }
10274 */
10275
10276 // Remove padding
10277 while (str1.EndsWith("="))
10278 {
10279 str1 = str1.Substring(0, str1.Length - 1);
10280 padding++;
10281 }
10282 while (str2.EndsWith("="))
10283 str2 = str2.Substring(0, str2.Length - 1);
10284
10285 byte[] d1 = new byte[str1.Length];
10286 byte[] d2 = new byte[str2.Length];
10287
10288 for (int i = 0 ; i < str1.Length ; i++)
10289 {
10290 int idx = b64.IndexOf(str1.Substring(i, 1));
10291 if (idx == -1)
10292 idx = 0;
10293 d1[i] = (byte)idx;
10294 }
10295
10296 for (int i = 0 ; i < str2.Length ; i++)
10297 {
10298 int idx = b64.IndexOf(str2.Substring(i, 1));
10299 if (idx == -1)
10300 idx = 0;
10301 d2[i] = (byte)idx;
10302 }
10303
10304 string output = String.Empty;
10305
10306 for (int pos = 0 ; pos < d1.Length ; pos++)
10307 output += b64[d1[pos] ^ d2[pos % d2.Length]];
10308
10309 // Here's a funny thing: LL blithely violate the base64
10310 // standard pretty much everywhere. Here, padding is
10311 // added only if the first input string had it, rather
10312 // than when the data actually needs it. This can result
10313 // in invalid base64 being returned. Go figure.
10314
10315 while (padding-- > 0)
10316 output += "=";
10317
10318 return output;
9603 } 10319 }
9604 10320
9605 public void llRemoteDataSetRegion() 10321 public void llRemoteDataSetRegion()
@@ -9742,188 +10458,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9742 public LSL_List llGetBoundingBox(string obj) 10458 public LSL_List llGetBoundingBox(string obj)
9743 { 10459 {
9744 m_host.AddScriptLPS(1); 10460 m_host.AddScriptLPS(1);
9745
9746 // Get target avatar if non-seated avatar or attachment, or prim and object
9747 UUID objID = UUID.Zero; 10461 UUID objID = UUID.Zero;
9748 UUID.TryParse(obj, out objID);
9749 ScenePresence agent = World.GetScenePresence(objID);
9750 if (agent != null)
9751 {
9752 if (agent.ParentPart != null)
9753 {
9754 objID = agent.ParentPart.UUID;
9755 agent = null;
9756 }
9757 }
9758 SceneObjectGroup group = null;
9759 SceneObjectPart target = World.GetSceneObjectPart(objID);
9760 if (target != null)
9761 {
9762 group = target.ParentGroup;
9763 if (group.IsAttachment) {
9764 objID = group.AttachedAvatar;
9765 agent = World.GetScenePresence(objID);
9766 group = null;
9767 target = null;
9768 }
9769 }
9770
9771 // Initialize but break if no target
9772 LSL_List result = new LSL_List(); 10462 LSL_List result = new LSL_List();
9773 int groupCount = 0; 10463
9774 int partCount = 0; 10464 // If the ID is not valid, return null result
9775 int vertexCount = 0; 10465 if (!UUID.TryParse(obj, out objID))
9776 if (target == null && agent == null)
9777 { 10466 {
9778 result.Add(new LSL_Vector()); 10467 result.Add(new LSL_Vector());
9779 result.Add(new LSL_Vector()); 10468 result.Add(new LSL_Vector());
9780 if (m_addStatsInGetBoundingBox)
9781 result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount));
9782 return result; 10469 return result;
9783 } 10470 }
9784 Vector3 minPosition = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
9785 Vector3 maxPosition = new Vector3(float.MinValue, float.MinValue, float.MinValue);
9786 10471
9787 // Try to get a mesher 10472 // Check if this is an attached prim. If so, replace
9788 IRendering primMesher = null; 10473 // the UUID with the avatar UUID and report it's bounding box
9789 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); 10474 SceneObjectPart part = World.GetSceneObjectPart(objID);
9790 if (renderers.Count > 0) 10475 if (part != null && part.ParentGroup.IsAttachment)
9791 primMesher = RenderingLoader.LoadRenderer(renderers[0]); 10476 objID = part.ParentGroup.AttachedAvatar;
9792 10477
9793 // Get bounding box of just avatar, seated or not 10478 // Find out if this is an avatar ID. If so, return it's box
9794 if (agent != null) 10479 ScenePresence presence = World.GetScenePresence(objID);
9795 { 10480 if (presence != null)
9796 bool hasParent = false;
9797 Vector3 lower;
9798 Vector3 upper;
9799 BoundingBoxOfScenePresence(agent, out lower, out upper);
9800 Vector3 offset = Vector3.Zero;
9801
9802 // Since local bounding box unrotated and untilted, keep it simple
9803 AddBoundingBoxOfSimpleBox(lower, upper, offset, agent.Rotation, hasParent, ref minPosition, ref maxPosition, ref vertexCount);
9804 partCount++;
9805 groupCount++;
9806
9807 // Return lower and upper bounding box corners
9808 result.Add(new LSL_Vector(minPosition));
9809 result.Add(new LSL_Vector(maxPosition));
9810 if (m_addStatsInGetBoundingBox)
9811 result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount));
9812 return result;
9813 }
9814 // Get bounding box of object including seated avatars
9815 else if (group != null)
9816 { 10481 {
9817 // Merge bounding boxes of all parts (prims and mesh) 10482 // As per LSL Wiki, there is no difference between sitting
9818 foreach (SceneObjectPart part in group.Parts) 10483 // and standing avatar since server 1.36
9819 { 10484 LSL_Vector lower;
9820 bool hasParent = (!part.IsRoot); 10485 LSL_Vector upper;
9821 // When requested or if no mesher, keep it simple
9822 if (m_useSimpleBoxesInGetBoundingBox || primMesher == null)
9823 {
9824 AddBoundingBoxOfSimpleBox(part.Scale * -0.5f, part.Scale * 0.5f, part.OffsetPosition, part.RotationOffset, hasParent, ref minPosition, ref maxPosition, ref vertexCount);
9825 }
9826 // Do the full mounty
9827 else
9828 {
9829 Primitive omvPrim = part.Shape.ToOmvPrimitive(part.OffsetPosition, part.RotationOffset);
9830 byte[] sculptAsset = null;
9831 if (omvPrim.Sculpt != null)
9832 sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString());
9833
9834 // When part is mesh
9835 // Quirk: Only imports as incompletely populated faceted mesh object, so needs an own handler.
9836 if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null)
9837 {
9838 AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
9839 FacetedMesh mesh = null;
9840 FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, DetailLevel.Highest, out mesh);
9841 meshAsset = null;
9842 if (mesh != null)
9843 {
9844 AddBoundingBoxOfFacetedMesh(mesh, omvPrim, hasParent, ref minPosition, ref maxPosition, ref vertexCount);
9845 mesh = null;
9846 }
9847 }
9848
9849 // When part is sculpt
9850 // Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt.
9851 else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null)
9852 {
9853 IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>();
9854 if (imgDecoder != null)
9855 {
9856 Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
9857 if (sculpt != null)
9858 {
9859 SimpleMesh mesh = primMesher.GenerateSimpleSculptMesh(omvPrim, (Bitmap)sculpt, DetailLevel.Medium);
9860 sculpt.Dispose();
9861 if (mesh != null)
9862 {
9863 AddBoundingBoxOfSimpleMesh(mesh, omvPrim, hasParent, ref minPosition, ref maxPosition, ref vertexCount);
9864 mesh = null;
9865 }
9866 }
9867 }
9868 }
9869 10486
9870 // When part is prim 10487 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
9871 else if (omvPrim.Sculpt == null)
9872 {
9873 SimpleMesh mesh = primMesher.GenerateSimpleMesh(omvPrim, DetailLevel.Medium);
9874 if (mesh != null)
9875 {
9876 AddBoundingBoxOfSimpleMesh(mesh, omvPrim, hasParent, ref minPosition, ref maxPosition, ref vertexCount);
9877 mesh = null;
9878 }
9879 }
9880 10488
9881 // When all else fails, try fallback to simple box 10489 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
9882 else 10490 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
9883 { 10491/*
9884 AddBoundingBoxOfSimpleBox(part.Scale * -0.5f, part.Scale * 0.5f, part.OffsetPosition, part.RotationOffset, hasParent, ref minPosition, ref maxPosition, ref vertexCount); 10492 {
9885 } 10493 // This is for ground sitting avatars
9886 } 10494 float height = presence.Appearance.AvatarHeight / 2.66666667f;
9887 partCount++; 10495 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
10496 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
10497 }
10498 else
10499 {
10500 // This is for standing/flying avatars
10501 float height = presence.Appearance.AvatarHeight / 2.0f;
10502 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
10503 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
9888 } 10504 }
9889 }
9890
9891 // Merge bounding boxes of seated avatars
9892 foreach (ScenePresence sp in group.GetSittingAvatars())
9893 {
9894 Vector3 lower;
9895 Vector3 upper;
9896 BoundingBoxOfScenePresence(sp, out lower, out upper);
9897 Vector3 offset = sp.OffsetPosition;
9898 10505
9899 bool hasParent = true; 10506 // Adjust to the documented error offsets (see LSL Wiki)
9900 // When requested or if no mesher, keep it simple 10507 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
9901 if (m_useSimpleBoxesInGetBoundingBox || primMesher == null) 10508 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
10509*/
9902 { 10510 {
9903 AddBoundingBoxOfSimpleBox(lower, upper, offset, sp.Rotation, hasParent, ref minPosition, ref maxPosition, ref vertexCount); 10511 // This is for ground sitting avatars TODO!
10512 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
10513 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
9904 } 10514 }
9905 // Do the full mounty
9906 else 10515 else
9907 { 10516 {
9908 // Prim shapes don't do center offsets, so add it here. 10517 // This is for standing/flying avatars
9909 offset = offset + (lower + upper) * 0.5f * sp.Rotation; 10518 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
9910 Primitive omvPrim = MakeOpenMetaversePrim(upper - lower, offset, sp.Rotation, ScriptBaseClass.PRIM_TYPE_SPHERE); 10519 upper = new LSL_Vector(box.X, box.Y, box.Z);
9911 SimpleMesh mesh = primMesher.GenerateSimpleMesh(omvPrim, DetailLevel.Medium);
9912 AddBoundingBoxOfSimpleMesh(mesh, omvPrim, hasParent, ref minPosition, ref maxPosition, ref vertexCount);
9913 mesh = null;
9914 } 10520 }
9915 partCount++; 10521
10522 if (lower.x > upper.x)
10523 lower.x = upper.x;
10524 if (lower.y > upper.y)
10525 lower.y = upper.y;
10526 if (lower.z > upper.z)
10527 lower.z = upper.z;
10528
10529 result.Add(lower);
10530 result.Add(upper);
10531 return result;
9916 } 10532 }
9917 10533
9918 groupCount++; 10534 part = World.GetSceneObjectPart(objID);
10535 // Currently only works for single prims without a sitting avatar
10536 if (part != null)
10537 {
10538 float minX;
10539 float maxX;
10540 float minY;
10541 float maxY;
10542 float minZ;
10543 float maxZ;
9919 10544
9920 // Return lower and upper bounding box corners 10545 // This BBox is in sim coordinates, with the offset being
9921 result.Add(new LSL_Vector(minPosition)); 10546 // a contained point.
9922 result.Add(new LSL_Vector(maxPosition)); 10547 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
9923 if (m_addStatsInGetBoundingBox) 10548 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
9924 result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount)); 10549
10550 minX -= offsets[0].X;
10551 maxX -= offsets[0].X;
10552 minY -= offsets[0].Y;
10553 maxY -= offsets[0].Y;
10554 minZ -= offsets[0].Z;
10555 maxZ -= offsets[0].Z;
10556
10557 LSL_Vector lower;
10558 LSL_Vector upper;
10559
10560 // Adjust to the documented error offsets (see LSL Wiki)
10561 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
10562 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
10563
10564 if (lower.x > upper.x)
10565 lower.x = upper.x;
10566 if (lower.y > upper.y)
10567 lower.y = upper.y;
10568 if (lower.z > upper.z)
10569 lower.z = upper.z;
10570
10571 result.Add(lower);
10572 result.Add(upper);
10573 return result;
10574 }
9925 10575
9926 primMesher = null; 10576 // Not found so return empty values
10577 result.Add(new LSL_Vector());
10578 result.Add(new LSL_Vector());
9927 return result; 10579 return result;
9928 } 10580 }
9929 10581
@@ -9963,425 +10615,71 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9963 } 10615 }
9964 } 10616 }
9965 10617
9966 /// <summary>
9967 /// Helper to approximate a part with a simple box.
9968 /// </summary>
9969 private void AddBoundingBoxOfSimpleBox(Vector3 corner1, Vector3 corner2, Vector3 offset, Quaternion rotation, bool hasParent, ref Vector3 lower, ref Vector3 upper, ref int count)
9970 {
9971 // Parse the 8 box corners
9972 for (int i = 0; i < 8; i++)
9973 {
9974 // Calculate each box corner
9975 Vector3 position = corner1;
9976 if ((i & 1) != 0)
9977 position.X = corner2.X;
9978 if ((i & 2) != 0)
9979 position.Y = corner2.Y;
9980 if ((i & 4) != 0)
9981 position.Z = corner2.Z;
9982 // Rotate part unless part is root
9983 if (hasParent)
9984 position = position * rotation;
9985 position = position + offset;
9986 // Adjust lower and upper bounding box corners if needed
9987 lower = Vector3.Min(lower, position);
9988 upper = Vector3.Max(upper, position);
9989 count++;
9990 }
9991 }
9992
9993 /// <summary>
9994 /// Helper to parse a meshed prim and needed especially
9995 /// for accuracy with tortured prims and sculpts.
9996 /// </summary>
9997 private void AddBoundingBoxOfSimpleMesh(SimpleMesh mesh, Primitive prim, bool hasParent, ref Vector3 lower, ref Vector3 upper, ref int count)
9998 {
9999 // Quirk: A meshed box contains 10 instead of the 8 necessary vertices.
10000 if (mesh != null)
10001 {
10002 // Parse each vertex in mesh
10003 foreach (Vertex vertex in mesh.Vertices)
10004 {
10005 Vector3 position = vertex.Position;
10006 position = position * prim.Scale;
10007 // Rotate part unless part is root
10008 if (hasParent)
10009 position = position * prim.Rotation;
10010 position = position + prim.Position;
10011 // Adjust lower and upper bounding box corners if needed
10012 lower = Vector3.Min(lower, position);
10013 upper = Vector3.Max(upper, position);
10014 count++;
10015 }
10016 }
10017 }
10018
10019 /// <summary>
10020 /// Helper to parse mesh because no method exists
10021 /// to parse mesh assets to SimpleMesh.
10022 /// </summary>
10023 private void AddBoundingBoxOfFacetedMesh(FacetedMesh mesh, Primitive prim, bool hasParent, ref Vector3 lower, ref Vector3 upper, ref int count)
10024 {
10025 if (mesh != null)
10026 {
10027 // Parse each face in mesh
10028 // since vertex array isn't populated.
10029 // This parses each unique vertex 3-6 times.
10030 foreach (Face face in mesh.Faces)
10031 {
10032 // Parse each vertex in face
10033 foreach (Vertex vertex in face.Vertices)
10034 {
10035 Vector3 position = vertex.Position;
10036 position = position * prim.Scale;
10037 // Rotate part unless part is root
10038 if (hasParent)
10039 position = position * prim.Rotation;
10040 position = position + prim.Position;
10041 // Adjust lower and upper bounding box corners if needed
10042 lower = Vector3.Min(lower, position);
10043 upper = Vector3.Max(upper, position);
10044 count++;
10045 }
10046 }
10047 }
10048 }
10049
10050 /// <summary>
10051 /// Helper to make up an OpenMetaverse prim
10052 /// needed to create mesh from parts.
10053 /// </summary>
10054 private Primitive MakeOpenMetaversePrim(Vector3 scale, Vector3 position, Quaternion rotation, int primType)
10055 {
10056 // Initialize and set common parameters
10057 Primitive prim = new OpenMetaverse.Primitive();
10058 prim.Scale = scale;
10059 prim.Position = position;
10060 prim.Rotation = rotation;
10061 prim.PrimData.PathShearX = 0.0f;
10062 prim.PrimData.PathShearY = 0.0f;
10063 prim.PrimData.PathBegin = 0.0f;
10064 prim.PrimData.PathEnd = 1.0f;
10065 prim.PrimData.PathScaleX = 1.0f;
10066 prim.PrimData.PathScaleY = 1.0f;
10067 prim.PrimData.PathTaperX = 0.0f;
10068 prim.PrimData.PathTaperY = 0.0f;
10069 prim.PrimData.PathTwistBegin = 0.0f;
10070 prim.PrimData.PathTwist = 0.0f;
10071 prim.PrimData.ProfileBegin = 0.0f;
10072 prim.PrimData.ProfileEnd = 1.0f;
10073 prim.PrimData.ProfileHollow = 0.0f;
10074 prim.PrimData.ProfileCurve = (ProfileCurve)1;
10075 prim.PrimData.ProfileHole = (HoleType)0;
10076 prim.PrimData.PathCurve = (PathCurve)16;
10077 prim.PrimData.PathRadiusOffset = 0.0f;
10078 prim.PrimData.PathRevolutions = 1.0f;
10079 prim.PrimData.PathSkew = 0.0f;
10080 prim.PrimData.PCode = OpenMetaverse.PCode.Prim;
10081 prim.PrimData.State = (byte)0;
10082
10083 // Set type specific parameters
10084 switch (primType)
10085 {
10086 // Set specific parameters for box
10087 case ScriptBaseClass.PRIM_TYPE_BOX:
10088 prim.PrimData.PathScaleY = 1.0f;
10089 prim.PrimData.ProfileCurve = (ProfileCurve)1;
10090 prim.PrimData.PathCurve = (PathCurve)16;
10091 break;
10092 // Set specific parameters for cylinder
10093 case ScriptBaseClass.PRIM_TYPE_CYLINDER:
10094 prim.PrimData.PathScaleY = 1.0f;
10095 prim.PrimData.ProfileCurve = (ProfileCurve)0;
10096 prim.PrimData.PathCurve = (PathCurve)16;
10097 break;
10098 // Set specific parameters for prism
10099 case ScriptBaseClass.PRIM_TYPE_PRISM:
10100 prim.PrimData.PathScaleY = 1.0f;
10101 prim.PrimData.ProfileCurve = (ProfileCurve)3;
10102 prim.PrimData.PathCurve = (PathCurve)16;
10103 break;
10104 // Set specific parameters for sphere
10105 case ScriptBaseClass.PRIM_TYPE_SPHERE:
10106 prim.PrimData.PathScaleY = 1.0f;
10107 prim.PrimData.ProfileCurve = (ProfileCurve)5;
10108 prim.PrimData.PathCurve = (PathCurve)32;
10109 break;
10110 // Set specific parameters for torus
10111 case ScriptBaseClass.PRIM_TYPE_TORUS:
10112 prim.PrimData.PathScaleY = 0.5f;
10113 prim.PrimData.ProfileCurve = (ProfileCurve)0;
10114 prim.PrimData.PathCurve = (PathCurve)32;
10115 break;
10116 // Set specific parameters for tube
10117 case ScriptBaseClass.PRIM_TYPE_TUBE:
10118 prim.PrimData.PathScaleY = 0.5f;
10119 prim.PrimData.ProfileCurve = (ProfileCurve)1;
10120 prim.PrimData.PathCurve = (PathCurve)32;
10121 break;
10122 // Set specific parameters for ring
10123 case ScriptBaseClass.PRIM_TYPE_RING:
10124 prim.PrimData.PathScaleY = 0.5f;
10125 prim.PrimData.ProfileCurve = (ProfileCurve)3;
10126 prim.PrimData.PathCurve = (PathCurve)32;
10127 break;
10128 // Set specific parameters for sculpt
10129 case ScriptBaseClass.PRIM_TYPE_SCULPT:
10130 prim.PrimData.PathScaleY = 1.0f;
10131 prim.PrimData.ProfileCurve = (ProfileCurve)5;
10132 prim.PrimData.PathCurve = (PathCurve)32;
10133 break;
10134 // Default to specific parameters for box
10135 default:
10136 prim.PrimData.PathScaleY = 1.0f;
10137 prim.PrimData.ProfileCurve = (ProfileCurve)1;
10138 prim.PrimData.PathCurve = (PathCurve)16;
10139 break;
10140 }
10141
10142 return prim;
10143 }
10144 10618
10145 /// <summary>
10146 /// Implementation of llGetGeometricCenter according to SL 2015-04-30.
10147 /// http://wiki.secondlife.com/wiki/LlGetGeometricCenter
10148 /// Returns the average position offset of all linked parts,
10149 /// including the root prim and seated avatars,
10150 /// relative to the root prim in local coordinates.
10151 /// </summary>
10152 public LSL_Vector llGetGeometricCenter() 10619 public LSL_Vector llGetGeometricCenter()
10153 { 10620 {
10154 // Subtract whatever position the root prim has to make it zero 10621 return new LSL_Vector(m_host.GetGeometricCenter());
10155 Vector3 offset = m_host.ParentGroup.RootPart.OffsetPosition * -1.0f;
10156
10157 // Add all prim/part position offsets
10158 foreach (SceneObjectPart part in m_host.ParentGroup.Parts)
10159 offset = offset + part.OffsetPosition;
10160 // Add all avatar/scene presence position offsets
10161 foreach (ScenePresence sp in m_host.ParentGroup.GetSittingAvatars())
10162 offset = offset + sp.OffsetPosition;
10163
10164 // Calculate and return the average offset
10165 offset = offset / (float)(m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount());
10166 return new LSL_Vector(offset);
10167 } 10622 }
10168 10623
10169 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 10624 public LSL_List llGetPrimitiveParams(LSL_List rules)
10170 { 10625 {
10171 LSL_List result = new LSL_List(); 10626 m_host.AddScriptLPS(1);
10172 LSL_List remaining;
10173
10174 while (true)
10175 {
10176// m_log.DebugFormat(
10177// "[LSL API]: GetEntityParams has {0} rules with scene entity named {1}",
10178// rules.Length, entity != null ? entity.Name : "NULL");
10179
10180 if (entity == null)
10181 return result;
10182 10627
10183 if (entity is SceneObjectPart) 10628 LSL_List result = new LSL_List();
10184 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result);
10185 else
10186 remaining = GetAgentParams((ScenePresence)entity, rules, ref result);
10187 10629
10188 if (remaining == null || remaining.Length < 2) 10630 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
10189 return result;
10190 10631
10632 while ((object)remaining != null && remaining.Length > 2)
10633 {
10191 int linknumber = remaining.GetLSLIntegerItem(0); 10634 int linknumber = remaining.GetLSLIntegerItem(0);
10192 rules = remaining.GetSublist(1, -1); 10635 rules = remaining.GetSublist(1, -1);
10193 entity = GetLinkEntity(m_host, linknumber); 10636 List<SceneObjectPart> parts = GetLinkParts(linknumber);
10194 }
10195 }
10196 10637
10197 public LSL_List llGetPrimitiveParams(LSL_List rules) 10638 foreach (SceneObjectPart part in parts)
10198 { 10639 remaining = GetPrimParams(part, rules, ref result);
10199 m_host.AddScriptLPS(1); 10640 }
10200 10641
10201 return GetEntityParams(m_host, rules); 10642 return result;
10202 } 10643 }
10203 10644
10204 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 10645 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
10205 { 10646 {
10206 m_host.AddScriptLPS(1); 10647 m_host.AddScriptLPS(1);
10207 10648
10208 return GetEntityParams(GetLinkEntity(m_host, linknumber), rules); 10649 // acording to SL wiki this must indicate a single link number or link_root or link_this.
10209 } 10650 // keep other options as before
10210 10651
10211 public LSL_Vector GetAgentSize(ScenePresence sp) 10652 List<SceneObjectPart> parts;
10212 { 10653 List<ScenePresence> avatars;
10213 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); 10654
10214 } 10655 LSL_List res = new LSL_List();
10656 LSL_List remaining = new LSL_List();
10215 10657
10216 /// <summary> 10658 while (rules.Length > 0)
10217 /// Gets params for a seated avatar in a linkset.
10218 /// </summary>
10219 /// <returns></returns>
10220 /// <param name='sp'></param>
10221 /// <param name='rules'></param>
10222 /// <param name='res'></param>
10223 public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res)
10224 {
10225 int idx = 0;
10226 while (idx < rules.Length)
10227 { 10659 {
10228 int code = (int)rules.GetLSLIntegerItem(idx++); 10660 parts = GetLinkParts(linknumber);
10229 int remain = rules.Length-idx; 10661 avatars = GetLinkAvatars(linknumber);
10230 10662
10231 switch (code) 10663 remaining = new LSL_List();
10664 foreach (SceneObjectPart part in parts)
10232 { 10665 {
10233 case (int)ScriptBaseClass.PRIM_MATERIAL: 10666 remaining = GetPrimParams(part, rules, ref res);
10234 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 10667 }
10235 break; 10668 foreach (ScenePresence avatar in avatars)
10236 10669 {
10237 case (int)ScriptBaseClass.PRIM_PHYSICS: 10670 remaining = GetPrimParams(avatar, rules, ref res);
10238 res.Add(ScriptBaseClass.FALSE); 10671 }
10239 break;
10240
10241 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
10242 res.Add(ScriptBaseClass.FALSE);
10243 break;
10244
10245 case (int)ScriptBaseClass.PRIM_PHANTOM:
10246 res.Add(ScriptBaseClass.FALSE);
10247 break;
10248
10249 case (int)ScriptBaseClass.PRIM_POSITION:
10250 res.Add(new LSL_Vector(sp.AbsolutePosition));
10251 break;
10252
10253 case (int)ScriptBaseClass.PRIM_SIZE:
10254 res.Add(GetAgentSize(sp));
10255 break;
10256
10257 case (int)ScriptBaseClass.PRIM_ROTATION:
10258 res.Add(sp.GetWorldRotation());
10259 break;
10260
10261 case (int)ScriptBaseClass.PRIM_TYPE:
10262 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
10263 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
10264 res.Add(new LSL_Vector(0, 1, 0));
10265 res.Add(new LSL_Float(0));
10266 res.Add(new LSL_Vector(0, 0, 0));
10267 res.Add(new LSL_Vector(1, 1, 0));
10268 res.Add(new LSL_Vector(0, 0, 0));
10269 break;
10270
10271 case (int)ScriptBaseClass.PRIM_TEXTURE:
10272 if (remain < 1)
10273 return new LSL_List();
10274
10275 int face = (int)rules.GetLSLIntegerItem(idx++);
10276 if (face > 21)
10277 break;
10278
10279 res.Add(new LSL_String(""));
10280 res.Add(ScriptBaseClass.ZERO_VECTOR);
10281 res.Add(ScriptBaseClass.ZERO_VECTOR);
10282 res.Add(new LSL_Float(0));
10283 break;
10284
10285 case (int)ScriptBaseClass.PRIM_COLOR:
10286 if (remain < 1)
10287 return new LSL_List();
10288
10289 face = (int)rules.GetLSLIntegerItem(idx++);
10290 if (face > 21)
10291 break;
10292
10293 res.Add(ScriptBaseClass.ZERO_VECTOR);
10294 res.Add(new LSL_Float(0));
10295 break;
10296
10297 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
10298 if (remain < 1)
10299 return new LSL_List();
10300
10301 face = (int)rules.GetLSLIntegerItem(idx++);
10302 if (face > 21)
10303 break;
10304
10305 res.Add(ScriptBaseClass.PRIM_SHINY_NONE);
10306 res.Add(ScriptBaseClass.PRIM_BUMP_NONE);
10307 break;
10308
10309 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
10310 if (remain < 1)
10311 return new LSL_List();
10312
10313 face = (int)rules.GetLSLIntegerItem(idx++);
10314 if (face > 21)
10315 break;
10316
10317 res.Add(ScriptBaseClass.FALSE);
10318 break;
10319
10320 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
10321 res.Add(ScriptBaseClass.FALSE);
10322 res.Add(new LSL_Integer(0));
10323 res.Add(new LSL_Float(0));
10324 res.Add(new LSL_Float(0));
10325 res.Add(new LSL_Float(0));
10326 res.Add(new LSL_Float(0));
10327 res.Add(ScriptBaseClass.ZERO_VECTOR);
10328 break;
10329
10330 case (int)ScriptBaseClass.PRIM_TEXGEN:
10331 if (remain < 1)
10332 return new LSL_List();
10333
10334 face = (int)rules.GetLSLIntegerItem(idx++);
10335 if (face > 21)
10336 break;
10337
10338 res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT);
10339 break;
10340
10341 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
10342 res.Add(ScriptBaseClass.FALSE);
10343 res.Add(ScriptBaseClass.ZERO_VECTOR);
10344 res.Add(ScriptBaseClass.ZERO_VECTOR);
10345 break;
10346
10347 case (int)ScriptBaseClass.PRIM_GLOW:
10348 if (remain < 1)
10349 return new LSL_List();
10350
10351 face = (int)rules.GetLSLIntegerItem(idx++);
10352 if (face > 21)
10353 break;
10354
10355 res.Add(new LSL_Float(0));
10356 break;
10357
10358 case (int)ScriptBaseClass.PRIM_TEXT:
10359 res.Add(new LSL_String(""));
10360 res.Add(ScriptBaseClass.ZERO_VECTOR);
10361 res.Add(new LSL_Float(1));
10362 break;
10363
10364 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
10365 res.Add(new LSL_Rotation(sp.Rotation));
10366 break;
10367
10368 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
10369 res.Add(new LSL_Vector(sp.OffsetPosition));
10370 break;
10371
10372 case (int)ScriptBaseClass.PRIM_SLICE:
10373 res.Add(new LSL_Vector(0, 1, 0));
10374 break;
10375
10376 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
10377 if(remain < 3)
10378 return new LSL_List();
10379 10672
10380 return rules.GetSublist(idx, -1); 10673 if (remaining.Length > 0)
10674 {
10675 linknumber = remaining.GetLSLIntegerItem(0);
10676 rules = remaining.GetSublist(1, -1);
10381 } 10677 }
10678 else
10679 break;
10382 } 10680 }
10383 10681
10384 return new LSL_List(); 10682 return res;
10385 } 10683 }
10386 10684
10387 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 10685 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
@@ -10420,19 +10718,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10420 break; 10718 break;
10421 10719
10422 case (int)ScriptBaseClass.PRIM_POSITION: 10720 case (int)ScriptBaseClass.PRIM_POSITION:
10423 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 10721 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
10424 10722 part.AbsolutePosition.Y,
10425 // For some reason, the part.AbsolutePosition.* values do not change if the 10723 part.AbsolutePosition.Z);
10426 // linkset is rotated; they always reflect the child prim's world position
10427 // as though the linkset is unrotated. This is incompatible behavior with SL's
10428 // implementation, so will break scripts imported from there (not to mention it
10429 // makes it more difficult to determine a child prim's actual inworld position).
10430 if (!part.IsRoot)
10431 {
10432 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
10433 v = ((v - rootPos) * llGetRootRotation()) + rootPos;
10434 }
10435
10436 res.Add(v); 10724 res.Add(v);
10437 break; 10725 break;
10438 10726
@@ -10541,7 +10829,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10541 Primitive.TextureEntry tex = part.Shape.Textures; 10829 Primitive.TextureEntry tex = part.Shape.Textures;
10542 if (face == ScriptBaseClass.ALL_SIDES) 10830 if (face == ScriptBaseClass.ALL_SIDES)
10543 { 10831 {
10544 for (face = 0 ; face < GetNumberOfSides(part); face++) 10832 for (face = 0; face < GetNumberOfSides(part); face++)
10545 { 10833 {
10546 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10834 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
10547 10835
@@ -10577,13 +10865,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10577 if (remain < 1) 10865 if (remain < 1)
10578 return new LSL_List(); 10866 return new LSL_List();
10579 10867
10580 face=(int)rules.GetLSLIntegerItem(idx++); 10868 face = (int)rules.GetLSLIntegerItem(idx++);
10581 10869
10582 tex = part.Shape.Textures; 10870 tex = part.Shape.Textures;
10583 Color4 texcolor; 10871 Color4 texcolor;
10584 if (face == ScriptBaseClass.ALL_SIDES) 10872 if (face == ScriptBaseClass.ALL_SIDES)
10585 { 10873 {
10586 for (face = 0 ; face < GetNumberOfSides(part); face++) 10874 for (face = 0; face < GetNumberOfSides(part); face++)
10587 { 10875 {
10588 texcolor = tex.GetFace((uint)face).RGBA; 10876 texcolor = tex.GetFace((uint)face).RGBA;
10589 res.Add(new LSL_Vector(texcolor.R, 10877 res.Add(new LSL_Vector(texcolor.R,
@@ -10606,30 +10894,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10606 if (remain < 1) 10894 if (remain < 1)
10607 return new LSL_List(); 10895 return new LSL_List();
10608 10896
10609 face=(int)rules.GetLSLIntegerItem(idx++); 10897 face = (int)rules.GetLSLIntegerItem(idx++);
10610 10898
10611 tex = part.Shape.Textures; 10899 tex = part.Shape.Textures;
10900 int shiny;
10612 if (face == ScriptBaseClass.ALL_SIDES) 10901 if (face == ScriptBaseClass.ALL_SIDES)
10613 { 10902 {
10614 for (face = 0; face < GetNumberOfSides(part); face++) 10903 for (face = 0; face < GetNumberOfSides(part); face++)
10615 { 10904 {
10616 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10905 Shininess shinyness = tex.GetFace((uint)face).Shiny;
10617 // Convert Shininess to PRIM_SHINY_* 10906 if (shinyness == Shininess.High)
10618 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 10907 {
10619 // PRIM_BUMP_* 10908 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
10620 res.Add(new LSL_Integer((int)texface.Bump)); 10909 }
10910 else if (shinyness == Shininess.Medium)
10911 {
10912 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
10913 }
10914 else if (shinyness == Shininess.Low)
10915 {
10916 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
10917 }
10918 else
10919 {
10920 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
10921 }
10922 res.Add(new LSL_Integer(shiny));
10923 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
10621 } 10924 }
10622 } 10925 }
10623 else 10926 else
10624 { 10927 {
10625 if (face >= 0 && face < GetNumberOfSides(part)) 10928 Shininess shinyness = tex.GetFace((uint)face).Shiny;
10929 if (shinyness == Shininess.High)
10626 { 10930 {
10627 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10931 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
10628 // Convert Shininess to PRIM_SHINY_* 10932 }
10629 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 10933 else if (shinyness == Shininess.Medium)
10630 // PRIM_BUMP_* 10934 {
10631 res.Add(new LSL_Integer((int)texface.Bump)); 10935 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
10632 } 10936 }
10937 else if (shinyness == Shininess.Low)
10938 {
10939 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
10940 }
10941 else
10942 {
10943 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
10944 }
10945 res.Add(new LSL_Integer(shiny));
10946 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
10633 } 10947 }
10634 break; 10948 break;
10635 10949
@@ -10640,21 +10954,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10640 face = (int)rules.GetLSLIntegerItem(idx++); 10954 face = (int)rules.GetLSLIntegerItem(idx++);
10641 10955
10642 tex = part.Shape.Textures; 10956 tex = part.Shape.Textures;
10957 int fullbright;
10643 if (face == ScriptBaseClass.ALL_SIDES) 10958 if (face == ScriptBaseClass.ALL_SIDES)
10644 { 10959 {
10645 for (face = 0; face < GetNumberOfSides(part); face++) 10960 for (face = 0; face < GetNumberOfSides(part); face++)
10646 { 10961 {
10647 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10962 if (tex.GetFace((uint)face).Fullbright == true)
10648 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 10963 {
10964 fullbright = ScriptBaseClass.TRUE;
10965 }
10966 else
10967 {
10968 fullbright = ScriptBaseClass.FALSE;
10969 }
10970 res.Add(new LSL_Integer(fullbright));
10649 } 10971 }
10650 } 10972 }
10651 else 10973 else
10652 { 10974 {
10653 if (face >= 0 && face < GetNumberOfSides(part)) 10975 if (tex.GetFace((uint)face).Fullbright == true)
10654 { 10976 {
10655 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10977 fullbright = ScriptBaseClass.TRUE;
10656 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
10657 } 10978 }
10979 else
10980 {
10981 fullbright = ScriptBaseClass.FALSE;
10982 }
10983 res.Add(new LSL_Integer(fullbright));
10658 } 10984 }
10659 break; 10985 break;
10660 10986
@@ -10676,27 +11002,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10676 break; 11002 break;
10677 11003
10678 case (int)ScriptBaseClass.PRIM_TEXGEN: 11004 case (int)ScriptBaseClass.PRIM_TEXGEN:
11005 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
10679 if (remain < 1) 11006 if (remain < 1)
10680 return new LSL_List(); 11007 return new LSL_List();
10681 11008
10682 face=(int)rules.GetLSLIntegerItem(idx++); 11009 face = (int)rules.GetLSLIntegerItem(idx++);
10683 11010
10684 tex = part.Shape.Textures; 11011 tex = part.Shape.Textures;
10685 if (face == ScriptBaseClass.ALL_SIDES) 11012 if (face == ScriptBaseClass.ALL_SIDES)
10686 { 11013 {
10687 for (face = 0; face < GetNumberOfSides(part); face++) 11014 for (face = 0; face < GetNumberOfSides(part); face++)
10688 { 11015 {
10689 MappingType texgen = tex.GetFace((uint)face).TexMapType; 11016 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
10690 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 11017 {
10691 res.Add(new LSL_Integer((uint)texgen >> 1)); 11018 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
11019 }
11020 else
11021 {
11022 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
11023 }
10692 } 11024 }
10693 } 11025 }
10694 else 11026 else
10695 { 11027 {
10696 if (face >= 0 && face < GetNumberOfSides(part)) 11028 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
10697 { 11029 {
10698 MappingType texgen = tex.GetFace((uint)face).TexMapType; 11030 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
10699 res.Add(new LSL_Integer((uint)texgen >> 1)); 11031 }
11032 else
11033 {
11034 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
10700 } 11035 }
10701 } 11036 }
10702 break; 11037 break;
@@ -10720,24 +11055,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10720 if (remain < 1) 11055 if (remain < 1)
10721 return new LSL_List(); 11056 return new LSL_List();
10722 11057
10723 face=(int)rules.GetLSLIntegerItem(idx++); 11058 face = (int)rules.GetLSLIntegerItem(idx++);
10724 11059
10725 tex = part.Shape.Textures; 11060 tex = part.Shape.Textures;
11061 float primglow;
10726 if (face == ScriptBaseClass.ALL_SIDES) 11062 if (face == ScriptBaseClass.ALL_SIDES)
10727 { 11063 {
10728 for (face = 0; face < GetNumberOfSides(part); face++) 11064 for (face = 0; face < GetNumberOfSides(part); face++)
10729 { 11065 {
10730 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 11066 primglow = tex.GetFace((uint)face).Glow;
10731 res.Add(new LSL_Float(texface.Glow)); 11067 res.Add(new LSL_Float(primglow));
10732 } 11068 }
10733 } 11069 }
10734 else 11070 else
10735 { 11071 {
10736 if (face >= 0 && face < GetNumberOfSides(part)) 11072 primglow = tex.GetFace((uint)face).Glow;
10737 { 11073 res.Add(new LSL_Float(primglow));
10738 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
10739 res.Add(new LSL_Float(texface.Glow));
10740 }
10741 } 11074 }
10742 break; 11075 break;
10743 11076
@@ -10747,17 +11080,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10747 res.Add(new LSL_Vector(textColor.R, 11080 res.Add(new LSL_Vector(textColor.R,
10748 textColor.G, 11081 textColor.G,
10749 textColor.B)); 11082 textColor.B));
10750 res.Add(new LSL_Float(1.0 - textColor.A)); 11083 res.Add(new LSL_Float(textColor.A));
10751 break; 11084 break;
11085
10752 case (int)ScriptBaseClass.PRIM_NAME: 11086 case (int)ScriptBaseClass.PRIM_NAME:
10753 res.Add(new LSL_String(part.Name)); 11087 res.Add(new LSL_String(part.Name));
10754 break; 11088 break;
11089
10755 case (int)ScriptBaseClass.PRIM_DESC: 11090 case (int)ScriptBaseClass.PRIM_DESC:
10756 res.Add(new LSL_String(part.Description)); 11091 res.Add(new LSL_String(part.Description));
10757 break; 11092 break;
10758 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 11093 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
10759 res.Add(new LSL_Rotation(part.RotationOffset)); 11094 res.Add(new LSL_Rotation(part.RotationOffset));
10760 break; 11095 break;
11096
10761 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 11097 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
10762 res.Add(new LSL_Vector(GetPartLocalPos(part))); 11098 res.Add(new LSL_Vector(GetPartLocalPos(part)));
10763 break; 11099 break;
@@ -10783,6 +11119,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10783 return new LSL_List(); 11119 return new LSL_List();
10784 } 11120 }
10785 11121
11122
10786 public LSL_List llGetPrimMediaParams(int face, LSL_List rules) 11123 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
10787 { 11124 {
10788 m_host.AddScriptLPS(1); 11125 m_host.AddScriptLPS(1);
@@ -11370,8 +11707,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11370 // The function returns an ordered list 11707 // The function returns an ordered list
11371 // representing the tokens found in the supplied 11708 // representing the tokens found in the supplied
11372 // sources string. If two successive tokenizers 11709 // sources string. If two successive tokenizers
11373 // are encountered, then a NULL entry is added 11710 // are encountered, then a null-string entry is
11374 // to the list. 11711 // added to the list.
11375 // 11712 //
11376 // It is a precondition that the source and 11713 // It is a precondition that the source and
11377 // toekizer lisst are non-null. If they are null, 11714 // toekizer lisst are non-null. If they are null,
@@ -11379,7 +11716,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11379 // while their lengths are being determined. 11716 // while their lengths are being determined.
11380 // 11717 //
11381 // A small amount of working memoryis required 11718 // A small amount of working memoryis required
11382 // of approximately 8*#tokenizers. 11719 // of approximately 8*#tokenizers + 8*srcstrlen.
11383 // 11720 //
11384 // There are many ways in which this function 11721 // There are many ways in which this function
11385 // can be implemented, this implementation is 11722 // can be implemented, this implementation is
@@ -11395,155 +11732,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11395 // and eliminates redundant tokenizers as soon 11732 // and eliminates redundant tokenizers as soon
11396 // as is possible. 11733 // as is possible.
11397 // 11734 //
11398 // The implementation tries to avoid any copying 11735 // The implementation tries to minimize temporary
11399 // of arrays or other objects. 11736 // garbage generation.
11400 // </remarks> 11737 // </remarks>
11401 11738
11402 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 11739 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
11403 { 11740 {
11404 int beginning = 0; 11741 return ParseString2List(src, separators, spacers, true);
11405 int srclen = src.Length; 11742 }
11406 int seplen = separators.Length;
11407 object[] separray = separators.Data;
11408 int spclen = spacers.Length;
11409 object[] spcarray = spacers.Data;
11410 int mlen = seplen+spclen;
11411
11412 int[] offset = new int[mlen+1];
11413 bool[] active = new bool[mlen];
11414
11415 int best;
11416 int j;
11417
11418 // Initial capacity reduces resize cost
11419 11743
11420 LSL_List tokens = new LSL_List(); 11744 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
11745 {
11746 int srclen = src.Length;
11747 int seplen = separators.Length;
11748 object[] separray = separators.Data;
11749 int spclen = spacers.Length;
11750 object[] spcarray = spacers.Data;
11751 int dellen = 0;
11752 string[] delarray = new string[seplen+spclen];
11421 11753
11422 // All entries are initially valid 11754 int outlen = 0;
11755 string[] outarray = new string[srclen*2+1];
11423 11756
11424 for (int i = 0; i < mlen; i++) 11757 int i, j;
11425 active[i] = true; 11758 string d;
11426 11759
11427 offset[mlen] = srclen; 11760 m_host.AddScriptLPS(1);
11428 11761
11429 while (beginning < srclen) 11762 /*
11763 * Convert separator and spacer lists to C# strings.
11764 * Also filter out null strings so we don't hang.
11765 */
11766 for (i = 0; i < seplen; i ++)
11430 { 11767 {
11768 d = separray[i].ToString();
11769 if (d.Length > 0)
11770 {
11771 delarray[dellen++] = d;
11772 }
11773 }
11774 seplen = dellen;
11431 11775
11432 best = mlen; // as bad as it gets 11776 for (i = 0; i < spclen; i ++)
11777 {
11778 d = spcarray[i].ToString();
11779 if (d.Length > 0)
11780 {
11781 delarray[dellen++] = d;
11782 }
11783 }
11433 11784
11434 // Scan for separators 11785 /*
11786 * Scan through source string from beginning to end.
11787 */
11788 for (i = 0;;)
11789 {
11435 11790
11436 for (j = 0; j < seplen; j++) 11791 /*
11792 * Find earliest delimeter in src starting at i (if any).
11793 */
11794 int earliestDel = -1;
11795 int earliestSrc = srclen;
11796 string earliestStr = null;
11797 for (j = 0; j < dellen; j ++)
11437 { 11798 {
11438 if (separray[j].ToString() == String.Empty) 11799 d = delarray[j];
11439 active[j] = false; 11800 if (d != null)
11440
11441 if (active[j])
11442 { 11801 {
11443 // scan all of the markers 11802 int index = src.IndexOf(d, i);
11444 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 11803 if (index < 0)
11445 { 11804 {
11446 // not present at all 11805 delarray[j] = null; // delim nowhere in src, don't check it anymore
11447 active[j] = false;
11448 } 11806 }
11449 else 11807 else if (index < earliestSrc)
11450 { 11808 {
11451 // present and correct 11809 earliestSrc = index; // where delimeter starts in source string
11452 if (offset[j] < offset[best]) 11810 earliestDel = j; // where delimeter is in delarray[]
11453 { 11811 earliestStr = d; // the delimeter string from delarray[]
11454 // closest so far 11812 if (index == i) break; // can't do any better than found at beg of string
11455 best = j;
11456 if (offset[best] == beginning)
11457 break;
11458 }
11459 } 11813 }
11460 } 11814 }
11461 } 11815 }
11462 11816
11463 // Scan for spacers 11817 /*
11464 11818 * Output source string starting at i through start of earliest delimeter.
11465 if (offset[best] != beginning) 11819 */
11820 if (keepNulls || (earliestSrc > i))
11466 { 11821 {
11467 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 11822 outarray[outlen++] = src.Substring(i, earliestSrc - i);
11468 {
11469 if (spcarray[j-seplen].ToString() == String.Empty)
11470 active[j] = false;
11471
11472 if (active[j])
11473 {
11474 // scan all of the markers
11475 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
11476 {
11477 // not present at all
11478 active[j] = false;
11479 }
11480 else
11481 {
11482 // present and correct
11483 if (offset[j] < offset[best])
11484 {
11485 // closest so far
11486 best = j;
11487 }
11488 }
11489 }
11490 }
11491 } 11823 }
11492 11824
11493 // This is the normal exit from the scanning loop 11825 /*
11826 * If no delimeter found at or after i, we're done scanning.
11827 */
11828 if (earliestDel < 0) break;
11494 11829
11495 if (best == mlen) 11830 /*
11831 * If delimeter was a spacer, output the spacer.
11832 */
11833 if (earliestDel >= seplen)
11496 { 11834 {
11497 // no markers were found on this pass 11835 outarray[outlen++] = earliestStr;
11498 // so we're pretty much done
11499 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
11500 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
11501 break;
11502 } 11836 }
11503 11837
11504 // Otherwise we just add the newly delimited token 11838 /*
11505 // and recalculate where the search should continue. 11839 * Look at rest of src string following delimeter.
11506 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 11840 */
11507 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 11841 i = earliestSrc + earliestStr.Length;
11508
11509 if (best < seplen)
11510 {
11511 beginning = offset[best] + (separray[best].ToString()).Length;
11512 }
11513 else
11514 {
11515 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
11516 string str = spcarray[best - seplen].ToString();
11517 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
11518 tokens.Add(new LSL_String(str));
11519 }
11520 } 11842 }
11521 11843
11522 // This an awkward an not very intuitive boundary case. If the 11844 /*
11523 // last substring is a tokenizer, then there is an implied trailing 11845 * Make up an exact-sized output array suitable for an LSL_List object.
11524 // null list entry. Hopefully the single comparison will not be too 11846 */
11525 // arduous. Alternatively the 'break' could be replced with a return 11847 object[] outlist = new object[outlen];
11526 // but that's shabby programming. 11848 for (i = 0; i < outlen; i ++)
11527
11528 if ((beginning == srclen) && (keepNulls))
11529 { 11849 {
11530 if (srclen != 0) 11850 outlist[i] = new LSL_String(outarray[i]);
11531 tokens.Add(new LSL_String(""));
11532 } 11851 }
11533 11852 return new LSL_List(outlist);
11534 return tokens;
11535 }
11536
11537 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
11538 {
11539 m_host.AddScriptLPS(1);
11540 return this.ParseString(src, separators, spacers, false);
11541 }
11542
11543 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
11544 {
11545 m_host.AddScriptLPS(1);
11546 return this.ParseString(src, separators, spacers, true);
11547 } 11853 }
11548 11854
11549 public LSL_Integer llGetObjectPermMask(int mask) 11855 public LSL_Integer llGetObjectPermMask(int mask)
@@ -11841,31 +12147,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11841 UUID key = new UUID(); 12147 UUID key = new UUID();
11842 if (UUID.TryParse(id, out key)) 12148 if (UUID.TryParse(id, out key))
11843 { 12149 {
11844 try 12150 // return total object mass
11845 { 12151 SceneObjectPart part = World.GetSceneObjectPart(key);
11846 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 12152 if (part != null)
11847 if (obj != null) 12153 return part.ParentGroup.GetMass();
11848 return (double)obj.GetMass(); 12154
11849 // the object is null so the key is for an avatar 12155 // the object is null so the key is for an avatar
11850 ScenePresence avatar = World.GetScenePresence(key); 12156 ScenePresence avatar = World.GetScenePresence(key);
11851 if (avatar != null) 12157 if (avatar != null)
11852 if (avatar.IsChildAgent)
11853 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
11854 // child agents have a mass of 1.0
11855 return 1;
11856 else
11857 return (double)avatar.GetMass();
11858 }
11859 catch (KeyNotFoundException)
11860 { 12158 {
11861 return 0; // The Object/Agent not in the region so just return zero 12159 if (avatar.IsChildAgent)
12160 {
12161 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
12162 // child agents have a mass of 1.0
12163 return 1;
12164 }
12165 else
12166 {
12167 return (double)avatar.GetMass();
12168 }
11862 } 12169 }
11863 } 12170 }
11864 return 0; 12171 return 0;
11865 } 12172 }
11866 12173
11867 /// <summary> 12174 /// <summary>
11868 /// illListReplaceList removes the sub-list defined by the inclusive indices 12175 /// llListReplaceList removes the sub-list defined by the inclusive indices
11869 /// start and end and inserts the src list in its place. The inclusive 12176 /// start and end and inserts the src list in its place. The inclusive
11870 /// nature of the indices means that at least one element must be deleted 12177 /// nature of the indices means that at least one element must be deleted
11871 /// if the indices are within the bounds of the existing list. I.e. 2,2 12178 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -11922,16 +12229,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11922 // based upon end. Note that if end exceeds the upper 12229 // based upon end. Note that if end exceeds the upper
11923 // bound in this case, the entire destination list 12230 // bound in this case, the entire destination list
11924 // is removed. 12231 // is removed.
11925 else 12232 else if (start == 0)
11926 { 12233 {
11927 if (end + 1 < dest.Length) 12234 if (end + 1 < dest.Length)
11928 {
11929 return src + dest.GetSublist(end + 1, -1); 12235 return src + dest.GetSublist(end + 1, -1);
11930 }
11931 else 12236 else
11932 {
11933 return src; 12237 return src;
11934 } 12238 }
12239 else // Start < 0
12240 {
12241 if (end + 1 < dest.Length)
12242 return dest.GetSublist(end + 1, -1);
12243 else
12244 return new LSL_List();
11935 } 12245 }
11936 } 12246 }
11937 // Finally, if start > end, we strip away a prefix and 12247 // Finally, if start > end, we strip away a prefix and
@@ -11968,7 +12278,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11968 // according to the docs, this command only works if script owner and land owner are the same 12278 // according to the docs, this command only works if script owner and land owner are the same
11969 // lets add estate owners and gods, too, and use the generic permission check. 12279 // lets add estate owners and gods, too, and use the generic permission check.
11970 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 12280 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
11971 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; 12281 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia, false)) return;
11972 12282
11973 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? 12283 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)?
11974 byte loop = 0; 12284 byte loop = 0;
@@ -12186,16 +12496,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12186 if (sp.currentParcelUUID == landData.GlobalID) 12496 if (sp.currentParcelUUID == landData.GlobalID)
12187 { 12497 {
12188 sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? 12498 sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
12189 (ParcelMediaCommandEnum)commandToSend, 12499 (ParcelMediaCommandEnum)commandToSend, time);
12190 time);
12191 } 12500 }
12192 }); 12501 });
12193 } 12502 }
12194 else if (!presence.IsChildAgent) 12503 else if (!presence.IsChildAgent)
12195 { 12504 {
12196 presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? 12505 presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
12197 (ParcelMediaCommandEnum)commandToSend, 12506 (ParcelMediaCommandEnum)commandToSend, time);
12198 time);
12199 } 12507 }
12200 } 12508 }
12201 ScriptSleep(m_sleepMsOnParcelMediaCommandList); 12509 ScriptSleep(m_sleepMsOnParcelMediaCommandList);
@@ -12212,7 +12520,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12212 12520
12213 if (aList.Data[i] != null) 12521 if (aList.Data[i] != null)
12214 { 12522 {
12215 switch ((ParcelMediaCommandEnum) aList.Data[i]) 12523 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
12216 { 12524 {
12217 case ParcelMediaCommandEnum.Url: 12525 case ParcelMediaCommandEnum.Url:
12218 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 12526 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -12269,15 +12577,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12269 12577
12270 if (quick_pay_buttons.Data.Length < 4) 12578 if (quick_pay_buttons.Data.Length < 4)
12271 { 12579 {
12272 Error("llSetPayPrice", "List must have at least 4 elements"); 12580 int x;
12273 return; 12581 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
12582 {
12583 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
12584 }
12274 } 12585 }
12275 m_host.ParentGroup.RootPart.PayPrice[0]=price; 12586 int[] nPrice = new int[5];
12276 12587 nPrice[0] = price;
12277 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 12588 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
12278 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 12589 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
12279 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 12590 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
12280 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 12591 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
12592 m_host.ParentGroup.RootPart.PayPrice = nPrice;
12281 m_host.ParentGroup.HasGroupChanged = true; 12593 m_host.ParentGroup.HasGroupChanged = true;
12282 } 12594 }
12283 12595
@@ -12294,7 +12606,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12294 return Vector3.Zero; 12606 return Vector3.Zero;
12295 } 12607 }
12296 12608
12297 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 12609// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
12610 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
12298 if (presence != null) 12611 if (presence != null)
12299 { 12612 {
12300 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 12613 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
@@ -12317,7 +12630,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12317 return Quaternion.Identity; 12630 return Quaternion.Identity;
12318 } 12631 }
12319 12632
12320 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 12633// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
12634 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
12321 if (presence != null) 12635 if (presence != null)
12322 { 12636 {
12323 return new LSL_Rotation(presence.CameraRotation); 12637 return new LSL_Rotation(presence.CameraRotation);
@@ -12370,8 +12684,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12370 { 12684 {
12371 m_host.AddScriptLPS(1); 12685 m_host.AddScriptLPS(1);
12372 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 12686 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
12373 if (detectedParams == null) return; // only works on the first detected avatar 12687 if (detectedParams == null)
12374 12688 {
12689 if (m_host.ParentGroup.IsAttachment == true)
12690 {
12691 detectedParams = new DetectParams();
12692 detectedParams.Key = m_host.OwnerID;
12693 }
12694 else
12695 {
12696 return;
12697 }
12698 }
12699
12375 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 12700 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
12376 if (avatar != null) 12701 if (avatar != null)
12377 { 12702 {
@@ -12386,7 +12711,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12386 m_host.AddScriptLPS(1); 12711 m_host.AddScriptLPS(1);
12387 UUID key; 12712 UUID key;
12388 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 12713 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
12389 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 12714 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false))
12390 { 12715 {
12391 int expires = 0; 12716 int expires = 0;
12392 if (hours != 0) 12717 if (hours != 0)
@@ -12427,7 +12752,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12427 m_host.AddScriptLPS(1); 12752 m_host.AddScriptLPS(1);
12428 UUID key; 12753 UUID key;
12429 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 12754 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
12430 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) 12755 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed, false))
12431 { 12756 {
12432 if (UUID.TryParse(avatar, out key)) 12757 if (UUID.TryParse(avatar, out key))
12433 { 12758 {
@@ -12454,7 +12779,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12454 m_host.AddScriptLPS(1); 12779 m_host.AddScriptLPS(1);
12455 UUID key; 12780 UUID key;
12456 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 12781 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
12457 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 12782 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false))
12458 { 12783 {
12459 if (UUID.TryParse(avatar, out key)) 12784 if (UUID.TryParse(avatar, out key))
12460 { 12785 {
@@ -12686,19 +13011,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12686 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 13011 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
12687 { 13012 {
12688 m_host.AddScriptLPS(1); 13013 m_host.AddScriptLPS(1);
12689 string ret = String.Empty; 13014
12690 string src1 = llBase64ToString(str1); 13015 if (str1 == String.Empty)
12691 string src2 = llBase64ToString(str2); 13016 return String.Empty;
12692 int c = 0; 13017 if (str2 == String.Empty)
12693 for (int i = 0; i < src1.Length; i++) 13018 return str1;
13019
13020 int len = str2.Length;
13021 if ((len % 4) != 0) // LL is EVIL!!!!
13022 {
13023 while (str2.EndsWith("="))
13024 str2 = str2.Substring(0, str2.Length - 1);
13025
13026 len = str2.Length;
13027 int mod = len % 4;
13028
13029 if (mod == 1)
13030 str2 = str2.Substring(0, str2.Length - 1);
13031 else if (mod == 2)
13032 str2 += "==";
13033 else if (mod == 3)
13034 str2 += "=";
13035 }
13036
13037 byte[] data1;
13038 byte[] data2;
13039 try
13040 {
13041 data1 = Convert.FromBase64String(str1);
13042 data2 = Convert.FromBase64String(str2);
13043 }
13044 catch (Exception)
12694 { 13045 {
12695 ret += (char) (src1[i] ^ src2[c]); 13046 return new LSL_String(String.Empty);
13047 }
12696 13048
12697 c++; 13049 byte[] d2 = new Byte[data1.Length];
12698 if (c >= src2.Length) 13050 int pos = 0;
12699 c = 0; 13051
13052 if (data1.Length <= data2.Length)
13053 {
13054 Array.Copy(data2, 0, d2, 0, data1.Length);
12700 } 13055 }
12701 return llStringToBase64(ret); 13056 else
13057 {
13058 while (pos < data1.Length)
13059 {
13060 len = data1.Length - pos;
13061 if (len > data2.Length)
13062 len = data2.Length;
13063
13064 Array.Copy(data2, 0, d2, pos, len);
13065 pos += len;
13066 }
13067 }
13068
13069 for (pos = 0 ; pos < data1.Length ; pos++ )
13070 data1[pos] ^= d2[pos];
13071
13072 return Convert.ToBase64String(data1);
12702 } 13073 }
12703 13074
12704 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 13075 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -12802,16 +13173,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12802 if (userAgent != null) 13173 if (userAgent != null)
12803 httpHeaders["User-Agent"] = userAgent; 13174 httpHeaders["User-Agent"] = userAgent;
12804 13175
13176 // See if the URL contains any header hacks
13177 string[] urlParts = url.Split(new char[] {'\n'});
13178 if (urlParts.Length > 1)
13179 {
13180 // Iterate the passed headers and parse them
13181 for (int i = 1 ; i < urlParts.Length ; i++ )
13182 {
13183 // The rest of those would be added to the body in SL.
13184 // Let's not do that.
13185 if (urlParts[i] == String.Empty)
13186 break;
13187
13188 // See if this could be a valid header
13189 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
13190 if (headerParts.Length != 2)
13191 continue;
13192
13193 string headerName = headerParts[0].Trim();
13194 string headerValue = headerParts[1].Trim();
13195
13196 // Filter out headers that could be used to abuse
13197 // another system or cloak the request
13198 if (headerName.ToLower() == "x-secondlife-shard" ||
13199 headerName.ToLower() == "x-secondlife-object-name" ||
13200 headerName.ToLower() == "x-secondlife-object-key" ||
13201 headerName.ToLower() == "x-secondlife-region" ||
13202 headerName.ToLower() == "x-secondlife-local-position" ||
13203 headerName.ToLower() == "x-secondlife-local-velocity" ||
13204 headerName.ToLower() == "x-secondlife-local-rotation" ||
13205 headerName.ToLower() == "x-secondlife-owner-name" ||
13206 headerName.ToLower() == "x-secondlife-owner-key" ||
13207 headerName.ToLower() == "connection" ||
13208 headerName.ToLower() == "content-length" ||
13209 headerName.ToLower() == "from" ||
13210 headerName.ToLower() == "host" ||
13211 headerName.ToLower() == "proxy-authorization" ||
13212 headerName.ToLower() == "referer" ||
13213 headerName.ToLower() == "trailer" ||
13214 headerName.ToLower() == "transfer-encoding" ||
13215 headerName.ToLower() == "via" ||
13216 headerName.ToLower() == "authorization")
13217 continue;
13218
13219 httpHeaders[headerName] = headerValue;
13220 }
13221
13222 // Finally, strip any protocol specifier from the URL
13223 url = urlParts[0].Trim();
13224 int idx = url.IndexOf(" HTTP/");
13225 if (idx != -1)
13226 url = url.Substring(0, idx);
13227 }
13228
12805 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 13229 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
12806 Regex r = new Regex(authregex); 13230 Regex r = new Regex(authregex);
12807 int[] gnums = r.GetGroupNumbers(); 13231 int[] gnums = r.GetGroupNumbers();
12808 Match m = r.Match(url); 13232 Match m = r.Match(url);
12809 if (m.Success) { 13233 if (m.Success)
12810 for (int i = 1; i < gnums.Length; i++) { 13234 {
13235 for (int i = 1; i < gnums.Length; i++)
13236 {
12811 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 13237 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
12812 //CaptureCollection cc = g.Captures; 13238 //CaptureCollection cc = g.Captures;
12813 } 13239 }
12814 if (m.Groups.Count == 5) { 13240 if (m.Groups.Count == 5)
13241 {
12815 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 13242 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
12816 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 13243 url = m.Groups[1].ToString() + m.Groups[4].ToString();
12817 } 13244 }
@@ -13018,6 +13445,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13018 13445
13019 LSL_List ret = new LSL_List(); 13446 LSL_List ret = new LSL_List();
13020 UUID key = new UUID(); 13447 UUID key = new UUID();
13448
13449
13021 if (UUID.TryParse(id, out key)) 13450 if (UUID.TryParse(id, out key))
13022 { 13451 {
13023 ScenePresence av = World.GetScenePresence(key); 13452 ScenePresence av = World.GetScenePresence(key);
@@ -13035,13 +13464,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13035 ret.Add(new LSL_String("")); 13464 ret.Add(new LSL_String(""));
13036 break; 13465 break;
13037 case ScriptBaseClass.OBJECT_POS: 13466 case ScriptBaseClass.OBJECT_POS:
13038 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 13467 Vector3 avpos;
13468
13469 if (av.ParentID != 0 && av.ParentPart != null)
13470 {
13471 avpos = av.OffsetPosition;
13472
13473 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
13474 avpos -= sitOffset;
13475
13476 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
13477 }
13478 else
13479 avpos = av.AbsolutePosition;
13480
13481 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
13039 break; 13482 break;
13040 case ScriptBaseClass.OBJECT_ROT: 13483 case ScriptBaseClass.OBJECT_ROT:
13041 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 13484 Quaternion avrot = av.Rotation;
13485 if (av.ParentID != 0 && av.ParentPart != null)
13486 {
13487 avrot = av.ParentPart.GetWorldRotation() * avrot;
13488 }
13489 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
13042 break; 13490 break;
13043 case ScriptBaseClass.OBJECT_VELOCITY: 13491 case ScriptBaseClass.OBJECT_VELOCITY:
13044 ret.Add(new LSL_Vector(av.GetWorldVelocity())); 13492 Vector3 avvel = av.GetWorldVelocity();
13493 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
13045 break; 13494 break;
13046 case ScriptBaseClass.OBJECT_OWNER: 13495 case ScriptBaseClass.OBJECT_OWNER:
13047 ret.Add(new LSL_String(id)); 13496 ret.Add(new LSL_String(id));
@@ -13143,11 +13592,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13143 case ScriptBaseClass.OBJECT_NAME: 13592 case ScriptBaseClass.OBJECT_NAME:
13144 ret.Add(new LSL_String(obj.Name)); 13593 ret.Add(new LSL_String(obj.Name));
13145 break; 13594 break;
13146 case ScriptBaseClass.OBJECT_DESC: 13595 case ScriptBaseClass.OBJECT_DESC:
13147 ret.Add(new LSL_String(obj.Description)); 13596 ret.Add(new LSL_String(obj.Description));
13148 break; 13597 break;
13149 case ScriptBaseClass.OBJECT_POS: 13598 case ScriptBaseClass.OBJECT_POS:
13150 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 13599 Vector3 opos = obj.AbsolutePosition;
13600 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
13151 break; 13601 break;
13152 case ScriptBaseClass.OBJECT_ROT: 13602 case ScriptBaseClass.OBJECT_ROT:
13153 Quaternion rot = Quaternion.Identity; 13603 Quaternion rot = Quaternion.Identity;
@@ -13220,9 +13670,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13220 // The value returned in SL for normal prims is prim count 13670 // The value returned in SL for normal prims is prim count
13221 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 13671 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
13222 break; 13672 break;
13223 // The following 3 costs I have intentionaly coded to return zero. They are part of 13673
13224 // "Land Impact" calculations. These calculations are probably not applicable 13674 // costs below may need to be diferent for root parts, need to check
13225 // to OpenSim and are not yet complete in SL
13226 case ScriptBaseClass.OBJECT_SERVER_COST: 13675 case ScriptBaseClass.OBJECT_SERVER_COST:
13227 // The linden calculation is here 13676 // The linden calculation is here
13228 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 13677 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -13230,16 +13679,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13230 ret.Add(new LSL_Float(0)); 13679 ret.Add(new LSL_Float(0));
13231 break; 13680 break;
13232 case ScriptBaseClass.OBJECT_STREAMING_COST: 13681 case ScriptBaseClass.OBJECT_STREAMING_COST:
13233 // The linden calculation is here 13682 // The value returned in SL for normal prims is prim count * 0.06
13234 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 13683 ret.Add(new LSL_Float(obj.StreamingCost));
13235 // The value returned in SL for normal prims looks like the prim count * 0.06
13236 ret.Add(new LSL_Float(0));
13237 break; 13684 break;
13238 case ScriptBaseClass.OBJECT_PHYSICS_COST: 13685 case ScriptBaseClass.OBJECT_PHYSICS_COST:
13239 // The linden calculation is here 13686 // The value returned in SL for normal prims is prim count
13240 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 13687 ret.Add(new LSL_Float(obj.PhysicsCost));
13241 // The value returned in SL for normal prims looks like the prim count
13242 ret.Add(new LSL_Float(0));
13243 break; 13688 break;
13244 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 13689 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
13245 ret.Add(new LSL_Float(0)); 13690 ret.Add(new LSL_Float(0));
@@ -13522,12 +13967,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13522 13967
13523 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 13968 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
13524 { 13969 {
13525 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 13970 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
13971
13972 LSL_List result = new LSL_List();
13526 13973
13527 if (obj != null && obj.OwnerID == m_host.OwnerID) 13974 if (obj != null && obj.OwnerID == m_host.OwnerID)
13528 return GetEntityParams(obj, rules); 13975 {
13976 LSL_List remaining = GetPrimParams(obj, rules, ref result);
13529 13977
13530 return new LSL_List(); 13978 while (remaining.Length > 2)
13979 {
13980 int linknumber = remaining.GetLSLIntegerItem(0);
13981 rules = remaining.GetSublist(1, -1);
13982 List<SceneObjectPart> parts = GetLinkParts(linknumber);
13983
13984 foreach (SceneObjectPart part in parts)
13985 remaining = GetPrimParams(part, rules, ref result);
13986 }
13987 }
13988
13989 return result;
13531 } 13990 }
13532 13991
13533 public void print(string str) 13992 public void print(string str)
@@ -13539,6 +13998,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13539 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 13998 ossl.CheckThreatLevel(ThreatLevel.High, "print");
13540 m_log.Info("LSL print():" + str); 13999 m_log.Info("LSL print():" + str);
13541 } 14000 }
14001 }
14002
14003 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
14004 {
14005 List<SceneObjectPart> parts = GetLinkParts(link);
14006 if (parts.Count < 1)
14007 return 0;
14008
14009 return GetNumberOfSides(parts[0]);
13542 } 14010 }
13543 14011
13544 private string Name2Username(string name) 14012 private string Name2Username(string name)
@@ -13583,7 +14051,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13583 14051
13584 return rq.ToString(); 14052 return rq.ToString();
13585 } 14053 }
13586 14054/*
14055 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
14056 {
14057 m_SayShoutCount = 0;
14058 }
14059*/
13587 private struct Tri 14060 private struct Tri
13588 { 14061 {
13589 public Vector3 p1; 14062 public Vector3 p1;
@@ -13732,9 +14205,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13732 14205
13733 ContactResult result = new ContactResult (); 14206 ContactResult result = new ContactResult ();
13734 result.ConsumerID = group.LocalId; 14207 result.ConsumerID = group.LocalId;
13735 result.Depth = intersection.distance; 14208// result.Depth = intersection.distance;
13736 result.Normal = intersection.normal; 14209 result.Normal = intersection.normal;
13737 result.Pos = intersection.ipoint; 14210 result.Pos = intersection.ipoint;
14211 result.Depth = Vector3.Mag(rayStart - result.Pos);
13738 14212
13739 contacts.Add(result); 14213 contacts.Add(result);
13740 }); 14214 });
@@ -13867,6 +14341,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13867 14341
13868 return contacts[0]; 14342 return contacts[0];
13869 } 14343 }
14344/*
14345 // not done:
14346 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
14347 {
14348 ContactResult[] contacts = null;
14349 World.ForEachSOG(delegate(SceneObjectGroup group)
14350 {
14351 if (m_host.ParentGroup == group)
14352 return;
14353
14354 if (group.IsAttachment)
14355 return;
14356
14357 if(group.RootPart.PhysActor != null)
14358 return;
14359
14360 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
14361 });
14362 return contacts;
14363 }
14364*/
13870 14365
13871 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 14366 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
13872 { 14367 {
@@ -13917,7 +14412,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13917 if (dist == 0) 14412 if (dist == 0)
13918 return list; 14413 return list;
13919 14414
13920 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull; 14415 RayFilterFlags rayfilter = RayFilterFlags.BackFaceCull;
13921 if (checkTerrain) 14416 if (checkTerrain)
13922 rayfilter |= RayFilterFlags.land; 14417 rayfilter |= RayFilterFlags.land;
13923// if (checkAgents) 14418// if (checkAgents)
@@ -13994,18 +14489,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13994 } 14489 }
13995 } 14490 }
13996 14491
14492 // Double check this
13997 if (checkTerrain) 14493 if (checkTerrain)
13998 { 14494 {
13999 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 14495 bool skipGroundCheck = false;
14000 if (groundContact != null) 14496
14001 results.Add((ContactResult)groundContact); 14497 foreach (ContactResult c in results)
14498 {
14499 if (c.ConsumerID == 0) // Physics gave us a ground collision
14500 skipGroundCheck = true;
14501 }
14502
14503 if (!skipGroundCheck)
14504 {
14505 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
14506 if (groundContact != null)
14507 results.Add((ContactResult)groundContact);
14508 }
14002 } 14509 }
14003 14510
14004 results.Sort(delegate(ContactResult a, ContactResult b) 14511 results.Sort(delegate(ContactResult a, ContactResult b)
14005 { 14512 {
14006 return a.Depth.CompareTo(b.Depth); 14513 return a.Depth.CompareTo(b.Depth);
14007 }); 14514 });
14008 14515
14009 int values = 0; 14516 int values = 0;
14010 SceneObjectGroup thisgrp = m_host.ParentGroup; 14517 SceneObjectGroup thisgrp = m_host.ParentGroup;
14011 14518
@@ -14062,6 +14569,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14062 14569
14063 return list; 14570 return list;
14064 } 14571 }
14572
14065 14573
14066 /// <summary> 14574 /// <summary>
14067 /// Implementation of llCastRay similar to SL 2015-04-21. 14575 /// Implementation of llCastRay similar to SL 2015-04-21.
@@ -14086,7 +14594,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14086 UUID userId = UUID.Zero; 14594 UUID userId = UUID.Zero;
14087 int msAvailable = 0; 14595 int msAvailable = 0;
14088 // Throttle per owner when attachment or "vehicle" (sat upon) 14596 // Throttle per owner when attachment or "vehicle" (sat upon)
14089 if (m_host.ParentGroup.IsAttachment || m_host.ParentGroup.GetSittingAvatars().Count > 0) 14597 if (m_host.ParentGroup.IsAttachment || m_host.ParentGroup.GetSittingAvatarsCount() > 0)
14090 { 14598 {
14091 userId = m_host.OwnerID; 14599 userId = m_host.OwnerID;
14092 msAvailable = m_msPerAvatarInCastRay; 14600 msAvailable = m_msPerAvatarInCastRay;
@@ -14964,7 +15472,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14964 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 15472 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
14965 if (!isAccount) return 0; 15473 if (!isAccount) return 0;
14966 if (estate.HasAccess(id)) return 1; 15474 if (estate.HasAccess(id)) return 1;
14967 if (estate.IsBanned(id)) 15475 if (estate.IsBanned(id, World.GetUserFlags(id)))
14968 estate.RemoveBan(id); 15476 estate.RemoveBan(id);
14969 estate.AddEstateUser(id); 15477 estate.AddEstateUser(id);
14970 break; 15478 break;
@@ -14983,14 +15491,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14983 break; 15491 break;
14984 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 15492 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
14985 if (!isAccount) return 0; 15493 if (!isAccount) return 0;
14986 if (estate.IsBanned(id)) return 1; 15494 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
14987 EstateBan ban = new EstateBan(); 15495 EstateBan ban = new EstateBan();
14988 ban.EstateID = estate.EstateID; 15496 ban.EstateID = estate.EstateID;
14989 ban.BannedUserID = id; 15497 ban.BannedUserID = id;
14990 estate.AddBan(ban); 15498 estate.AddBan(ban);
14991 break; 15499 break;
14992 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 15500 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
14993 if (!isAccount || !estate.IsBanned(id)) return 0; 15501 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
14994 estate.RemoveBan(id); 15502 estate.RemoveBan(id);
14995 break; 15503 break;
14996 default: return 0; 15504 default: return 0;
@@ -15049,13 +15557,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
15049 public void llCollisionSprite(string impact_sprite) 15557 public void llCollisionSprite(string impact_sprite)
15050 { 15558 {
15051 m_host.AddScriptLPS(1); 15559 m_host.AddScriptLPS(1);
15052 NotImplemented("llCollisionSprite"); 15560 // Viewer 2.0 broke this and it's likely LL has no intention
15561 // of fixing it. Therefore, letting this be a NOP seems appropriate.
15053 } 15562 }
15054 15563
15055 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 15564 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
15056 { 15565 {
15057 m_host.AddScriptLPS(1); 15566 m_host.AddScriptLPS(1);
15058 NotImplemented("llGodLikeRezObject"); 15567
15568 if (!World.Permissions.IsGod(m_host.OwnerID))
15569 NotImplemented("llGodLikeRezObject");
15570
15571 AssetBase rezAsset = World.AssetService.Get(inventory);
15572 if (rezAsset == null)
15573 {
15574 llSay(0, "Asset not found");
15575 return;
15576 }
15577
15578 SceneObjectGroup group = null;
15579
15580 try
15581 {
15582 string xmlData = Utils.BytesToString(rezAsset.Data);
15583 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
15584 }
15585 catch
15586 {
15587 llSay(0, "Asset not found");
15588 return;
15589 }
15590
15591 if (group == null)
15592 {
15593 llSay(0, "Asset not found");
15594 return;
15595 }
15596
15597 group.RootPart.AttachPoint = group.RootPart.Shape.State;
15598 group.RootPart.AttachedPos = group.AbsolutePosition;
15599
15600 group.ResetIDs();
15601
15602 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
15603 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
15604 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
15605 group.ScheduleGroupForFullUpdate();
15606
15607 // objects rezzed with this method are die_at_edge by default.
15608 group.RootPart.SetDieAtEdge(true);
15609
15610 group.ResumeScripts();
15611
15612 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
15613 "object_rez", new Object[] {
15614 new LSL_String(
15615 group.RootPart.UUID.ToString()) },
15616 new DetectParams[0]));
15059 } 15617 }
15060 15618
15061 public LSL_String llTransferLindenDollars(string destination, int amount) 15619 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -15106,8 +15664,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
15106 return; 15664 return;
15107 } 15665 }
15108 15666
15667 string reason;
15109 bool result = money.ObjectGiveMoney( 15668 bool result = money.ObjectGiveMoney(
15110 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 15669 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn, out reason);
15111 15670
15112 if (result) 15671 if (result)
15113 { 15672 {
@@ -15115,7 +15674,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
15115 return; 15674 return;
15116 } 15675 }
15117 15676
15118 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS"; 15677 replydata = reason;
15119 } 15678 }
15120 finally 15679 finally
15121 { 15680 {
@@ -15132,6 +15691,813 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
15132 } 15691 }
15133 15692
15134 #endregion 15693 #endregion
15694
15695
15696 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
15697 {
15698 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
15699
15700 int idx = 0;
15701 int idxStart = 0;
15702
15703 bool positionChanged = false;
15704 Vector3 finalPos = Vector3.Zero;
15705
15706 try
15707 {
15708 while (idx < rules.Length)
15709 {
15710 ++rulesParsed;
15711 int code = rules.GetLSLIntegerItem(idx++);
15712
15713 int remain = rules.Length - idx;
15714 idxStart = idx;
15715
15716 switch (code)
15717 {
15718 case (int)ScriptBaseClass.PRIM_POSITION:
15719 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
15720 {
15721 if (remain < 1)
15722 return new LSL_List();
15723
15724 LSL_Vector v;
15725 v = rules.GetVector3Item(idx++);
15726
15727 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
15728
15729 v = v + 2 * sitOffset;
15730
15731 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
15732 av.SendAvatarDataToAllAgents();
15733
15734 }
15735 break;
15736
15737 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
15738 case (int)ScriptBaseClass.PRIM_ROTATION:
15739 {
15740 if (remain < 1)
15741 return new LSL_List();
15742
15743 LSL_Rotation r;
15744 r = rules.GetQuaternionItem(idx++);
15745
15746 av.Rotation = r * llGetRootRotation();
15747 av.SendAvatarDataToAllAgents();
15748 }
15749 break;
15750
15751 // parse rest doing nothing but number of parameters error check
15752 case (int)ScriptBaseClass.PRIM_SIZE:
15753 case (int)ScriptBaseClass.PRIM_MATERIAL:
15754 case (int)ScriptBaseClass.PRIM_PHANTOM:
15755 case (int)ScriptBaseClass.PRIM_PHYSICS:
15756 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
15757 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
15758 case (int)ScriptBaseClass.PRIM_NAME:
15759 case (int)ScriptBaseClass.PRIM_DESC:
15760 if (remain < 1)
15761 return new LSL_List();
15762 idx++;
15763 break;
15764
15765 case (int)ScriptBaseClass.PRIM_GLOW:
15766 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
15767 case (int)ScriptBaseClass.PRIM_TEXGEN:
15768 if (remain < 2)
15769 return new LSL_List();
15770 idx += 2;
15771 break;
15772
15773 case (int)ScriptBaseClass.PRIM_TYPE:
15774 if (remain < 3)
15775 return new LSL_List();
15776 code = (int)rules.GetLSLIntegerItem(idx++);
15777 remain = rules.Length - idx;
15778 switch (code)
15779 {
15780 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
15781 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
15782 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
15783 if (remain < 6)
15784 return new LSL_List();
15785 idx += 6;
15786 break;
15787
15788 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
15789 if (remain < 5)
15790 return new LSL_List();
15791 idx += 5;
15792 break;
15793
15794 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
15795 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
15796 case (int)ScriptBaseClass.PRIM_TYPE_RING:
15797 if (remain < 11)
15798 return new LSL_List();
15799 idx += 11;
15800 break;
15801
15802 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
15803 if (remain < 2)
15804 return new LSL_List();
15805 idx += 2;
15806 break;
15807 }
15808 break;
15809
15810 case (int)ScriptBaseClass.PRIM_COLOR:
15811 case (int)ScriptBaseClass.PRIM_TEXT:
15812 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
15813 case (int)ScriptBaseClass.PRIM_OMEGA:
15814 if (remain < 3)
15815 return new LSL_List();
15816 idx += 3;
15817 break;
15818
15819 case (int)ScriptBaseClass.PRIM_TEXTURE:
15820 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
15821 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
15822 if (remain < 5)
15823 return new LSL_List();
15824 idx += 5;
15825 break;
15826
15827 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
15828 if (remain < 7)
15829 return new LSL_List();
15830
15831 idx += 7;
15832 break;
15833
15834 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
15835 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
15836 return new LSL_List();
15837
15838 return rules.GetSublist(idx, -1);
15839 }
15840 }
15841 }
15842 catch (InvalidCastException e)
15843 {
15844 Error(originFunc,string.Format(
15845 " error running rule #{1}: arg #{2} ",
15846 rulesParsed, idx - idxStart) + e.Message);
15847 }
15848 finally
15849 {
15850 if (positionChanged)
15851 {
15852 av.OffsetPosition = finalPos;
15853// av.SendAvatarDataToAllAgents();
15854 av.SendTerseUpdateToAllClients();
15855 positionChanged = false;
15856 }
15857 }
15858 return new LSL_List();
15859 }
15860
15861 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
15862 {
15863 // avatars case
15864 // replies as SL wiki
15865
15866// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
15867 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
15868
15869 int idx = 0;
15870 while (idx < rules.Length)
15871 {
15872 int code = (int)rules.GetLSLIntegerItem(idx++);
15873 int remain = rules.Length - idx;
15874
15875 switch (code)
15876 {
15877 case (int)ScriptBaseClass.PRIM_MATERIAL:
15878 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
15879 break;
15880
15881 case (int)ScriptBaseClass.PRIM_PHYSICS:
15882 res.Add(new LSL_Integer(0));
15883 break;
15884
15885 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
15886 res.Add(new LSL_Integer(0));
15887 break;
15888
15889 case (int)ScriptBaseClass.PRIM_PHANTOM:
15890 res.Add(new LSL_Integer(0));
15891 break;
15892
15893 case (int)ScriptBaseClass.PRIM_POSITION:
15894
15895 Vector3 pos = avatar.OffsetPosition;
15896
15897 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
15898 pos -= sitOffset;
15899
15900 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
15901 break;
15902
15903 case (int)ScriptBaseClass.PRIM_SIZE:
15904 Vector3 s = avatar.Appearance.AvatarSize;
15905 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
15906
15907 break;
15908
15909 case (int)ScriptBaseClass.PRIM_ROTATION:
15910 LSL_Rotation rot = new LSL_Rotation(avatar.Rotation.X, avatar.Rotation.Y, avatar.Rotation.Z, avatar.Rotation.W) / llGetRootRotation();
15911
15912 res.Add(rot);
15913 break;
15914
15915 case (int)ScriptBaseClass.PRIM_TYPE:
15916 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
15917 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
15918 res.Add(new LSL_Vector(0f,1.0f,0f));
15919 res.Add(new LSL_Float(0.0f));
15920 res.Add(new LSL_Vector(0, 0, 0));
15921 res.Add(new LSL_Vector(1.0f,1.0f,0f));
15922 res.Add(new LSL_Vector(0, 0, 0));
15923 break;
15924
15925 case (int)ScriptBaseClass.PRIM_TEXTURE:
15926 if (remain < 1)
15927 return new LSL_List();
15928
15929 int face = (int)rules.GetLSLIntegerItem(idx++);
15930 if (face == ScriptBaseClass.ALL_SIDES)
15931 {
15932 for (face = 0; face < 21; face++)
15933 {
15934 res.Add(new LSL_String(""));
15935 res.Add(new LSL_Vector(0,0,0));
15936 res.Add(new LSL_Vector(0,0,0));
15937 res.Add(new LSL_Float(0.0));
15938 }
15939 }
15940 else
15941 {
15942 if (face >= 0 && face < 21)
15943 {
15944 res.Add(new LSL_String(""));
15945 res.Add(new LSL_Vector(0,0,0));
15946 res.Add(new LSL_Vector(0,0,0));
15947 res.Add(new LSL_Float(0.0));
15948 }
15949 }
15950 break;
15951
15952 case (int)ScriptBaseClass.PRIM_COLOR:
15953 if (remain < 1)
15954 return new LSL_List();
15955
15956 face = (int)rules.GetLSLIntegerItem(idx++);
15957
15958 if (face == ScriptBaseClass.ALL_SIDES)
15959 {
15960 for (face = 0; face < 21; face++)
15961 {
15962 res.Add(new LSL_Vector(0,0,0));
15963 res.Add(new LSL_Float(0));
15964 }
15965 }
15966 else
15967 {
15968 res.Add(new LSL_Vector(0,0,0));
15969 res.Add(new LSL_Float(0));
15970 }
15971 break;
15972
15973 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
15974 if (remain < 1)
15975 return new LSL_List();
15976 face = (int)rules.GetLSLIntegerItem(idx++);
15977
15978 if (face == ScriptBaseClass.ALL_SIDES)
15979 {
15980 for (face = 0; face < 21; face++)
15981 {
15982 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
15983 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
15984 }
15985 }
15986 else
15987 {
15988 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
15989 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
15990 }
15991 break;
15992
15993 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
15994 if (remain < 1)
15995 return new LSL_List();
15996 face = (int)rules.GetLSLIntegerItem(idx++);
15997
15998 if (face == ScriptBaseClass.ALL_SIDES)
15999 {
16000 for (face = 0; face < 21; face++)
16001 {
16002 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
16003 }
16004 }
16005 else
16006 {
16007 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
16008 }
16009 break;
16010
16011 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
16012 res.Add(new LSL_Integer(0));
16013 res.Add(new LSL_Integer(0));// softness
16014 res.Add(new LSL_Float(0.0f)); // gravity
16015 res.Add(new LSL_Float(0.0f)); // friction
16016 res.Add(new LSL_Float(0.0f)); // wind
16017 res.Add(new LSL_Float(0.0f)); // tension
16018 res.Add(new LSL_Vector(0f,0f,0f));
16019 break;
16020
16021 case (int)ScriptBaseClass.PRIM_TEXGEN:
16022 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
16023 if (remain < 1)
16024 return new LSL_List();
16025 face = (int)rules.GetLSLIntegerItem(idx++);
16026
16027 if (face == ScriptBaseClass.ALL_SIDES)
16028 {
16029 for (face = 0; face < 21; face++)
16030 {
16031 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
16032 }
16033 }
16034 else
16035 {
16036 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
16037 }
16038 break;
16039
16040 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
16041 res.Add(new LSL_Integer(0));
16042 res.Add(new LSL_Vector(0f,0f,0f));
16043 res.Add(new LSL_Float(0f)); // intensity
16044 res.Add(new LSL_Float(0f)); // radius
16045 res.Add(new LSL_Float(0f)); // falloff
16046 break;
16047
16048 case (int)ScriptBaseClass.PRIM_GLOW:
16049 if (remain < 1)
16050 return new LSL_List();
16051 face = (int)rules.GetLSLIntegerItem(idx++);
16052
16053 if (face == ScriptBaseClass.ALL_SIDES)
16054 {
16055 for (face = 0; face < 21; face++)
16056 {
16057 res.Add(new LSL_Float(0f));
16058 }
16059 }
16060 else
16061 {
16062 res.Add(new LSL_Float(0f));
16063 }
16064 break;
16065
16066 case (int)ScriptBaseClass.PRIM_TEXT:
16067 res.Add(new LSL_String(""));
16068 res.Add(new LSL_Vector(0f,0f,0f));
16069 res.Add(new LSL_Float(1.0f));
16070 break;
16071
16072 case (int)ScriptBaseClass.PRIM_NAME:
16073 res.Add(new LSL_String(avatar.Name));
16074 break;
16075
16076 case (int)ScriptBaseClass.PRIM_DESC:
16077 res.Add(new LSL_String(""));
16078 break;
16079
16080 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
16081 Quaternion lrot = avatar.Rotation;
16082
16083 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
16084 {
16085 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
16086 }
16087 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
16088 break;
16089
16090 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
16091 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
16092 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
16093 lpos -= lsitOffset;
16094
16095 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
16096 {
16097 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
16098 }
16099 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
16100 break;
16101
16102 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
16103 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
16104 return new LSL_List();
16105
16106 return rules.GetSublist(idx, -1);
16107 }
16108 }
16109
16110 return new LSL_List();
16111 }
16112
16113 public void llSetAnimationOverride(LSL_String animState, LSL_String anim)
16114 {
16115 string state = String.Empty;
16116
16117 foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL)
16118 {
16119 if (kvp.Value.ToLower() == ((string)animState).ToLower())
16120 {
16121 state = kvp.Key;
16122 break;
16123 }
16124 }
16125
16126 if (state == String.Empty)
16127 {
16128 llShout(ScriptBaseClass.DEBUG_CHANNEL, "Invalid animation state " + animState);
16129 return;
16130 }
16131
16132 if (m_item.PermsGranter == UUID.Zero)
16133 {
16134 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16135 return;
16136 }
16137
16138 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS) == 0)
16139 {
16140 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16141 return;
16142 }
16143
16144 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
16145
16146 if (presence == null)
16147 return;
16148
16149 UUID animID;
16150
16151 animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation);
16152
16153 if (animID == UUID.Zero)
16154 {
16155 String animupper = ((string)anim).ToUpperInvariant();
16156 DefaultAvatarAnimations.AnimsUUID.TryGetValue(animupper, out animID);
16157 }
16158
16159 if (animID == UUID.Zero)
16160 {
16161 llShout(ScriptBaseClass.DEBUG_CHANNEL, "Animation not found");
16162 return;
16163 }
16164
16165 presence.SetAnimationOverride(state, animID);
16166 }
16167
16168 public void llResetAnimationOverride(LSL_String animState)
16169 {
16170 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
16171 if (presence == null)
16172 return;
16173
16174 if (m_item.PermsGranter == UUID.Zero)
16175 {
16176 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16177 return;
16178 }
16179
16180 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS) == 0)
16181 {
16182 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16183 return;
16184 }
16185
16186 if (animState == "ALL")
16187 {
16188 presence.SetAnimationOverride("ALL", UUID.Zero);
16189 return;
16190 }
16191
16192 string state = String.Empty;
16193
16194 foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL)
16195 {
16196 if (kvp.Value.ToLower() == ((string)animState).ToLower())
16197 {
16198 state = kvp.Key;
16199 break;
16200 }
16201 }
16202
16203 if (state == String.Empty)
16204 {
16205 return;
16206 }
16207
16208 presence.SetAnimationOverride(state, UUID.Zero);
16209 }
16210
16211 public LSL_String llGetAnimationOverride(LSL_String animState)
16212 {
16213 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
16214 if (presence == null)
16215 return String.Empty;
16216
16217 if (m_item.PermsGranter == UUID.Zero)
16218 {
16219 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16220 return String.Empty;
16221 }
16222
16223 if ((m_item.PermsMask & (ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS | ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION)) == 0)
16224 {
16225 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16226 return String.Empty;
16227 }
16228
16229 string state = String.Empty;
16230
16231 foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL)
16232 {
16233 if (kvp.Value.ToLower() == ((string)animState).ToLower())
16234 {
16235 state = kvp.Key;
16236 break;
16237 }
16238 }
16239
16240 if (state == String.Empty)
16241 {
16242 return String.Empty;
16243 }
16244
16245 UUID animID = presence.GetAnimationOverride(state);
16246 if (animID == UUID.Zero)
16247 return animState;
16248
16249 foreach (KeyValuePair<string, UUID> kvp in DefaultAvatarAnimations.AnimsUUID)
16250 {
16251 if (kvp.Value == animID)
16252 return kvp.Key.ToLower();
16253 }
16254
16255 foreach (TaskInventoryItem item in m_host.Inventory.GetInventoryItems())
16256 {
16257 if (item.AssetID == animID)
16258 return item.Name;
16259 }
16260
16261 return String.Empty;
16262 }
16263
16264 public LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers)
16265 {
16266 OSD o = OSDParser.DeserializeJson(json);
16267 OSD specVal = JsonGetSpecific(o, specifiers, 0);
16268
16269 return specVal.AsString();
16270 }
16271
16272 public LSL_List llJson2List(LSL_String json)
16273 {
16274 try
16275 {
16276 OSD o = OSDParser.DeserializeJson(json);
16277 return (LSL_List)ParseJsonNode(o);
16278 }
16279 catch (Exception)
16280 {
16281 return new LSL_List(ScriptBaseClass.JSON_INVALID);
16282 }
16283 }
16284
16285 private object ParseJsonNode(OSD node)
16286 {
16287 if (node.Type == OSDType.Integer)
16288 return new LSL_Integer(node.AsInteger());
16289 if (node.Type == OSDType.Boolean)
16290 return new LSL_Integer(node.AsBoolean() ? 1 : 0);
16291 if (node.Type == OSDType.Real)
16292 return new LSL_Float(node.AsReal());
16293 if (node.Type == OSDType.UUID || node.Type == OSDType.String)
16294 return new LSL_String(node.AsString());
16295 if (node.Type == OSDType.Array)
16296 {
16297 LSL_List resp = new LSL_List();
16298 OSDArray ar = node as OSDArray;
16299 foreach (OSD o in ar)
16300 resp.Add(ParseJsonNode(o));
16301 return resp;
16302 }
16303 if (node.Type == OSDType.Map)
16304 {
16305 LSL_List resp = new LSL_List();
16306 OSDMap ar = node as OSDMap;
16307 foreach (KeyValuePair<string, OSD> o in ar)
16308 {
16309 resp.Add(new LSL_String(o.Key));
16310 resp.Add(ParseJsonNode(o.Value));
16311 }
16312 return resp;
16313 }
16314 throw new Exception(ScriptBaseClass.JSON_INVALID);
16315 }
16316
16317 public LSL_String llList2Json(LSL_String type, LSL_List values)
16318 {
16319 try
16320 {
16321 if (type == ScriptBaseClass.JSON_ARRAY)
16322 {
16323 OSDArray array = new OSDArray();
16324 foreach (object o in values.Data)
16325 {
16326 array.Add(ListToJson(o));
16327 }
16328 return OSDParser.SerializeJsonString(array);
16329 }
16330 else if (type == ScriptBaseClass.JSON_OBJECT)
16331 {
16332 OSDMap map = new OSDMap();
16333 for (int i = 0; i < values.Data.Length; i += 2)
16334 {
16335 if (!(values.Data[i] is LSL_String))
16336 return ScriptBaseClass.JSON_INVALID;
16337 map.Add(((LSL_String)values.Data[i]).m_string, ListToJson(values.Data[i + 1]));
16338 }
16339 return OSDParser.SerializeJsonString(map);
16340 }
16341 return ScriptBaseClass.JSON_INVALID;
16342 }
16343 catch (Exception ex)
16344 {
16345 return ex.Message;
16346 }
16347 }
16348
16349 private OSD ListToJson(object o)
16350 {
16351 if (o is LSL_Float)
16352 return OSD.FromReal(((LSL_Float)o).value);
16353 if (o is LSL_Integer)
16354 {
16355 int i = ((LSL_Integer)o).value;
16356 if (i == 0)
16357 return OSD.FromBoolean(false);
16358 else if (i == 1)
16359 return OSD.FromBoolean(true);
16360 return OSD.FromInteger(i);
16361 }
16362 if (o is LSL_Rotation)
16363 return OSD.FromString(((LSL_Rotation)o).ToString());
16364 if (o is LSL_Vector)
16365 return OSD.FromString(((LSL_Vector)o).ToString());
16366 if (o is LSL_String)
16367 {
16368 string str = ((LSL_String)o).m_string;
16369 if (str == ScriptBaseClass.JSON_NULL)
16370 return new OSD();
16371 return OSD.FromString(str);
16372 }
16373 throw new Exception(ScriptBaseClass.JSON_INVALID);
16374 }
16375
16376 private OSD JsonGetSpecific(OSD o, LSL_List specifiers, int i)
16377 {
16378 object spec = specifiers.Data[i];
16379 OSD nextVal = null;
16380 if (o is OSDArray)
16381 {
16382 if (spec is LSL_Integer)
16383 nextVal = ((OSDArray)o)[((LSL_Integer)spec).value];
16384 }
16385 if (o is OSDMap)
16386 {
16387 if (spec is LSL_String)
16388 nextVal = ((OSDMap)o)[((LSL_String)spec).m_string];
16389 }
16390 if (nextVal != null)
16391 {
16392 if (specifiers.Data.Length - 1 > i)
16393 return JsonGetSpecific(nextVal, specifiers, i + 1);
16394 }
16395 return nextVal;
16396 }
16397
16398 public LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value)
16399 {
16400 try
16401 {
16402 OSD o = OSDParser.DeserializeJson(json);
16403 JsonSetSpecific(o, specifiers, 0, value);
16404 return OSDParser.SerializeJsonString(o);
16405 }
16406 catch (Exception)
16407 {
16408 }
16409 return ScriptBaseClass.JSON_INVALID;
16410 }
16411
16412 private void JsonSetSpecific(OSD o, LSL_List specifiers, int i, LSL_String val)
16413 {
16414 object spec = specifiers.Data[i];
16415 // 20131224 not used object specNext = i+1 == specifiers.Data.Length ? null : specifiers.Data[i+1];
16416 OSD nextVal = null;
16417 if (o is OSDArray)
16418 {
16419 OSDArray array = ((OSDArray)o);
16420 if (spec is LSL_Integer)
16421 {
16422 int v = ((LSL_Integer)spec).value;
16423 if (v >= array.Count)
16424 array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val));
16425 else
16426 nextVal = ((OSDArray)o)[v];
16427 }
16428 else if (spec is LSL_String && ((LSL_String)spec) == ScriptBaseClass.JSON_APPEND)
16429 array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val));
16430 }
16431 if (o is OSDMap)
16432 {
16433 if (spec is LSL_String)
16434 {
16435 OSDMap map = ((OSDMap)o);
16436 if (map.ContainsKey(((LSL_String)spec).m_string))
16437 nextVal = map[((LSL_String)spec).m_string];
16438 else
16439 map.Add(((LSL_String)spec).m_string, JsonBuildRestOfSpec(specifiers, i + 1, val));
16440 }
16441 }
16442 if (nextVal != null)
16443 {
16444 if (specifiers.Data.Length - 1 > i)
16445 {
16446 JsonSetSpecific(nextVal, specifiers, i + 1, val);
16447 return;
16448 }
16449 }
16450 }
16451
16452 private OSD JsonBuildRestOfSpec(LSL_List specifiers, int i, LSL_String val)
16453 {
16454 object spec = i >= specifiers.Data.Length ? null : specifiers.Data[i];
16455 // 20131224 not used object specNext = i+1 >= specifiers.Data.Length ? null : specifiers.Data[i+1];
16456
16457 if (spec == null)
16458 return OSD.FromString(val);
16459
16460 if (spec is LSL_Integer ||
16461 (spec is LSL_String && ((LSL_String)spec) == ScriptBaseClass.JSON_APPEND))
16462 {
16463 OSDArray array = new OSDArray();
16464 array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val));
16465 return array;
16466 }
16467 else if (spec is LSL_String)
16468 {
16469 OSDMap map = new OSDMap();
16470 map.Add((LSL_String)spec, JsonBuildRestOfSpec(specifiers, i + 1, val));
16471 return map;
16472 }
16473 return new OSD();
16474 }
16475
16476 public LSL_String llJsonValueType(LSL_String json, LSL_List specifiers)
16477 {
16478 OSD o = OSDParser.DeserializeJson(json);
16479 OSD specVal = JsonGetSpecific(o, specifiers, 0);
16480 if (specVal == null)
16481 return ScriptBaseClass.JSON_INVALID;
16482 switch (specVal.Type)
16483 {
16484 case OSDType.Array:
16485 return ScriptBaseClass.JSON_ARRAY;
16486 case OSDType.Boolean:
16487 return specVal.AsBoolean() ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE;
16488 case OSDType.Integer:
16489 case OSDType.Real:
16490 return ScriptBaseClass.JSON_NUMBER;
16491 case OSDType.Map:
16492 return ScriptBaseClass.JSON_OBJECT;
16493 case OSDType.String:
16494 case OSDType.UUID:
16495 return ScriptBaseClass.JSON_STRING;
16496 case OSDType.Unknown:
16497 return ScriptBaseClass.JSON_NULL;
16498 }
16499 return ScriptBaseClass.JSON_INVALID;
16500 }
15135 } 16501 }
15136 16502
15137 public class NotecardCache 16503 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 1458c95..7bd4fa7 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 e799714..fae0bda 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -140,8 +140,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
140 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 140 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
141 internal float m_ScriptDelayFactor = 1.0f; 141 internal float m_ScriptDelayFactor = 1.0f;
142 internal float m_ScriptDistanceFactor = 1.0f; 142 internal float m_ScriptDistanceFactor = 1.0f;
143 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 143 internal bool m_debuggerSafe = false;
144 144 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
145 protected IUrlModule m_UrlModule = null; 145 protected IUrlModule m_UrlModule = null;
146 146
147 public void Initialize( 147 public void Initialize(
@@ -150,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
150 m_ScriptEngine = scriptEngine; 150 m_ScriptEngine = scriptEngine;
151 m_host = host; 151 m_host = host;
152 m_item = item; 152 m_item = item;
153 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
153 154
154 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 155 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
155 156
@@ -194,7 +195,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
194 default: 195 default:
195 break; 196 break;
196 } 197 }
197 } 198 }
198 199
199 public override Object InitializeLifetimeService() 200 public override Object InitializeLifetimeService()
200 { 201 {
@@ -216,7 +217,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
216 217
217 internal void OSSLError(string msg) 218 internal void OSSLError(string msg)
218 { 219 {
219 throw new ScriptException("OSSL Runtime Error: " + msg); 220 if (m_debuggerSafe)
221 {
222 OSSLShoutError(msg);
223 }
224 else
225 {
226 throw new ScriptException("OSSL Runtime Error: " + msg);
227 }
220 } 228 }
221 229
222 /// <summary> 230 /// <summary>
@@ -820,7 +828,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
820 private void TeleportAgent(string agent, int regionX, int regionY, 828 private void TeleportAgent(string agent, int regionX, int regionY,
821 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions) 829 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions)
822 { 830 {
823 // ulong regionHandle = Util.UIntsToLong(((uint)regionX * (uint)Constants.RegionSize), ((uint)regionY * (uint)Constants.RegionSize));
824 ulong regionHandle = Util.RegionLocToHandle((uint)regionX, (uint)regionY); 831 ulong regionHandle = Util.RegionLocToHandle((uint)regionX, (uint)regionY);
825 832
826 m_host.AddScriptLPS(1); 833 m_host.AddScriptLPS(1);
@@ -993,18 +1000,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
993 if (target != null) 1000 if (target != null)
994 { 1001 {
995 UUID animID=UUID.Zero; 1002 UUID animID=UUID.Zero;
996 lock (m_host.TaskInventory) 1003 m_host.TaskInventory.LockItemsForRead(true);
1004 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
997 { 1005 {
998 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 1006 if (inv.Value.Name == animation)
999 { 1007 {
1000 if (inv.Value.Name == animation) 1008 if (inv.Value.Type == (int)AssetType.Animation)
1001 { 1009 animID = inv.Value.AssetID;
1002 if (inv.Value.Type == (int)AssetType.Animation) 1010 continue;
1003 animID = inv.Value.AssetID;
1004 continue;
1005 }
1006 } 1011 }
1007 } 1012 }
1013 m_host.TaskInventory.LockItemsForRead(false);
1008 if (animID == UUID.Zero) 1014 if (animID == UUID.Zero)
1009 target.Animator.AddAnimation(animation, m_host.UUID); 1015 target.Animator.AddAnimation(animation, m_host.UUID);
1010 else 1016 else
@@ -1046,6 +1052,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1046 animID = UUID.Zero; 1052 animID = UUID.Zero;
1047 } 1053 }
1048 1054
1055
1049 if (animID == UUID.Zero) 1056 if (animID == UUID.Zero)
1050 target.Animator.RemoveAnimation(animation); 1057 target.Animator.RemoveAnimation(animation);
1051 else 1058 else
@@ -1487,7 +1494,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1487 return; 1494 return;
1488 } 1495 }
1489 1496
1490 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, startLandObject, GroupPowers.LandOptions)) 1497 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, startLandObject, GroupPowers.LandOptions, false))
1491 { 1498 {
1492 OSSLShoutError("You do not have permission to modify the parcel"); 1499 OSSLShoutError("You do not have permission to modify the parcel");
1493 return; 1500 return;
@@ -1934,15 +1941,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1934 { 1941 {
1935 UUID assetID = UUID.Zero; 1942 UUID assetID = UUID.Zero;
1936 1943
1937 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1944 bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID);
1945
1946 if (!notecardNameIsUUID)
1938 { 1947 {
1939 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1948 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1940 {
1941 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1942 {
1943 assetID = item.AssetID;
1944 }
1945 }
1946 } 1949 }
1947 1950
1948 if (assetID == UUID.Zero) 1951 if (assetID == UUID.Zero)
@@ -1953,13 +1956,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1953 AssetBase a = World.AssetService.Get(assetID.ToString()); 1956 AssetBase a = World.AssetService.Get(assetID.ToString());
1954 1957
1955 if (a == null) 1958 if (a == null)
1956 return UUID.Zero; 1959 {
1960 // Whoops, it's still possible here that the notecard name was properly
1961 // formatted like a UUID but isn't an asset UUID so lets look it up by name after all
1962 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1963 if (assetID == UUID.Zero)
1964 return UUID.Zero;
1965
1966 if (!NotecardCache.IsCached(assetID))
1967 {
1968 a = World.AssetService.Get(assetID.ToString());
1969
1970 if (a == null)
1971 {
1972 return UUID.Zero;
1973 }
1974 }
1975 }
1957 1976
1958 NotecardCache.Cache(assetID, a.Data); 1977 NotecardCache.Cache(assetID, a.Data);
1959 }; 1978 };
1960 1979
1961 return assetID; 1980 return assetID;
1962 } 1981 }
1982 protected UUID SearchTaskInventoryForAssetId(string name)
1983 {
1984 UUID assetId = UUID.Zero;
1985 m_host.TaskInventory.LockItemsForRead(true);
1986 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1987 {
1988 if (item.Type == 7 && item.Name == name)
1989 {
1990 assetId = item.AssetID;
1991 }
1992 }
1993 m_host.TaskInventory.LockItemsForRead(false);
1994 return assetId;
1995 }
1963 1996
1964 /// <summary> 1997 /// <summary>
1965 /// Directly get an entire notecard at once. 1998 /// Directly get an entire notecard at once.
@@ -2543,8 +2576,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2543 { 2576 {
2544 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2577 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2545 m_host.AddScriptLPS(1); 2578 m_host.AddScriptLPS(1);
2579
2580 // have to get the npc module also here to set the default Not Owned
2581 INPCModule module = World.RequestModuleInterface<INPCModule>();
2582 if(module == null)
2583 return new LSL_Key(UUID.Zero.ToString());
2584
2585 bool owned = (module.NPCOptionFlags & NPCOptionsFlags.AllowNotOwned) == 0;
2546 2586
2547 return NpcCreate(firstname, lastname, position, notecard, false, false); 2587 return NpcCreate(firstname, lastname, position, notecard, owned, false);
2548 } 2588 }
2549 2589
2550 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2590 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2561,17 +2601,49 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2561 private LSL_Key NpcCreate( 2601 private LSL_Key NpcCreate(
2562 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2602 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2563 { 2603 {
2604
2605 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2606 return new LSL_Key(UUID.Zero.ToString());
2607
2564 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2608 INPCModule module = World.RequestModuleInterface<INPCModule>();
2565 if (module != null) 2609 if (module != null)
2566 { 2610 {
2611 string groupTitle = String.Empty;
2567 AvatarAppearance appearance = null; 2612 AvatarAppearance appearance = null;
2568 2613
2569 UUID id; 2614 // check creation options
2570 if (UUID.TryParse(notecard, out id)) 2615 NPCOptionsFlags createFlags = module.NPCOptionFlags;
2616
2617 if((createFlags & NPCOptionsFlags.AllowNotOwned) == 0 && !owned)
2618 {
2619 OSSLError("Not owned NPCs disabled");
2620 owned = true; // we should get here...
2621 }
2622
2623 if((createFlags & NPCOptionsFlags.AllowSenseAsAvatar) == 0 && senseAsAgent)
2624 {
2625 OSSLError("NPC allow sense as Avatar disabled");
2626 senseAsAgent = false;
2627 }
2628
2629 if((createFlags & NPCOptionsFlags.NoNPCGroup) == 0)
2630 {
2631 if (firstname != String.Empty || lastname != String.Empty)
2632 {
2633 if (firstname != "Shown outfit:")
2634 groupTitle = "- NPC -";
2635 }
2636 }
2637
2638 if((createFlags & NPCOptionsFlags.AllowCloneOtherAvatars) != 0)
2571 { 2639 {
2572 ScenePresence clonePresence = World.GetScenePresence(id); 2640 UUID id;
2573 if (clonePresence != null) 2641 if (UUID.TryParse(notecard, out id))
2574 appearance = clonePresence.Appearance; 2642 {
2643 ScenePresence clonePresence = World.GetScenePresence(id);
2644 if (clonePresence != null)
2645 appearance = clonePresence.Appearance;
2646 }
2575 } 2647 }
2576 2648
2577 if (appearance == null) 2649 if (appearance == null)
@@ -2580,9 +2652,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2580 2652
2581 if (appearanceSerialized != null) 2653 if (appearanceSerialized != null)
2582 { 2654 {
2583 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2655 try
2584 appearance = new AvatarAppearance(); 2656 {
2585 appearance.Unpack(appearanceOsd); 2657 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2658 appearance = new AvatarAppearance();
2659 appearance.Unpack(appearanceOsd);
2660 }
2661 catch
2662 {
2663 return UUID.Zero.ToString();
2664 }
2586 } 2665 }
2587 else 2666 else
2588 { 2667 {
@@ -2601,6 +2680,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2601 World, 2680 World,
2602 appearance); 2681 appearance);
2603 2682
2683 ScenePresence sp;
2684 if (World.TryGetScenePresence(x, out sp))
2685 {
2686 sp.Grouptitle = groupTitle;
2687 sp.SendAvatarDataToAllAgents();
2688 }
2604 return new LSL_Key(x.ToString()); 2689 return new LSL_Key(x.ToString());
2605 } 2690 }
2606 2691
@@ -2898,16 +2983,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2898 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2983 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2899 m_host.AddScriptLPS(1); 2984 m_host.AddScriptLPS(1);
2900 2985
2901 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2986 try
2902 if (module != null)
2903 { 2987 {
2904 UUID npcId = new UUID(npc.m_string); 2988 INPCModule module = World.RequestModuleInterface<INPCModule>();
2989 if (module != null)
2990 {
2991 UUID npcId = new UUID(npc.m_string);
2905 2992
2906 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2993 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2907 return; 2994 return;
2908 2995
2909 module.DeleteNPC(npcId, World); 2996 module.DeleteNPC(npcId, World);
2997 }
2910 } 2998 }
2999 catch { }
2911 } 3000 }
2912 3001
2913 public void osNpcPlayAnimation(LSL_Key npc, string animation) 3002 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3185,7 +3274,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3185 { 3274 {
3186 Scene scene = m_ScriptEngine.World; 3275 Scene scene = m_ScriptEngine.World;
3187 GridRegion region = scene.GridService.GetRegionByUUID(UUID.Zero, World.RegionInfo.RegionID); 3276 GridRegion region = scene.GridService.GetRegionByUUID(UUID.Zero, World.RegionInfo.RegionID);
3188 return new LSL_Vector((float)region.RegionSizeX, (float)region.RegionSizeX, Constants.RegionHeight); 3277 return new LSL_Vector((float)region.RegionSizeX, (float)region.RegionSizeY, (float)Constants.RegionHeight);
3189 } 3278 }
3190 } 3279 }
3191 3280
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 64dc2e2..7bfe27b 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
@@ -358,7 +358,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
358 if (avatar == null) 358 if (avatar == null)
359 return sensedEntities; 359 return sensedEntities;
360 360
361 q = avatar.GetWorldRotation() * q; 361 fromRegionPos = avatar.AbsolutePosition;
362 q = avatar.Rotation;
362 } 363 }
363 364
364 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 365 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -402,7 +403,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
402 objtype = 0; 403 objtype = 0;
403 404
404 part = ((SceneObjectGroup)ent).RootPart; 405 part = ((SceneObjectGroup)ent).RootPart;
405 if (part.ParentGroup.AttachmentPoint != 0) // Attached so ignore 406 if (part.ParentGroup.RootPart.Shape.PCode != (byte)PCode.Tree &&
407 part.ParentGroup.RootPart.Shape.PCode != (byte)PCode.NewTree &&
408 part.ParentGroup.AttachmentPoint != 0) // Attached so ignore
406 continue; 409 continue;
407 410
408 if (part.Inventory.ContainsScripts()) 411 if (part.Inventory.ContainsScripts())
@@ -489,8 +492,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
489 // Don't proceed if the avatar for this attachment has since been removed from the scene. 492 // Don't proceed if the avatar for this attachment has since been removed from the scene.
490 if (avatar == null) 493 if (avatar == null)
491 return sensedEntities; 494 return sensedEntities;
492 495 fromRegionPos = avatar.AbsolutePosition;
493 q = avatar.GetWorldRotation() * q; 496 q = avatar.Rotation;
494 } 497 }
495 498
496 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 499 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -506,7 +509,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
506// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 509// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
507// presence.Name, presence.PresenceType, ts.name, ts.type); 510// presence.Name, presence.PresenceType, ts.name, ts.type);
508 511
509 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 512 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
510 { 513 {
511 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 514 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
512 if (npcData == null || !npcData.SenseAsAgent) 515 if (npcData == null || !npcData.SenseAsAgent)
@@ -546,7 +549,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
546 return; 549 return;
547 550
548 toRegionPos = presence.AbsolutePosition; 551 toRegionPos = presence.AbsolutePosition;
549 dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos)); 552 dis = Util.GetDistanceTo(toRegionPos, fromRegionPos);
553 if (presence.IsSatOnObject && presence.ParentPart != null &&
554 presence.ParentPart.ParentGroup != null &&
555 presence.ParentPart.ParentGroup.RootPart != null)
556 {
557 Vector3 rpos = presence.ParentPart.ParentGroup.RootPart.AbsolutePosition;
558 double dis2 = Util.GetDistanceTo(rpos, fromRegionPos);
559 if (dis > dis2)
560 dis = dis2;
561 }
550 562
551 // Disabled for now since all osNpc* methods check for appropriate ownership permission. 563 // Disabled for now since all osNpc* methods check for appropriate ownership permission.
552 // Perhaps could be re-enabled as an NPC setting at some point since being able to make NPCs not 564 // Perhaps could be re-enabled as an NPC setting at some point since being able to make NPCs not
@@ -706,4 +718,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
706 return retList; 718 return retList;
707 } 719 }
708 } 720 }
709} \ No newline at end of file 721}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index 0b14565..5b1fdc0 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> 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 = new Dictionary<string, TimerInfo>(Timers);
130 foreach (TimerInfo ts in tvals) 131 }
132
133 foreach (TimerInfo ts in tvals.Values)
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 3d58573..8b8638c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -127,6 +127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
127 LSL_String llGetEnv(LSL_String name); 127 LSL_String llGetEnv(LSL_String name);
128 LSL_Vector llGetForce(); 128 LSL_Vector llGetForce();
129 LSL_Integer llGetFreeMemory(); 129 LSL_Integer llGetFreeMemory();
130 LSL_Integer llGetUsedMemory();
130 LSL_Integer llGetFreeURLs(); 131 LSL_Integer llGetFreeURLs();
131 LSL_Vector llGetGeometricCenter(); 132 LSL_Vector llGetGeometricCenter();
132 LSL_Float llGetGMTclock(); 133 LSL_Float llGetGMTclock();
@@ -204,12 +205,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
204 LSL_String llGetTimestamp(); 205 LSL_String llGetTimestamp();
205 LSL_Vector llGetTorque(); 206 LSL_Vector llGetTorque();
206 LSL_Integer llGetUnixTime(); 207 LSL_Integer llGetUnixTime();
207 LSL_Integer llGetUsedMemory();
208 LSL_Vector llGetVel(); 208 LSL_Vector llGetVel();
209 LSL_Float llGetWallclock(); 209 LSL_Float llGetWallclock();
210 void llGiveInventory(string destination, string inventory); 210 void llGiveInventory(string destination, string inventory);
211 void llGiveInventoryList(string destination, string category, LSL_List inventory); 211 void llGiveInventoryList(string destination, string category, LSL_List inventory);
212 void llGiveMoney(string destination, int amount); 212 LSL_Integer llGiveMoney(string destination, int amount);
213 LSL_String llTransferLindenDollars(string destination, int amount); 213 LSL_String llTransferLindenDollars(string destination, int amount);
214 void llGodLikeRezObject(string inventory, LSL_Vector pos); 214 void llGodLikeRezObject(string inventory, LSL_Vector pos);
215 LSL_Float llGround(LSL_Vector offset); 215 LSL_Float llGround(LSL_Vector offset);
@@ -344,7 +344,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
344 void llSetDamage(double damage); 344 void llSetDamage(double damage);
345 void llSetForce(LSL_Vector force, int local); 345 void llSetForce(LSL_Vector force, int local);
346 void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local); 346 void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local);
347 void llSetVelocity(LSL_Vector velocity, int local); 347 void llSetVelocity(LSL_Vector vel, int local);
348 void llSetAngularVelocity(LSL_Vector angularVelocity, int local); 348 void llSetAngularVelocity(LSL_Vector angularVelocity, int local);
349 void llSetHoverHeight(double height, int water, double tau); 349 void llSetHoverHeight(double height, int water, double tau);
350 void llSetInventoryPermMask(string item, int mask, int value); 350 void llSetInventoryPermMask(string item, int mask, int value);
@@ -362,11 +362,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
362 void llSetParcelMusicURL(string url); 362 void llSetParcelMusicURL(string url);
363 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 363 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
364 void llSetPos(LSL_Vector pos); 364 void llSetPos(LSL_Vector pos);
365 LSL_Integer llSetRegionPos(LSL_Vector pos);
365 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 366 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
366 void llSetPrimitiveParams(LSL_List rules); 367 void llSetPrimitiveParams(LSL_List rules);
367 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 368 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
368 void llSetPrimURL(string url); 369 void llSetPrimURL(string url);
369 LSL_Integer llSetRegionPos(LSL_Vector pos);
370 void llSetRemoteScriptAccessPin(int pin); 370 void llSetRemoteScriptAccessPin(int pin);
371 void llSetRot(LSL_Rotation rot); 371 void llSetRot(LSL_Rotation rot);
372 void llSetScale(LSL_Vector scale); 372 void llSetScale(LSL_Vector scale);
@@ -429,10 +429,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
429 LSL_Vector llWind(LSL_Vector offset); 429 LSL_Vector llWind(LSL_Vector offset);
430 LSL_String llXorBase64Strings(string str1, string str2); 430 LSL_String llXorBase64Strings(string str1, string str2);
431 LSL_String llXorBase64StringsCorrect(string str1, string str2); 431 LSL_String llXorBase64StringsCorrect(string str1, string str2);
432 void print(string str); 432 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
433 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
433 434
434 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); 435 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
435 void llSetKeyframedMotion(LSL_List frames, LSL_List options); 436 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
436 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 437 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
438 LSL_List llGetPhysicsMaterial();
439 void llSetAnimationOverride(LSL_String animState, LSL_String anim);
440 void llResetAnimationOverride(LSL_String anim_state);
441 LSL_String llGetAnimationOverride(LSL_String anim_state);
442 LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers);
443 LSL_List llJson2List(LSL_String json);
444 LSL_String llList2Json(LSL_String type, LSL_List values);
445 LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value);
446 LSL_String llJsonValueType(LSL_String json, LSL_List specifiers);
437 } 447 }
438} 448}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 6259b76..4e567e6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -144,7 +144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
144 // Avatar Info Commands 144 // Avatar Info Commands
145 string osGetAgentIP(string agent); 145 string osGetAgentIP(string agent);
146 LSL_List osGetAgents(); 146 LSL_List osGetAgents();
147 147
148 // Teleport commands 148 // Teleport commands
149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index ce17ed0..1cc2cfb 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;
@@ -133,6 +134,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
133 return (eventFlags); 134 return (eventFlags);
134 } 135 }
135 136
137 [DebuggerNonUserCode]
136 public void ExecuteEvent(string state, string FunctionName, object[] args) 138 public void ExecuteEvent(string state, string FunctionName, object[] args)
137 { 139 {
138 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 140 // 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 9aecea2..158acc6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -57,7 +57,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
57 public const int ACTIVE = 2; 57 public const int ACTIVE = 2;
58 public const int PASSIVE = 4; 58 public const int PASSIVE = 4;
59 public const int SCRIPTED = 8; 59 public const int SCRIPTED = 8;
60 public const int OS_NPC = 0x01000000;
61 60
62 public const int CONTROL_FWD = 1; 61 public const int CONTROL_FWD = 1;
63 public const int CONTROL_BACK = 2; 62 public const int CONTROL_BACK = 2;
@@ -82,6 +81,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
82 public const int PERMISSION_CHANGE_PERMISSIONS = 512; 81 public const int PERMISSION_CHANGE_PERMISSIONS = 512;
83 public const int PERMISSION_TRACK_CAMERA = 1024; 82 public const int PERMISSION_TRACK_CAMERA = 1024;
84 public const int PERMISSION_CONTROL_CAMERA = 2048; 83 public const int PERMISSION_CONTROL_CAMERA = 2048;
84 public const int PERMISSION_TELEPORT = 4096;
85 public const int PERMISSION_OVERRIDE_ANIMATIONS = 0x8000;
85 86
86 public const int AGENT_FLYING = 1; 87 public const int AGENT_FLYING = 1;
87 public const int AGENT_ATTACHMENTS = 2; 88 public const int AGENT_ATTACHMENTS = 2;
@@ -96,6 +97,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
96 public const int AGENT_CROUCHING = 1024; 97 public const int AGENT_CROUCHING = 1024;
97 public const int AGENT_BUSY = 2048; 98 public const int AGENT_BUSY = 2048;
98 public const int AGENT_ALWAYS_RUN = 4096; 99 public const int AGENT_ALWAYS_RUN = 4096;
100 public const int AGENT_MALE = 8192;
99 101
100 //Particle Systems 102 //Particle Systems
101 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 103 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -353,6 +355,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
353 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 355 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
354 public const int CHANGED_MEDIA = 2048; 356 public const int CHANGED_MEDIA = 2048;
355 public const int CHANGED_ANIMATION = 16384; 357 public const int CHANGED_ANIMATION = 16384;
358 public const int CHANGED_POSITION = 32768;
356 public const int TYPE_INVALID = 0; 359 public const int TYPE_INVALID = 0;
357 public const int TYPE_INTEGER = 1; 360 public const int TYPE_INTEGER = 1;
358 public const int TYPE_FLOAT = 2; 361 public const int TYPE_FLOAT = 2;
@@ -708,7 +711,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
708 public const int FRICTION = 2; 711 public const int FRICTION = 2;
709 public const int RESTITUTION = 4; 712 public const int RESTITUTION = 4;
710 public const int GRAVITY_MULTIPLIER = 8; 713 public const int GRAVITY_MULTIPLIER = 8;
711 714
712 // extra constants for llSetPrimMediaParams 715 // extra constants for llSetPrimMediaParams
713 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 716 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
714 public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000); 717 public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000);
@@ -795,6 +798,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
795 public const int KFM_CMD_STOP = 1; 798 public const int KFM_CMD_STOP = 1;
796 public const int KFM_CMD_PAUSE = 2; 799 public const int KFM_CMD_PAUSE = 2;
797 800
801 public const string JSON_ARRAY = "JSON_ARRAY";
802 public const string JSON_OBJECT = "JSON_OBJECT";
803 public const string JSON_INVALID = "JSON_INVALID";
804 public const string JSON_NUMBER = "JSON_NUMBER";
805 public const string JSON_STRING = "JSON_STRING";
806 public const string JSON_TRUE = "JSON_TRUE";
807 public const string JSON_FALSE = "JSON_FALSE";
808 public const string JSON_NULL = "JSON_NULL";
809 public const string JSON_APPEND = "JSON_APPEND";
810
798 /// <summary> 811 /// <summary>
799 /// process name parameter as regex 812 /// process name parameter as regex
800 /// </summary> 813 /// </summary>
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 35aaf01..cea66d2 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();
@@ -479,6 +481,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
479 return m_LSL_Functions.llGetFreeMemory(); 481 return m_LSL_Functions.llGetFreeMemory();
480 } 482 }
481 483
484 public LSL_Integer llGetUsedMemory()
485 {
486 return m_LSL_Functions.llGetUsedMemory();
487 }
488
482 public LSL_Integer llGetFreeURLs() 489 public LSL_Integer llGetFreeURLs()
483 { 490 {
484 return m_LSL_Functions.llGetFreeURLs(); 491 return m_LSL_Functions.llGetFreeURLs();
@@ -559,11 +566,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
559 return m_LSL_Functions.llGetLinkNumberOfSides(link); 566 return m_LSL_Functions.llGetLinkNumberOfSides(link);
560 } 567 }
561 568
562 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
563 {
564 m_LSL_Functions.llSetKeyframedMotion(frames, options);
565 }
566
567 public LSL_Integer llGetListEntryType(LSL_List src, int index) 569 public LSL_Integer llGetListEntryType(LSL_List src, int index)
568 { 570 {
569 return m_LSL_Functions.llGetListEntryType(src, index); 571 return m_LSL_Functions.llGetListEntryType(src, index);
@@ -859,11 +861,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
859 return m_LSL_Functions.llGetUnixTime(); 861 return m_LSL_Functions.llGetUnixTime();
860 } 862 }
861 863
862 public LSL_Integer llGetUsedMemory()
863 {
864 return m_LSL_Functions.llGetUsedMemory();
865 }
866
867 public LSL_Vector llGetVel() 864 public LSL_Vector llGetVel()
868 { 865 {
869 return m_LSL_Functions.llGetVel(); 866 return m_LSL_Functions.llGetVel();
@@ -884,9 +881,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
884 m_LSL_Functions.llGiveInventoryList(destination, category, inventory); 881 m_LSL_Functions.llGiveInventoryList(destination, category, inventory);
885 } 882 }
886 883
887 public void llGiveMoney(string destination, int amount) 884 public LSL_Integer llGiveMoney(string destination, int amount)
888 { 885 {
889 m_LSL_Functions.llGiveMoney(destination, amount); 886 return m_LSL_Functions.llGiveMoney(destination, amount);
890 } 887 }
891 888
892 public LSL_String llTransferLindenDollars(string destination, int amount) 889 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -1563,6 +1560,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1563 m_LSL_Functions.llSetVelocity(force, local); 1560 m_LSL_Functions.llSetVelocity(force, local);
1564 } 1561 }
1565 1562
1563
1566 public void llSetAngularVelocity(LSL_Vector force, int local) 1564 public void llSetAngularVelocity(LSL_Vector force, int local)
1567 { 1565 {
1568 m_LSL_Functions.llSetAngularVelocity(force, local); 1566 m_LSL_Functions.llSetAngularVelocity(force, local);
@@ -1643,6 +1641,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1643 m_LSL_Functions.llSetPos(pos); 1641 m_LSL_Functions.llSetPos(pos);
1644 } 1642 }
1645 1643
1644 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1645 {
1646 return m_LSL_Functions.llSetRegionPos(pos);
1647 }
1648
1646 public void llSetPrimitiveParams(LSL_List rules) 1649 public void llSetPrimitiveParams(LSL_List rules)
1647 { 1650 {
1648 m_LSL_Functions.llSetPrimitiveParams(rules); 1651 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1658,11 +1661,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1658 m_LSL_Functions.llSetPrimURL(url); 1661 m_LSL_Functions.llSetPrimURL(url);
1659 } 1662 }
1660 1663
1661 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1662 {
1663 return m_LSL_Functions.llSetRegionPos(pos);
1664 }
1665
1666 public void llSetRemoteScriptAccessPin(int pin) 1664 public void llSetRemoteScriptAccessPin(int pin)
1667 { 1665 {
1668 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1666 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -2008,9 +2006,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
2008 return m_LSL_Functions.llClearLinkMedia(link, face); 2006 return m_LSL_Functions.llClearLinkMedia(link, face);
2009 } 2007 }
2010 2008
2011 public void print(string str) 2009 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
2010 {
2011 return m_LSL_Functions.llGetLinkNumberOfSides(link);
2012 }
2013
2014 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
2015 {
2016 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2017 }
2018
2019 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
2020 {
2021 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
2022 }
2023
2024 public LSL_List llGetPhysicsMaterial()
2025 {
2026 return m_LSL_Functions.llGetPhysicsMaterial();
2027 }
2028
2029 public void llSetAnimationOverride(LSL_String animState, LSL_String anim)
2030 {
2031 m_LSL_Functions.llSetAnimationOverride(animState, anim);
2032 }
2033
2034 public void llResetAnimationOverride(LSL_String anim_state)
2035 {
2036 m_LSL_Functions.llResetAnimationOverride(anim_state);
2037 }
2038
2039 public LSL_String llGetAnimationOverride(LSL_String anim_state)
2040 {
2041 return m_LSL_Functions.llGetAnimationOverride(anim_state);
2042 }
2043
2044 public LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers)
2045 {
2046 return m_LSL_Functions.llJsonGetValue(json, specifiers);
2047 }
2048
2049 public LSL_List llJson2List(LSL_String json)
2050 {
2051 return m_LSL_Functions.llJson2List(json);
2052 }
2053
2054 public LSL_String llList2Json(LSL_String type, LSL_List values)
2055 {
2056 return m_LSL_Functions.llList2Json(type, values);
2057 }
2058
2059 public LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value)
2060 {
2061 return m_LSL_Functions.llJsonSetValue(json, specifiers, value);
2062 }
2063
2064 public LSL_String llJsonValueType(LSL_String json, LSL_List specifiers)
2012 { 2065 {
2013 m_LSL_Functions.print(str); 2066 return m_LSL_Functions.llJsonValueType(json, specifiers);
2014 } 2067 }
2015 } 2068 }
2016} 2069}
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 a60f381..31393bb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -439,7 +439,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
439 { 439 {
440 return m_OSSL_Functions.osParseJSON(JSON); 440 return m_OSSL_Functions.osParseJSON(JSON);
441 } 441 }
442 442
443 public Object osParseJSONNew(string JSON) 443 public Object osParseJSONNew(string JSON)
444 { 444 {
445 return m_OSSL_Functions.osParseJSONNew(JSON); 445 return m_OSSL_Functions.osParseJSONNew(JSON);
@@ -744,14 +744,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
744 if (Position.y > ((int)Constants.RegionSize - 1)) 744 if (Position.y > ((int)Constants.RegionSize - 1))
745 Position.y = ((int)Constants.RegionSize - 1); 745 Position.y = ((int)Constants.RegionSize - 1);
746 */ 746 */
747 if (Position.z > Constants.RegionHeight)
748 Position.z = Constants.RegionHeight;
749 if (Position.x < 0) 747 if (Position.x < 0)
750 Position.x = 0; 748 Position.x = 0;
751 if (Position.y < 0) 749 if (Position.y < 0)
752 Position.y = 0; 750 Position.y = 0;
753 if (Position.z < 0) 751 if (Position.z < 0)
754 Position.z = 0; 752 Position.z = 0;
753 if (Position.z > Constants.RegionHeight)
754 Position.z = Constants.RegionHeight;
755 prim.OSSL.llSetPos(Position); 755 prim.OSSL.llSetPos(Position);
756 } 756 }
757 757
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp
deleted file mode 100644
index f02d2d9..0000000
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp
+++ /dev/null
@@ -1,48 +0,0 @@
1<Project name="OpenSim.Region.ScriptEngine.Shared.Api.Runtime" description="" standardNamespace="OpenSim.Region.ScriptEngine.Shared.Api.Runtime" newfilesearch="None" enableviewstate="True" fileversion="2.0" language="C#" clr-version="Net_2_0" ctype="DotNetProject">
2 <Configurations active="Debug">
3 <Configuration name="Debug" ctype="DotNetProjectConfiguration">
4 <Output directory="./../../../../../../bin/" assembly="OpenSim.Region.ScriptEngine.Shared.Api.Runtime" executeScript="" executeBeforeBuild="" executeAfterBuild="" executeBeforeBuildArguments="" executeAfterBuildArguments="" />
5 <Build debugmode="True" target="Library" />
6 <Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
7 <CodeGeneration compiler="Csc" warninglevel="4" nowarn="" includedebuginformation="True" optimize="False" unsafecodeallowed="False" generateoverflowchecks="False" mainclass="" target="Library" definesymbols="TRACE;DEBUG" generatexmldocumentation="False" win32Icon="" ctype="CSharpCompilerParameters" />
8 </Configuration>
9 <Configuration name="Release" ctype="DotNetProjectConfiguration">
10 <Output directory="./../../../../../../bin/" assembly="OpenSim.Region.ScriptEngine.Shared.Api.Runtime" executeScript="" executeBeforeBuild="" executeAfterBuild="" executeBeforeBuildArguments="" executeAfterBuildArguments="" />
11 <Build debugmode="True" target="Library" />
12 <Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
13 <CodeGeneration compiler="Csc" warninglevel="4" nowarn="" includedebuginformation="False" optimize="True" unsafecodeallowed="False" generateoverflowchecks="False" mainclass="" target="Library" definesymbols="TRACE" generatexmldocumentation="False" win32Icon="" ctype="CSharpCompilerParameters" />
14 </Configuration>
15 </Configurations>
16 <DeploymentInformation target="" script="" strategy="File">
17 <excludeFiles />
18 </DeploymentInformation>
19 <Contents>
20 <File name="./CM_Constants.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
21 <File name="./Executor.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
22 <File name="./LSL_Constants.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
23 <File name="./LSL_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
24 <File name="./LS_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
25 <File name="./MOD_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
26 <File name="./OSSL_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
27 <File name="./ScriptBase.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
28 <File name="./ScriptSponsor.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
29 </Contents>
30 <References>
31 <ProjectReference type="Assembly" refto="../../../../../../bin/log4net.dll" localcopy="False" />
32 <ProjectReference type="Assembly" refto="../../../../../../bin/Nini.dll" localcopy="False" />
33 <ProjectReference type="Assembly" refto="../../../../../../bin/Nini.dll" localcopy="False" />
34 <ProjectReference type="Assembly" refto="../../../../../../bin/OpenMetaverseTypes.dll" localcopy="False" />
35 <ProjectReference type="Project" localcopy="False" refto="OpenSim" />
36 <ProjectReference type="Project" localcopy="False" refto="OpenSim.Framework" />
37 <ProjectReference type="Project" localcopy="False" refto="OpenSim.Framework.Communications" />
38 <ProjectReference type="Project" localcopy="False" refto="OpenSim.Framework.Console" />
39 <ProjectReference type="Project" localcopy="False" refto="OpenSim.Region.CoreModules" />
40 <ProjectReference type="Project" localcopy="False" refto="OpenSim.Region.Framework" />
41 <ProjectReference type="Project" localcopy="False" refto="OpenSim.Region.ScriptEngine.Shared" />
42 <ProjectReference type="Assembly" refto="../../../../../../bin/RAIL.dll" localcopy="False" />
43 <ProjectReference type="Gac" localcopy="False" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
44 <ProjectReference type="Gac" localcopy="False" refto="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
45 <ProjectReference type="Gac" localcopy="False" refto="System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
46 <ProjectReference type="Gac" localcopy="False" refto="System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
47 </References>
48</Project>
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);