aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs117
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3950
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs170
-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
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs45
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs77
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs51
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/EventManager.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/Tests/XEnginePersistenceTests.cs2
23 files changed, 3328 insertions, 1492 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..f9f21f1 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)));
3275 3562
3276 if (m_host.ParentGroup.IsAttachment || strength == 0 || pa == null || !pa.IsPhysical) 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);
3566
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 }
@@ -4707,9 +5077,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4707 { 5077 {
4708 Error("llTextBox", "Empty message"); 5078 Error("llTextBox", "Empty message");
4709 } 5079 }
4710 else if (message.Length > 512) 5080 else if (Encoding.UTF8.GetByteCount(message) > 512)
4711 { 5081 {
4712 Error("llTextBox", "Message more than 512 characters"); 5082 Error("llTextBox", "Message longer than 512 bytes");
4713 } 5083 }
4714 else 5084 else
4715 { 5085 {
@@ -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); 6849 return new LSL_Integer(0);
6418 ScenePresence presence = World.GetScenePresence(agentId); 6850
6419 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6851 // Check if it's a group key
6420 return new LSL_Integer(0); 6852 if (uuid == m_host.ParentGroup.RootPart.GroupID)
6421 IClientAPI client = presence.ControllingClient;
6422 if (m_host.GroupID == client.ActiveGroupId)
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
6425 return new LSL_Integer(0); 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
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,29 +7895,43 @@ 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 if (message == string.Empty)
7912 {
7913 Error("llDialog", "Empty message");
7914 }
7915 else if (Encoding.UTF8.GetByteCount(message) > 512)
7916 {
7917 Error("llDialog", "Message longer than 512 bytes");
7918 }
7919
7920 string[] buts = new string[length];
7921 for (int i = 0; i < length; i++)
7446 { 7922 {
7447 if (buttons.Data[i].ToString() == String.Empty) 7923 if (buttons.Data[i].ToString() == String.Empty)
7448 { 7924 {
7449 Error("llDialog", "Button label cannot be blank"); 7925 Error("llDialog", "Button label cannot be blank");
7450 return; 7926 return;
7451 } 7927 }
7928/*
7452 if (buttons.Data[i].ToString().Length > 24) 7929 if (buttons.Data[i].ToString().Length > 24)
7453 { 7930 {
7454 Error("llDialog", "Button label cannot be longer than 24 characters"); 7931 Error("llDialog", "Button label cannot be longer than 24 characters");
7455 return; 7932 return;
7456 } 7933 }
7934*/
7457 buts[i] = buttons.Data[i].ToString(); 7935 buts[i] = buttons.Data[i].ToString();
7458 } 7936 }
7459 7937
@@ -7513,9 +7991,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7513 return; 7991 return;
7514 } 7992 }
7515 7993
7516 // the rest of the permission checks are done in RezScript, so check the pin there as well 7994 SceneObjectPart dest = World.GetSceneObjectPart(destId);
7517 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7995 if (dest != null)
7996 {
7997 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7998 {
7999 // the rest of the permission checks are done in RezScript, so check the pin there as well
8000 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
7518 8001
8002 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
8003 m_host.Inventory.RemoveInventoryItem(item.ItemID);
8004 }
8005 }
7519 // this will cause the delay even if the script pin or permissions were wrong - seems ok 8006 // this will cause the delay even if the script pin or permissions were wrong - seems ok
7520 ScriptSleep(m_sleepMsOnRemoteLoadScriptPin); 8007 ScriptSleep(m_sleepMsOnRemoteLoadScriptPin);
7521 } 8008 }
@@ -7589,19 +8076,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7589 public LSL_String llMD5String(string src, int nonce) 8076 public LSL_String llMD5String(string src, int nonce)
7590 { 8077 {
7591 m_host.AddScriptLPS(1); 8078 m_host.AddScriptLPS(1);
7592 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 8079 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
7593 } 8080 }
7594 8081
7595 public LSL_String llSHA1String(string src) 8082 public LSL_String llSHA1String(string src)
7596 { 8083 {
7597 m_host.AddScriptLPS(1); 8084 m_host.AddScriptLPS(1);
7598 return Util.SHA1Hash(src).ToLower(); 8085 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
7599 } 8086 }
7600 8087
7601 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 8088 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
7602 { 8089 {
7603 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 8090 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7604 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 8091 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
8092 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8093 return shapeBlock;
7605 8094
7606 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 8095 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
7607 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 8096 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -7706,6 +8195,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7706 // Prim type box, cylinder and prism. 8195 // 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) 8196 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 { 8197 {
8198 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8199 return;
8200
7709 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 8201 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7710 ObjectShapePacket.ObjectDataBlock shapeBlock; 8202 ObjectShapePacket.ObjectDataBlock shapeBlock;
7711 8203
@@ -7759,6 +8251,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7759 // Prim type sphere. 8251 // 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) 8252 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7761 { 8253 {
8254 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8255 return;
8256
7762 ObjectShapePacket.ObjectDataBlock shapeBlock; 8257 ObjectShapePacket.ObjectDataBlock shapeBlock;
7763 8258
7764 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 8259 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7805,6 +8300,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7805 // Prim type torus, tube and ring. 8300 // 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) 8301 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 { 8302 {
8303 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8304 return;
8305
7808 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 8306 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7809 ObjectShapePacket.ObjectDataBlock shapeBlock; 8307 ObjectShapePacket.ObjectDataBlock shapeBlock;
7810 8308
@@ -7940,6 +8438,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7940 // Prim type sculpt. 8438 // Prim type sculpt.
7941 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 8439 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7942 { 8440 {
8441 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8442 return;
8443
7943 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 8444 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7944 UUID sculptId; 8445 UUID sculptId;
7945 8446
@@ -7962,7 +8463,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7962 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 8463 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7963 { 8464 {
7964 // default 8465 // default
7965 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 8466 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7966 } 8467 }
7967 8468
7968 part.Shape.SetSculptProperties((byte)type, sculptId); 8469 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7995,9 +8496,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7995 SetLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 8496 SetLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7996 } 8497 }
7997 8498
7998 protected void SetLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 8499 private void SetLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7999 { 8500 {
8000 SetEntityParams(GetLinkEntities(linknumber), rules, originFunc); 8501 List<object> parts = new List<object>();
8502 List<SceneObjectPart> prims = GetLinkParts(linknumber);
8503 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
8504 foreach (SceneObjectPart p in prims)
8505 parts.Add(p);
8506 foreach (ScenePresence p in avatars)
8507 parts.Add(p);
8508
8509 LSL_List remaining = new LSL_List();
8510 uint rulesParsed = 0;
8511
8512 if (parts.Count > 0)
8513 {
8514 foreach (object part in parts)
8515 {
8516 if (part is SceneObjectPart)
8517 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
8518 else
8519 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
8520 }
8521
8522 while (remaining.Length > 2)
8523 {
8524 linknumber = remaining.GetLSLIntegerItem(0);
8525 rules = remaining.GetSublist(1, -1);
8526 parts.Clear();
8527 prims = GetLinkParts(linknumber);
8528 avatars = GetLinkAvatars(linknumber);
8529 foreach (SceneObjectPart p in prims)
8530 parts.Add(p);
8531 foreach (ScenePresence p in avatars)
8532 parts.Add(p);
8533
8534 remaining = new LSL_List();
8535 foreach (object part in parts)
8536 {
8537 if (part is SceneObjectPart)
8538 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
8539 else
8540 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
8541 }
8542 }
8543 }
8001 } 8544 }
8002 8545
8003 protected void SetEntityParams(List<ISceneEntity> entities, LSL_List rules, string originFunc) 8546 protected void SetEntityParams(List<ISceneEntity> entities, LSL_List rules, string originFunc)
@@ -8176,11 +8719,81 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8176 } 8719 }
8177 } 8720 }
8178 8721
8722 public LSL_List llGetPhysicsMaterial()
8723 {
8724 LSL_List result = new LSL_List();
8725
8726 result.Add(new LSL_Float(m_host.GravityModifier));
8727 result.Add(new LSL_Float(m_host.Restitution));
8728 result.Add(new LSL_Float(m_host.Friction));
8729 result.Add(new LSL_Float(m_host.Density));
8730
8731 return result;
8732 }
8733
8734 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
8735 float material_density, float material_friction,
8736 float material_restitution, float material_gravity_modifier)
8737 {
8738 ExtraPhysicsData physdata = new ExtraPhysicsData();
8739 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
8740 physdata.Density = part.Density;
8741 physdata.Friction = part.Friction;
8742 physdata.Bounce = part.Restitution;
8743 physdata.GravitationModifier = part.GravityModifier;
8744
8745 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
8746 physdata.Density = material_density;
8747 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
8748 physdata.Friction = material_friction;
8749 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
8750 physdata.Bounce = material_restitution;
8751 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
8752 physdata.GravitationModifier = material_gravity_modifier;
8753
8754 part.UpdateExtraPhysics(physdata);
8755 }
8756
8757 public void llSetPhysicsMaterial(int material_bits,
8758 float material_gravity_modifier, float material_restitution,
8759 float material_friction, float material_density)
8760 {
8761 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8762 }
8763
8764 // vector up using libomv (c&p from sop )
8765 // vector up rotated by r
8766 private Vector3 Zrot(Quaternion r)
8767 {
8768 double x, y, z, m;
8769
8770 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
8771 if (Math.Abs(1.0 - m) > 0.000001)
8772 {
8773 m = 1.0 / Math.Sqrt(m);
8774 r.X *= (float)m;
8775 r.Y *= (float)m;
8776 r.Z *= (float)m;
8777 r.W *= (float)m;
8778 }
8779
8780 x = 2 * (r.X * r.Z + r.Y * r.W);
8781 y = 2 * (-r.X * r.W + r.Y * r.Z);
8782 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
8783
8784 return new Vector3((float)x, (float)y, (float)z);
8785 }
8786
8179 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 8787 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
8180 { 8788 {
8789 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8790 return new LSL_List();
8791
8181 int idx = 0; 8792 int idx = 0;
8182 int idxStart = 0; 8793 int idxStart = 0;
8183 8794
8795 SceneObjectGroup parentgrp = part.ParentGroup;
8796
8184 bool positionChanged = false; 8797 bool positionChanged = false;
8185 LSL_Vector currentPosition = GetPartLocalPos(part); 8798 LSL_Vector currentPosition = GetPartLocalPos(part);
8186 8799
@@ -8216,8 +8829,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)); 8829 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(); 8830 return new LSL_List();
8218 } 8831 }
8832 if (part.IsRoot && !part.ParentGroup.IsAttachment)
8833 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
8834 else
8835 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
8219 positionChanged = true; 8836 positionChanged = true;
8220 currentPosition = GetSetPosTarget(part, v, currentPosition);
8221 8837
8222 break; 8838 break;
8223 case ScriptBaseClass.PRIM_SIZE: 8839 case ScriptBaseClass.PRIM_SIZE:
@@ -8242,7 +8858,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8242 return new LSL_List(); 8858 return new LSL_List();
8243 } 8859 }
8244 // try to let this work as in SL... 8860 // try to let this work as in SL...
8245 if (part.ParentID == 0) 8861 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
8246 { 8862 {
8247 // special case: If we are root, rotate complete SOG to new rotation 8863 // special case: If we are root, rotate complete SOG to new rotation
8248 SetRot(part, q); 8864 SetRot(part, q);
@@ -9243,7 +9859,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9243 9859
9244 break; 9860 break;
9245 9861
9246 case ScriptBaseClass.PRIM_TEMP_ON_REZ: 9862 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
9863 if (remain < 5)
9864 return new LSL_List();
9865
9866 int material_bits = rules.GetLSLIntegerItem(idx++);
9867 float material_density = (float)rules.GetLSLFloatItem(idx++);
9868 float material_friction = (float)rules.GetLSLFloatItem(idx++);
9869 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
9870 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
9871
9872 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
9873
9874 break;
9875
9876 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
9247 if (remain < 1) 9877 if (remain < 1)
9248 return new LSL_List(); 9878 return new LSL_List();
9249 string temp = rules.Data[idx++].ToString(); 9879 string temp = rules.Data[idx++].ToString();
@@ -9437,14 +10067,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9437 if (part.ParentGroup.RootPart == part) 10067 if (part.ParentGroup.RootPart == part)
9438 { 10068 {
9439 SceneObjectGroup parent = part.ParentGroup; 10069 SceneObjectGroup parent = part.ParentGroup;
9440 parent.UpdateGroupPosition(currentPosition); 10070// Util.FireAndForget(delegate(object x) {
10071 parent.UpdateGroupPosition(currentPosition);
10072// });
9441 } 10073 }
9442 else 10074 else
9443 { 10075 {
9444 part.OffsetPosition = currentPosition; 10076 part.OffsetPosition = currentPosition;
9445 SceneObjectGroup parent = part.ParentGroup; 10077// SceneObjectGroup parent = part.ParentGroup;
9446 parent.HasGroupChanged = true; 10078// parent.HasGroupChanged = true;
9447 parent.ScheduleGroupForTerseUpdate(); 10079// parent.ScheduleGroupForTerseUpdate();
10080 part.ScheduleTerseUpdate();
9448 } 10081 }
9449 } 10082 }
9450 } 10083 }
@@ -9511,7 +10144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9511 SceneObjectPart parentPart = sp.ParentPart; 10144 SceneObjectPart parentPart = sp.ParentPart;
9512 10145
9513 if (parentPart != null) 10146 if (parentPart != null)
9514 sp.Rotation = m_host.GetWorldRotation() * inRot; 10147 sp.Rotation = m_host.GetWorldRotation() * inRot;
9515 10148
9516 break; 10149 break;
9517 10150
@@ -9596,10 +10229,104 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9596 10229
9597 public LSL_String llXorBase64Strings(string str1, string str2) 10230 public LSL_String llXorBase64Strings(string str1, string str2)
9598 { 10231 {
10232 int padding = 0;
10233
10234 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
10235
10236 ScriptSleep(300);
9599 m_host.AddScriptLPS(1); 10237 m_host.AddScriptLPS(1);
9600 Deprecated("llXorBase64Strings", "Use llXorBase64 instead"); 10238
9601 ScriptSleep(m_sleepMsOnXorBase64Strings); 10239 if (str1 == String.Empty)
9602 return String.Empty; 10240 return String.Empty;
10241 if (str2 == String.Empty)
10242 return str1;
10243
10244 int len = str2.Length;
10245 if ((len % 4) != 0) // LL is EVIL!!!!
10246 {
10247 while (str2.EndsWith("="))
10248 str2 = str2.Substring(0, str2.Length - 1);
10249
10250 len = str2.Length;
10251 int mod = len % 4;
10252
10253 if (mod == 1)
10254 str2 = str2.Substring(0, str2.Length - 1);
10255 else if (mod == 2)
10256 str2 += "==";
10257 else if (mod == 3)
10258 str2 += "=";
10259 }
10260
10261 byte[] data1;
10262 byte[] data2;
10263 try
10264 {
10265 data1 = Convert.FromBase64String(str1);
10266 data2 = Convert.FromBase64String(str2);
10267 }
10268 catch (Exception)
10269 {
10270 return new LSL_String(String.Empty);
10271 }
10272
10273 // For cases where the decoded length of s2 is greater
10274 // than the decoded length of s1, simply perform a normal
10275 // decode and XOR
10276 //
10277 /*
10278 if (data2.Length >= data1.Length)
10279 {
10280 for (int pos = 0 ; pos < data1.Length ; pos++ )
10281 data1[pos] ^= data2[pos];
10282
10283 return Convert.ToBase64String(data1);
10284 }
10285 */
10286
10287 // Remove padding
10288 while (str1.EndsWith("="))
10289 {
10290 str1 = str1.Substring(0, str1.Length - 1);
10291 padding++;
10292 }
10293 while (str2.EndsWith("="))
10294 str2 = str2.Substring(0, str2.Length - 1);
10295
10296 byte[] d1 = new byte[str1.Length];
10297 byte[] d2 = new byte[str2.Length];
10298
10299 for (int i = 0 ; i < str1.Length ; i++)
10300 {
10301 int idx = b64.IndexOf(str1.Substring(i, 1));
10302 if (idx == -1)
10303 idx = 0;
10304 d1[i] = (byte)idx;
10305 }
10306
10307 for (int i = 0 ; i < str2.Length ; i++)
10308 {
10309 int idx = b64.IndexOf(str2.Substring(i, 1));
10310 if (idx == -1)
10311 idx = 0;
10312 d2[i] = (byte)idx;
10313 }
10314
10315 string output = String.Empty;
10316
10317 for (int pos = 0 ; pos < d1.Length ; pos++)
10318 output += b64[d1[pos] ^ d2[pos % d2.Length]];
10319
10320 // Here's a funny thing: LL blithely violate the base64
10321 // standard pretty much everywhere. Here, padding is
10322 // added only if the first input string had it, rather
10323 // than when the data actually needs it. This can result
10324 // in invalid base64 being returned. Go figure.
10325
10326 while (padding-- > 0)
10327 output += "=";
10328
10329 return output;
9603 } 10330 }
9604 10331
9605 public void llRemoteDataSetRegion() 10332 public void llRemoteDataSetRegion()
@@ -9742,188 +10469,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9742 public LSL_List llGetBoundingBox(string obj) 10469 public LSL_List llGetBoundingBox(string obj)
9743 { 10470 {
9744 m_host.AddScriptLPS(1); 10471 m_host.AddScriptLPS(1);
9745
9746 // Get target avatar if non-seated avatar or attachment, or prim and object
9747 UUID objID = UUID.Zero; 10472 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(); 10473 LSL_List result = new LSL_List();
9773 int groupCount = 0; 10474
9774 int partCount = 0; 10475 // If the ID is not valid, return null result
9775 int vertexCount = 0; 10476 if (!UUID.TryParse(obj, out objID))
9776 if (target == null && agent == null)
9777 { 10477 {
9778 result.Add(new LSL_Vector()); 10478 result.Add(new LSL_Vector());
9779 result.Add(new LSL_Vector()); 10479 result.Add(new LSL_Vector());
9780 if (m_addStatsInGetBoundingBox)
9781 result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount));
9782 return result; 10480 return result;
9783 } 10481 }
9784 Vector3 minPosition = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
9785 Vector3 maxPosition = new Vector3(float.MinValue, float.MinValue, float.MinValue);
9786 10482
9787 // Try to get a mesher 10483 // Check if this is an attached prim. If so, replace
9788 IRendering primMesher = null; 10484 // the UUID with the avatar UUID and report it's bounding box
9789 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); 10485 SceneObjectPart part = World.GetSceneObjectPart(objID);
9790 if (renderers.Count > 0) 10486 if (part != null && part.ParentGroup.IsAttachment)
9791 primMesher = RenderingLoader.LoadRenderer(renderers[0]); 10487 objID = part.ParentGroup.AttachedAvatar;
9792 10488
9793 // Get bounding box of just avatar, seated or not 10489 // Find out if this is an avatar ID. If so, return it's box
9794 if (agent != null) 10490 ScenePresence presence = World.GetScenePresence(objID);
9795 { 10491 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 { 10492 {
9817 // Merge bounding boxes of all parts (prims and mesh) 10493 // As per LSL Wiki, there is no difference between sitting
9818 foreach (SceneObjectPart part in group.Parts) 10494 // and standing avatar since server 1.36
9819 { 10495 LSL_Vector lower;
9820 bool hasParent = (!part.IsRoot); 10496 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 10497
9870 // When part is prim 10498 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 10499
9881 // When all else fails, try fallback to simple box 10500 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
9882 else 10501 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
9883 { 10502/*
9884 AddBoundingBoxOfSimpleBox(part.Scale * -0.5f, part.Scale * 0.5f, part.OffsetPosition, part.RotationOffset, hasParent, ref minPosition, ref maxPosition, ref vertexCount); 10503 {
9885 } 10504 // This is for ground sitting avatars
9886 } 10505 float height = presence.Appearance.AvatarHeight / 2.66666667f;
9887 partCount++; 10506 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
10507 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
10508 }
10509 else
10510 {
10511 // This is for standing/flying avatars
10512 float height = presence.Appearance.AvatarHeight / 2.0f;
10513 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
10514 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
9888 } 10515 }
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 10516
9899 bool hasParent = true; 10517 // Adjust to the documented error offsets (see LSL Wiki)
9900 // When requested or if no mesher, keep it simple 10518 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
9901 if (m_useSimpleBoxesInGetBoundingBox || primMesher == null) 10519 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
10520*/
9902 { 10521 {
9903 AddBoundingBoxOfSimpleBox(lower, upper, offset, sp.Rotation, hasParent, ref minPosition, ref maxPosition, ref vertexCount); 10522 // This is for ground sitting avatars TODO!
10523 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
10524 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
9904 } 10525 }
9905 // Do the full mounty
9906 else 10526 else
9907 { 10527 {
9908 // Prim shapes don't do center offsets, so add it here. 10528 // This is for standing/flying avatars
9909 offset = offset + (lower + upper) * 0.5f * sp.Rotation; 10529 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
9910 Primitive omvPrim = MakeOpenMetaversePrim(upper - lower, offset, sp.Rotation, ScriptBaseClass.PRIM_TYPE_SPHERE); 10530 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 } 10531 }
9915 partCount++; 10532
10533 if (lower.x > upper.x)
10534 lower.x = upper.x;
10535 if (lower.y > upper.y)
10536 lower.y = upper.y;
10537 if (lower.z > upper.z)
10538 lower.z = upper.z;
10539
10540 result.Add(lower);
10541 result.Add(upper);
10542 return result;
9916 } 10543 }
9917 10544
9918 groupCount++; 10545 part = World.GetSceneObjectPart(objID);
10546 // Currently only works for single prims without a sitting avatar
10547 if (part != null)
10548 {
10549 float minX;
10550 float maxX;
10551 float minY;
10552 float maxY;
10553 float minZ;
10554 float maxZ;
9919 10555
9920 // Return lower and upper bounding box corners 10556 // This BBox is in sim coordinates, with the offset being
9921 result.Add(new LSL_Vector(minPosition)); 10557 // a contained point.
9922 result.Add(new LSL_Vector(maxPosition)); 10558 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
9923 if (m_addStatsInGetBoundingBox) 10559 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
9924 result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount)); 10560
10561 minX -= offsets[0].X;
10562 maxX -= offsets[0].X;
10563 minY -= offsets[0].Y;
10564 maxY -= offsets[0].Y;
10565 minZ -= offsets[0].Z;
10566 maxZ -= offsets[0].Z;
10567
10568 LSL_Vector lower;
10569 LSL_Vector upper;
10570
10571 // Adjust to the documented error offsets (see LSL Wiki)
10572 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
10573 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
10574
10575 if (lower.x > upper.x)
10576 lower.x = upper.x;
10577 if (lower.y > upper.y)
10578 lower.y = upper.y;
10579 if (lower.z > upper.z)
10580 lower.z = upper.z;
10581
10582 result.Add(lower);
10583 result.Add(upper);
10584 return result;
10585 }
9925 10586
9926 primMesher = null; 10587 // Not found so return empty values
10588 result.Add(new LSL_Vector());
10589 result.Add(new LSL_Vector());
9927 return result; 10590 return result;
9928 } 10591 }
9929 10592
@@ -9963,425 +10626,71 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9963 } 10626 }
9964 } 10627 }
9965 10628
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 10629
10142 return prim;
10143 }
10144
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() 10630 public LSL_Vector llGetGeometricCenter()
10153 { 10631 {
10154 // Subtract whatever position the root prim has to make it zero 10632 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 } 10633 }
10168 10634
10169 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 10635 public LSL_List llGetPrimitiveParams(LSL_List rules)
10170 { 10636 {
10171 LSL_List result = new LSL_List(); 10637 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 10638
10183 if (entity is SceneObjectPart) 10639 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 10640
10188 if (remaining == null || remaining.Length < 2) 10641 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
10189 return result;
10190 10642
10643 while ((object)remaining != null && remaining.Length > 2)
10644 {
10191 int linknumber = remaining.GetLSLIntegerItem(0); 10645 int linknumber = remaining.GetLSLIntegerItem(0);
10192 rules = remaining.GetSublist(1, -1); 10646 rules = remaining.GetSublist(1, -1);
10193 entity = GetLinkEntity(m_host, linknumber); 10647 List<SceneObjectPart> parts = GetLinkParts(linknumber);
10194 }
10195 }
10196 10648
10197 public LSL_List llGetPrimitiveParams(LSL_List rules) 10649 foreach (SceneObjectPart part in parts)
10198 { 10650 remaining = GetPrimParams(part, rules, ref result);
10199 m_host.AddScriptLPS(1); 10651 }
10200 10652
10201 return GetEntityParams(m_host, rules); 10653 return result;
10202 } 10654 }
10203 10655
10204 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 10656 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
10205 { 10657 {
10206 m_host.AddScriptLPS(1); 10658 m_host.AddScriptLPS(1);
10207 10659
10208 return GetEntityParams(GetLinkEntity(m_host, linknumber), rules); 10660 // acording to SL wiki this must indicate a single link number or link_root or link_this.
10209 } 10661 // keep other options as before
10210 10662
10211 public LSL_Vector GetAgentSize(ScenePresence sp) 10663 List<SceneObjectPart> parts;
10212 { 10664 List<ScenePresence> avatars;
10213 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); 10665
10214 } 10666 LSL_List res = new LSL_List();
10667 LSL_List remaining = new LSL_List();
10215 10668
10216 /// <summary> 10669 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 { 10670 {
10228 int code = (int)rules.GetLSLIntegerItem(idx++); 10671 parts = GetLinkParts(linknumber);
10229 int remain = rules.Length-idx; 10672 avatars = GetLinkAvatars(linknumber);
10230 10673
10231 switch (code) 10674 remaining = new LSL_List();
10675 foreach (SceneObjectPart part in parts)
10232 { 10676 {
10233 case (int)ScriptBaseClass.PRIM_MATERIAL: 10677 remaining = GetPrimParams(part, rules, ref res);
10234 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 10678 }
10235 break; 10679 foreach (ScenePresence avatar in avatars)
10236 10680 {
10237 case (int)ScriptBaseClass.PRIM_PHYSICS: 10681 remaining = GetPrimParams(avatar, rules, ref res);
10238 res.Add(ScriptBaseClass.FALSE); 10682 }
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 10683
10380 return rules.GetSublist(idx, -1); 10684 if (remaining.Length > 0)
10685 {
10686 linknumber = remaining.GetLSLIntegerItem(0);
10687 rules = remaining.GetSublist(1, -1);
10381 } 10688 }
10689 else
10690 break;
10382 } 10691 }
10383 10692
10384 return new LSL_List(); 10693 return res;
10385 } 10694 }
10386 10695
10387 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 10696 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
@@ -10420,19 +10729,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10420 break; 10729 break;
10421 10730
10422 case (int)ScriptBaseClass.PRIM_POSITION: 10731 case (int)ScriptBaseClass.PRIM_POSITION:
10423 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 10732 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
10424 10733 part.AbsolutePosition.Y,
10425 // For some reason, the part.AbsolutePosition.* values do not change if the 10734 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); 10735 res.Add(v);
10437 break; 10736 break;
10438 10737
@@ -10541,7 +10840,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10541 Primitive.TextureEntry tex = part.Shape.Textures; 10840 Primitive.TextureEntry tex = part.Shape.Textures;
10542 if (face == ScriptBaseClass.ALL_SIDES) 10841 if (face == ScriptBaseClass.ALL_SIDES)
10543 { 10842 {
10544 for (face = 0 ; face < GetNumberOfSides(part); face++) 10843 for (face = 0; face < GetNumberOfSides(part); face++)
10545 { 10844 {
10546 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10845 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
10547 10846
@@ -10577,13 +10876,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10577 if (remain < 1) 10876 if (remain < 1)
10578 return new LSL_List(); 10877 return new LSL_List();
10579 10878
10580 face=(int)rules.GetLSLIntegerItem(idx++); 10879 face = (int)rules.GetLSLIntegerItem(idx++);
10581 10880
10582 tex = part.Shape.Textures; 10881 tex = part.Shape.Textures;
10583 Color4 texcolor; 10882 Color4 texcolor;
10584 if (face == ScriptBaseClass.ALL_SIDES) 10883 if (face == ScriptBaseClass.ALL_SIDES)
10585 { 10884 {
10586 for (face = 0 ; face < GetNumberOfSides(part); face++) 10885 for (face = 0; face < GetNumberOfSides(part); face++)
10587 { 10886 {
10588 texcolor = tex.GetFace((uint)face).RGBA; 10887 texcolor = tex.GetFace((uint)face).RGBA;
10589 res.Add(new LSL_Vector(texcolor.R, 10888 res.Add(new LSL_Vector(texcolor.R,
@@ -10606,30 +10905,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10606 if (remain < 1) 10905 if (remain < 1)
10607 return new LSL_List(); 10906 return new LSL_List();
10608 10907
10609 face=(int)rules.GetLSLIntegerItem(idx++); 10908 face = (int)rules.GetLSLIntegerItem(idx++);
10610 10909
10611 tex = part.Shape.Textures; 10910 tex = part.Shape.Textures;
10911 int shiny;
10612 if (face == ScriptBaseClass.ALL_SIDES) 10912 if (face == ScriptBaseClass.ALL_SIDES)
10613 { 10913 {
10614 for (face = 0; face < GetNumberOfSides(part); face++) 10914 for (face = 0; face < GetNumberOfSides(part); face++)
10615 { 10915 {
10616 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10916 Shininess shinyness = tex.GetFace((uint)face).Shiny;
10617 // Convert Shininess to PRIM_SHINY_* 10917 if (shinyness == Shininess.High)
10618 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 10918 {
10619 // PRIM_BUMP_* 10919 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
10620 res.Add(new LSL_Integer((int)texface.Bump)); 10920 }
10921 else if (shinyness == Shininess.Medium)
10922 {
10923 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
10924 }
10925 else if (shinyness == Shininess.Low)
10926 {
10927 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
10928 }
10929 else
10930 {
10931 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
10932 }
10933 res.Add(new LSL_Integer(shiny));
10934 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
10621 } 10935 }
10622 } 10936 }
10623 else 10937 else
10624 { 10938 {
10625 if (face >= 0 && face < GetNumberOfSides(part)) 10939 Shininess shinyness = tex.GetFace((uint)face).Shiny;
10940 if (shinyness == Shininess.High)
10626 { 10941 {
10627 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10942 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
10628 // Convert Shininess to PRIM_SHINY_* 10943 }
10629 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 10944 else if (shinyness == Shininess.Medium)
10630 // PRIM_BUMP_* 10945 {
10631 res.Add(new LSL_Integer((int)texface.Bump)); 10946 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
10947 }
10948 else if (shinyness == Shininess.Low)
10949 {
10950 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
10951 }
10952 else
10953 {
10954 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
10632 } 10955 }
10956 res.Add(new LSL_Integer(shiny));
10957 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
10633 } 10958 }
10634 break; 10959 break;
10635 10960
@@ -10640,21 +10965,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10640 face = (int)rules.GetLSLIntegerItem(idx++); 10965 face = (int)rules.GetLSLIntegerItem(idx++);
10641 10966
10642 tex = part.Shape.Textures; 10967 tex = part.Shape.Textures;
10968 int fullbright;
10643 if (face == ScriptBaseClass.ALL_SIDES) 10969 if (face == ScriptBaseClass.ALL_SIDES)
10644 { 10970 {
10645 for (face = 0; face < GetNumberOfSides(part); face++) 10971 for (face = 0; face < GetNumberOfSides(part); face++)
10646 { 10972 {
10647 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10973 if (tex.GetFace((uint)face).Fullbright == true)
10648 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 10974 {
10975 fullbright = ScriptBaseClass.TRUE;
10976 }
10977 else
10978 {
10979 fullbright = ScriptBaseClass.FALSE;
10980 }
10981 res.Add(new LSL_Integer(fullbright));
10649 } 10982 }
10650 } 10983 }
10651 else 10984 else
10652 { 10985 {
10653 if (face >= 0 && face < GetNumberOfSides(part)) 10986 if (tex.GetFace((uint)face).Fullbright == true)
10654 { 10987 {
10655 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10988 fullbright = ScriptBaseClass.TRUE;
10656 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 10989 }
10990 else
10991 {
10992 fullbright = ScriptBaseClass.FALSE;
10657 } 10993 }
10994 res.Add(new LSL_Integer(fullbright));
10658 } 10995 }
10659 break; 10996 break;
10660 10997
@@ -10676,27 +11013,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10676 break; 11013 break;
10677 11014
10678 case (int)ScriptBaseClass.PRIM_TEXGEN: 11015 case (int)ScriptBaseClass.PRIM_TEXGEN:
11016 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
10679 if (remain < 1) 11017 if (remain < 1)
10680 return new LSL_List(); 11018 return new LSL_List();
10681 11019
10682 face=(int)rules.GetLSLIntegerItem(idx++); 11020 face = (int)rules.GetLSLIntegerItem(idx++);
10683 11021
10684 tex = part.Shape.Textures; 11022 tex = part.Shape.Textures;
10685 if (face == ScriptBaseClass.ALL_SIDES) 11023 if (face == ScriptBaseClass.ALL_SIDES)
10686 { 11024 {
10687 for (face = 0; face < GetNumberOfSides(part); face++) 11025 for (face = 0; face < GetNumberOfSides(part); face++)
10688 { 11026 {
10689 MappingType texgen = tex.GetFace((uint)face).TexMapType; 11027 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
10690 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 11028 {
10691 res.Add(new LSL_Integer((uint)texgen >> 1)); 11029 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
11030 }
11031 else
11032 {
11033 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
11034 }
10692 } 11035 }
10693 } 11036 }
10694 else 11037 else
10695 { 11038 {
10696 if (face >= 0 && face < GetNumberOfSides(part)) 11039 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
10697 { 11040 {
10698 MappingType texgen = tex.GetFace((uint)face).TexMapType; 11041 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
10699 res.Add(new LSL_Integer((uint)texgen >> 1)); 11042 }
11043 else
11044 {
11045 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
10700 } 11046 }
10701 } 11047 }
10702 break; 11048 break;
@@ -10720,24 +11066,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10720 if (remain < 1) 11066 if (remain < 1)
10721 return new LSL_List(); 11067 return new LSL_List();
10722 11068
10723 face=(int)rules.GetLSLIntegerItem(idx++); 11069 face = (int)rules.GetLSLIntegerItem(idx++);
10724 11070
10725 tex = part.Shape.Textures; 11071 tex = part.Shape.Textures;
11072 float primglow;
10726 if (face == ScriptBaseClass.ALL_SIDES) 11073 if (face == ScriptBaseClass.ALL_SIDES)
10727 { 11074 {
10728 for (face = 0; face < GetNumberOfSides(part); face++) 11075 for (face = 0; face < GetNumberOfSides(part); face++)
10729 { 11076 {
10730 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 11077 primglow = tex.GetFace((uint)face).Glow;
10731 res.Add(new LSL_Float(texface.Glow)); 11078 res.Add(new LSL_Float(primglow));
10732 } 11079 }
10733 } 11080 }
10734 else 11081 else
10735 { 11082 {
10736 if (face >= 0 && face < GetNumberOfSides(part)) 11083 primglow = tex.GetFace((uint)face).Glow;
10737 { 11084 res.Add(new LSL_Float(primglow));
10738 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
10739 res.Add(new LSL_Float(texface.Glow));
10740 }
10741 } 11085 }
10742 break; 11086 break;
10743 11087
@@ -10747,17 +11091,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10747 res.Add(new LSL_Vector(textColor.R, 11091 res.Add(new LSL_Vector(textColor.R,
10748 textColor.G, 11092 textColor.G,
10749 textColor.B)); 11093 textColor.B));
10750 res.Add(new LSL_Float(1.0 - textColor.A)); 11094 res.Add(new LSL_Float(textColor.A));
10751 break; 11095 break;
11096
10752 case (int)ScriptBaseClass.PRIM_NAME: 11097 case (int)ScriptBaseClass.PRIM_NAME:
10753 res.Add(new LSL_String(part.Name)); 11098 res.Add(new LSL_String(part.Name));
10754 break; 11099 break;
11100
10755 case (int)ScriptBaseClass.PRIM_DESC: 11101 case (int)ScriptBaseClass.PRIM_DESC:
10756 res.Add(new LSL_String(part.Description)); 11102 res.Add(new LSL_String(part.Description));
10757 break; 11103 break;
10758 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 11104 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
10759 res.Add(new LSL_Rotation(part.RotationOffset)); 11105 res.Add(new LSL_Rotation(part.RotationOffset));
10760 break; 11106 break;
11107
10761 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 11108 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
10762 res.Add(new LSL_Vector(GetPartLocalPos(part))); 11109 res.Add(new LSL_Vector(GetPartLocalPos(part)));
10763 break; 11110 break;
@@ -10783,6 +11130,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10783 return new LSL_List(); 11130 return new LSL_List();
10784 } 11131 }
10785 11132
11133
10786 public LSL_List llGetPrimMediaParams(int face, LSL_List rules) 11134 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
10787 { 11135 {
10788 m_host.AddScriptLPS(1); 11136 m_host.AddScriptLPS(1);
@@ -11370,8 +11718,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11370 // The function returns an ordered list 11718 // The function returns an ordered list
11371 // representing the tokens found in the supplied 11719 // representing the tokens found in the supplied
11372 // sources string. If two successive tokenizers 11720 // sources string. If two successive tokenizers
11373 // are encountered, then a NULL entry is added 11721 // are encountered, then a null-string entry is
11374 // to the list. 11722 // added to the list.
11375 // 11723 //
11376 // It is a precondition that the source and 11724 // It is a precondition that the source and
11377 // toekizer lisst are non-null. If they are null, 11725 // toekizer lisst are non-null. If they are null,
@@ -11379,7 +11727,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11379 // while their lengths are being determined. 11727 // while their lengths are being determined.
11380 // 11728 //
11381 // A small amount of working memoryis required 11729 // A small amount of working memoryis required
11382 // of approximately 8*#tokenizers. 11730 // of approximately 8*#tokenizers + 8*srcstrlen.
11383 // 11731 //
11384 // There are many ways in which this function 11732 // There are many ways in which this function
11385 // can be implemented, this implementation is 11733 // can be implemented, this implementation is
@@ -11395,155 +11743,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11395 // and eliminates redundant tokenizers as soon 11743 // and eliminates redundant tokenizers as soon
11396 // as is possible. 11744 // as is possible.
11397 // 11745 //
11398 // The implementation tries to avoid any copying 11746 // The implementation tries to minimize temporary
11399 // of arrays or other objects. 11747 // garbage generation.
11400 // </remarks> 11748 // </remarks>
11401 11749
11402 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 11750 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
11403 { 11751 {
11404 int beginning = 0; 11752 return ParseString2List(src, separators, spacers, true);
11405 int srclen = src.Length; 11753 }
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 11754
11420 LSL_List tokens = new LSL_List(); 11755 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
11756 {
11757 int srclen = src.Length;
11758 int seplen = separators.Length;
11759 object[] separray = separators.Data;
11760 int spclen = spacers.Length;
11761 object[] spcarray = spacers.Data;
11762 int dellen = 0;
11763 string[] delarray = new string[seplen+spclen];
11421 11764
11422 // All entries are initially valid 11765 int outlen = 0;
11766 string[] outarray = new string[srclen*2+1];
11423 11767
11424 for (int i = 0; i < mlen; i++) 11768 int i, j;
11425 active[i] = true; 11769 string d;
11426 11770
11427 offset[mlen] = srclen; 11771 m_host.AddScriptLPS(1);
11428 11772
11429 while (beginning < srclen) 11773 /*
11774 * Convert separator and spacer lists to C# strings.
11775 * Also filter out null strings so we don't hang.
11776 */
11777 for (i = 0; i < seplen; i ++)
11430 { 11778 {
11779 d = separray[i].ToString();
11780 if (d.Length > 0)
11781 {
11782 delarray[dellen++] = d;
11783 }
11784 }
11785 seplen = dellen;
11431 11786
11432 best = mlen; // as bad as it gets 11787 for (i = 0; i < spclen; i ++)
11788 {
11789 d = spcarray[i].ToString();
11790 if (d.Length > 0)
11791 {
11792 delarray[dellen++] = d;
11793 }
11794 }
11433 11795
11434 // Scan for separators 11796 /*
11797 * Scan through source string from beginning to end.
11798 */
11799 for (i = 0;;)
11800 {
11435 11801
11436 for (j = 0; j < seplen; j++) 11802 /*
11803 * Find earliest delimeter in src starting at i (if any).
11804 */
11805 int earliestDel = -1;
11806 int earliestSrc = srclen;
11807 string earliestStr = null;
11808 for (j = 0; j < dellen; j ++)
11437 { 11809 {
11438 if (separray[j].ToString() == String.Empty) 11810 d = delarray[j];
11439 active[j] = false; 11811 if (d != null)
11440
11441 if (active[j])
11442 { 11812 {
11443 // scan all of the markers 11813 int index = src.IndexOf(d, i);
11444 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 11814 if (index < 0)
11445 { 11815 {
11446 // not present at all 11816 delarray[j] = null; // delim nowhere in src, don't check it anymore
11447 active[j] = false;
11448 } 11817 }
11449 else 11818 else if (index < earliestSrc)
11450 { 11819 {
11451 // present and correct 11820 earliestSrc = index; // where delimeter starts in source string
11452 if (offset[j] < offset[best]) 11821 earliestDel = j; // where delimeter is in delarray[]
11453 { 11822 earliestStr = d; // the delimeter string from delarray[]
11454 // closest so far 11823 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 } 11824 }
11460 } 11825 }
11461 } 11826 }
11462 11827
11463 // Scan for spacers 11828 /*
11464 11829 * Output source string starting at i through start of earliest delimeter.
11465 if (offset[best] != beginning) 11830 */
11831 if (keepNulls || (earliestSrc > i))
11466 { 11832 {
11467 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 11833 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 } 11834 }
11492 11835
11493 // This is the normal exit from the scanning loop 11836 /*
11837 * If no delimeter found at or after i, we're done scanning.
11838 */
11839 if (earliestDel < 0) break;
11494 11840
11495 if (best == mlen) 11841 /*
11842 * If delimeter was a spacer, output the spacer.
11843 */
11844 if (earliestDel >= seplen)
11496 { 11845 {
11497 // no markers were found on this pass 11846 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 } 11847 }
11503 11848
11504 // Otherwise we just add the newly delimited token 11849 /*
11505 // and recalculate where the search should continue. 11850 * Look at rest of src string following delimeter.
11506 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 11851 */
11507 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 11852 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 } 11853 }
11521 11854
11522 // This an awkward an not very intuitive boundary case. If the 11855 /*
11523 // last substring is a tokenizer, then there is an implied trailing 11856 * 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 11857 */
11525 // arduous. Alternatively the 'break' could be replced with a return 11858 object[] outlist = new object[outlen];
11526 // but that's shabby programming. 11859 for (i = 0; i < outlen; i ++)
11527
11528 if ((beginning == srclen) && (keepNulls))
11529 { 11860 {
11530 if (srclen != 0) 11861 outlist[i] = new LSL_String(outarray[i]);
11531 tokens.Add(new LSL_String(""));
11532 } 11862 }
11533 11863 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 } 11864 }
11548 11865
11549 public LSL_Integer llGetObjectPermMask(int mask) 11866 public LSL_Integer llGetObjectPermMask(int mask)
@@ -11841,31 +12158,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11841 UUID key = new UUID(); 12158 UUID key = new UUID();
11842 if (UUID.TryParse(id, out key)) 12159 if (UUID.TryParse(id, out key))
11843 { 12160 {
11844 try 12161 // return total object mass
11845 { 12162 SceneObjectPart part = World.GetSceneObjectPart(key);
11846 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 12163 if (part != null)
11847 if (obj != null) 12164 return part.ParentGroup.GetMass();
11848 return (double)obj.GetMass(); 12165
11849 // the object is null so the key is for an avatar 12166 // the object is null so the key is for an avatar
11850 ScenePresence avatar = World.GetScenePresence(key); 12167 ScenePresence avatar = World.GetScenePresence(key);
11851 if (avatar != null) 12168 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 { 12169 {
11861 return 0; // The Object/Agent not in the region so just return zero 12170 if (avatar.IsChildAgent)
12171 {
12172 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
12173 // child agents have a mass of 1.0
12174 return 1;
12175 }
12176 else
12177 {
12178 return (double)avatar.GetMass();
12179 }
11862 } 12180 }
11863 } 12181 }
11864 return 0; 12182 return 0;
11865 } 12183 }
11866 12184
11867 /// <summary> 12185 /// <summary>
11868 /// illListReplaceList removes the sub-list defined by the inclusive indices 12186 /// llListReplaceList removes the sub-list defined by the inclusive indices
11869 /// start and end and inserts the src list in its place. The inclusive 12187 /// 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 12188 /// 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 12189 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -11922,16 +12240,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11922 // based upon end. Note that if end exceeds the upper 12240 // based upon end. Note that if end exceeds the upper
11923 // bound in this case, the entire destination list 12241 // bound in this case, the entire destination list
11924 // is removed. 12242 // is removed.
11925 else 12243 else if (start == 0)
11926 { 12244 {
11927 if (end + 1 < dest.Length) 12245 if (end + 1 < dest.Length)
11928 {
11929 return src + dest.GetSublist(end + 1, -1); 12246 return src + dest.GetSublist(end + 1, -1);
11930 }
11931 else 12247 else
11932 {
11933 return src; 12248 return src;
11934 } 12249 }
12250 else // Start < 0
12251 {
12252 if (end + 1 < dest.Length)
12253 return dest.GetSublist(end + 1, -1);
12254 else
12255 return new LSL_List();
11935 } 12256 }
11936 } 12257 }
11937 // Finally, if start > end, we strip away a prefix and 12258 // Finally, if start > end, we strip away a prefix and
@@ -11968,7 +12289,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 12289 // 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. 12290 // lets add estate owners and gods, too, and use the generic permission check.
11970 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 12291 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
11971 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; 12292 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia, false)) return;
11972 12293
11973 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? 12294 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)?
11974 byte loop = 0; 12295 byte loop = 0;
@@ -12186,16 +12507,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12186 if (sp.currentParcelUUID == landData.GlobalID) 12507 if (sp.currentParcelUUID == landData.GlobalID)
12187 { 12508 {
12188 sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? 12509 sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
12189 (ParcelMediaCommandEnum)commandToSend, 12510 (ParcelMediaCommandEnum)commandToSend, time);
12190 time);
12191 } 12511 }
12192 }); 12512 });
12193 } 12513 }
12194 else if (!presence.IsChildAgent) 12514 else if (!presence.IsChildAgent)
12195 { 12515 {
12196 presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? 12516 presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
12197 (ParcelMediaCommandEnum)commandToSend, 12517 (ParcelMediaCommandEnum)commandToSend, time);
12198 time);
12199 } 12518 }
12200 } 12519 }
12201 ScriptSleep(m_sleepMsOnParcelMediaCommandList); 12520 ScriptSleep(m_sleepMsOnParcelMediaCommandList);
@@ -12212,7 +12531,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12212 12531
12213 if (aList.Data[i] != null) 12532 if (aList.Data[i] != null)
12214 { 12533 {
12215 switch ((ParcelMediaCommandEnum) aList.Data[i]) 12534 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
12216 { 12535 {
12217 case ParcelMediaCommandEnum.Url: 12536 case ParcelMediaCommandEnum.Url:
12218 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 12537 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -12269,15 +12588,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12269 12588
12270 if (quick_pay_buttons.Data.Length < 4) 12589 if (quick_pay_buttons.Data.Length < 4)
12271 { 12590 {
12272 Error("llSetPayPrice", "List must have at least 4 elements"); 12591 int x;
12273 return; 12592 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
12593 {
12594 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
12595 }
12274 } 12596 }
12275 m_host.ParentGroup.RootPart.PayPrice[0]=price; 12597 int[] nPrice = new int[5];
12276 12598 nPrice[0] = price;
12277 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 12599 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
12278 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 12600 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
12279 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 12601 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
12280 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 12602 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
12603 m_host.ParentGroup.RootPart.PayPrice = nPrice;
12281 m_host.ParentGroup.HasGroupChanged = true; 12604 m_host.ParentGroup.HasGroupChanged = true;
12282 } 12605 }
12283 12606
@@ -12294,7 +12617,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12294 return Vector3.Zero; 12617 return Vector3.Zero;
12295 } 12618 }
12296 12619
12297 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 12620// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
12621 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
12298 if (presence != null) 12622 if (presence != null)
12299 { 12623 {
12300 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 12624 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
@@ -12317,7 +12641,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12317 return Quaternion.Identity; 12641 return Quaternion.Identity;
12318 } 12642 }
12319 12643
12320 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 12644// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
12645 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
12321 if (presence != null) 12646 if (presence != null)
12322 { 12647 {
12323 return new LSL_Rotation(presence.CameraRotation); 12648 return new LSL_Rotation(presence.CameraRotation);
@@ -12370,8 +12695,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12370 { 12695 {
12371 m_host.AddScriptLPS(1); 12696 m_host.AddScriptLPS(1);
12372 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 12697 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
12373 if (detectedParams == null) return; // only works on the first detected avatar 12698 if (detectedParams == null)
12374 12699 {
12700 if (m_host.ParentGroup.IsAttachment == true)
12701 {
12702 detectedParams = new DetectParams();
12703 detectedParams.Key = m_host.OwnerID;
12704 }
12705 else
12706 {
12707 return;
12708 }
12709 }
12710
12375 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 12711 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
12376 if (avatar != null) 12712 if (avatar != null)
12377 { 12713 {
@@ -12386,7 +12722,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12386 m_host.AddScriptLPS(1); 12722 m_host.AddScriptLPS(1);
12387 UUID key; 12723 UUID key;
12388 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 12724 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
12389 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 12725 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false))
12390 { 12726 {
12391 int expires = 0; 12727 int expires = 0;
12392 if (hours != 0) 12728 if (hours != 0)
@@ -12427,7 +12763,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12427 m_host.AddScriptLPS(1); 12763 m_host.AddScriptLPS(1);
12428 UUID key; 12764 UUID key;
12429 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 12765 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
12430 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) 12766 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed, false))
12431 { 12767 {
12432 if (UUID.TryParse(avatar, out key)) 12768 if (UUID.TryParse(avatar, out key))
12433 { 12769 {
@@ -12454,7 +12790,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12454 m_host.AddScriptLPS(1); 12790 m_host.AddScriptLPS(1);
12455 UUID key; 12791 UUID key;
12456 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 12792 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
12457 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 12793 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false))
12458 { 12794 {
12459 if (UUID.TryParse(avatar, out key)) 12795 if (UUID.TryParse(avatar, out key))
12460 { 12796 {
@@ -12686,19 +13022,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12686 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 13022 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
12687 { 13023 {
12688 m_host.AddScriptLPS(1); 13024 m_host.AddScriptLPS(1);
12689 string ret = String.Empty; 13025
12690 string src1 = llBase64ToString(str1); 13026 if (str1 == String.Empty)
12691 string src2 = llBase64ToString(str2); 13027 return String.Empty;
12692 int c = 0; 13028 if (str2 == String.Empty)
12693 for (int i = 0; i < src1.Length; i++) 13029 return str1;
13030
13031 int len = str2.Length;
13032 if ((len % 4) != 0) // LL is EVIL!!!!
13033 {
13034 while (str2.EndsWith("="))
13035 str2 = str2.Substring(0, str2.Length - 1);
13036
13037 len = str2.Length;
13038 int mod = len % 4;
13039
13040 if (mod == 1)
13041 str2 = str2.Substring(0, str2.Length - 1);
13042 else if (mod == 2)
13043 str2 += "==";
13044 else if (mod == 3)
13045 str2 += "=";
13046 }
13047
13048 byte[] data1;
13049 byte[] data2;
13050 try
12694 { 13051 {
12695 ret += (char) (src1[i] ^ src2[c]); 13052 data1 = Convert.FromBase64String(str1);
13053 data2 = Convert.FromBase64String(str2);
13054 }
13055 catch (Exception)
13056 {
13057 return new LSL_String(String.Empty);
13058 }
12696 13059
12697 c++; 13060 byte[] d2 = new Byte[data1.Length];
12698 if (c >= src2.Length) 13061 int pos = 0;
12699 c = 0; 13062
13063 if (data1.Length <= data2.Length)
13064 {
13065 Array.Copy(data2, 0, d2, 0, data1.Length);
12700 } 13066 }
12701 return llStringToBase64(ret); 13067 else
13068 {
13069 while (pos < data1.Length)
13070 {
13071 len = data1.Length - pos;
13072 if (len > data2.Length)
13073 len = data2.Length;
13074
13075 Array.Copy(data2, 0, d2, pos, len);
13076 pos += len;
13077 }
13078 }
13079
13080 for (pos = 0 ; pos < data1.Length ; pos++ )
13081 data1[pos] ^= d2[pos];
13082
13083 return Convert.ToBase64String(data1);
12702 } 13084 }
12703 13085
12704 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 13086 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -12802,16 +13184,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12802 if (userAgent != null) 13184 if (userAgent != null)
12803 httpHeaders["User-Agent"] = userAgent; 13185 httpHeaders["User-Agent"] = userAgent;
12804 13186
13187 // See if the URL contains any header hacks
13188 string[] urlParts = url.Split(new char[] {'\n'});
13189 if (urlParts.Length > 1)
13190 {
13191 // Iterate the passed headers and parse them
13192 for (int i = 1 ; i < urlParts.Length ; i++ )
13193 {
13194 // The rest of those would be added to the body in SL.
13195 // Let's not do that.
13196 if (urlParts[i] == String.Empty)
13197 break;
13198
13199 // See if this could be a valid header
13200 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
13201 if (headerParts.Length != 2)
13202 continue;
13203
13204 string headerName = headerParts[0].Trim();
13205 string headerValue = headerParts[1].Trim();
13206
13207 // Filter out headers that could be used to abuse
13208 // another system or cloak the request
13209 if (headerName.ToLower() == "x-secondlife-shard" ||
13210 headerName.ToLower() == "x-secondlife-object-name" ||
13211 headerName.ToLower() == "x-secondlife-object-key" ||
13212 headerName.ToLower() == "x-secondlife-region" ||
13213 headerName.ToLower() == "x-secondlife-local-position" ||
13214 headerName.ToLower() == "x-secondlife-local-velocity" ||
13215 headerName.ToLower() == "x-secondlife-local-rotation" ||
13216 headerName.ToLower() == "x-secondlife-owner-name" ||
13217 headerName.ToLower() == "x-secondlife-owner-key" ||
13218 headerName.ToLower() == "connection" ||
13219 headerName.ToLower() == "content-length" ||
13220 headerName.ToLower() == "from" ||
13221 headerName.ToLower() == "host" ||
13222 headerName.ToLower() == "proxy-authorization" ||
13223 headerName.ToLower() == "referer" ||
13224 headerName.ToLower() == "trailer" ||
13225 headerName.ToLower() == "transfer-encoding" ||
13226 headerName.ToLower() == "via" ||
13227 headerName.ToLower() == "authorization")
13228 continue;
13229
13230 httpHeaders[headerName] = headerValue;
13231 }
13232
13233 // Finally, strip any protocol specifier from the URL
13234 url = urlParts[0].Trim();
13235 int idx = url.IndexOf(" HTTP/");
13236 if (idx != -1)
13237 url = url.Substring(0, idx);
13238 }
13239
12805 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 13240 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
12806 Regex r = new Regex(authregex); 13241 Regex r = new Regex(authregex);
12807 int[] gnums = r.GetGroupNumbers(); 13242 int[] gnums = r.GetGroupNumbers();
12808 Match m = r.Match(url); 13243 Match m = r.Match(url);
12809 if (m.Success) { 13244 if (m.Success)
12810 for (int i = 1; i < gnums.Length; i++) { 13245 {
13246 for (int i = 1; i < gnums.Length; i++)
13247 {
12811 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 13248 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
12812 //CaptureCollection cc = g.Captures; 13249 //CaptureCollection cc = g.Captures;
12813 } 13250 }
12814 if (m.Groups.Count == 5) { 13251 if (m.Groups.Count == 5)
13252 {
12815 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 13253 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(); 13254 url = m.Groups[1].ToString() + m.Groups[4].ToString();
12817 } 13255 }
@@ -13018,6 +13456,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13018 13456
13019 LSL_List ret = new LSL_List(); 13457 LSL_List ret = new LSL_List();
13020 UUID key = new UUID(); 13458 UUID key = new UUID();
13459
13460
13021 if (UUID.TryParse(id, out key)) 13461 if (UUID.TryParse(id, out key))
13022 { 13462 {
13023 ScenePresence av = World.GetScenePresence(key); 13463 ScenePresence av = World.GetScenePresence(key);
@@ -13035,13 +13475,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13035 ret.Add(new LSL_String("")); 13475 ret.Add(new LSL_String(""));
13036 break; 13476 break;
13037 case ScriptBaseClass.OBJECT_POS: 13477 case ScriptBaseClass.OBJECT_POS:
13038 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 13478 Vector3 avpos;
13479
13480 if (av.ParentID != 0 && av.ParentPart != null &&
13481 av.ParentPart.ParentGroup != null && av.ParentPart.ParentGroup.RootPart != null )
13482 {
13483 avpos = av.OffsetPosition;
13484
13485 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
13486 avpos -= sitOffset;
13487 SceneObjectPart sitRoot = av.ParentPart.ParentGroup.RootPart;
13488 avpos = sitRoot.GetWorldPosition() + avpos * sitRoot.GetWorldRotation();
13489 }
13490 else
13491 avpos = av.AbsolutePosition;
13492
13493 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
13039 break; 13494 break;
13040 case ScriptBaseClass.OBJECT_ROT: 13495 case ScriptBaseClass.OBJECT_ROT:
13041 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 13496 Quaternion avrot = av.GetWorldRotation();
13497 ret.Add(new LSL_Rotation(avrot));
13042 break; 13498 break;
13043 case ScriptBaseClass.OBJECT_VELOCITY: 13499 case ScriptBaseClass.OBJECT_VELOCITY:
13044 ret.Add(new LSL_Vector(av.GetWorldVelocity())); 13500 Vector3 avvel = av.GetWorldVelocity();
13501 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
13045 break; 13502 break;
13046 case ScriptBaseClass.OBJECT_OWNER: 13503 case ScriptBaseClass.OBJECT_OWNER:
13047 ret.Add(new LSL_String(id)); 13504 ret.Add(new LSL_String(id));
@@ -13143,11 +13600,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13143 case ScriptBaseClass.OBJECT_NAME: 13600 case ScriptBaseClass.OBJECT_NAME:
13144 ret.Add(new LSL_String(obj.Name)); 13601 ret.Add(new LSL_String(obj.Name));
13145 break; 13602 break;
13146 case ScriptBaseClass.OBJECT_DESC: 13603 case ScriptBaseClass.OBJECT_DESC:
13147 ret.Add(new LSL_String(obj.Description)); 13604 ret.Add(new LSL_String(obj.Description));
13148 break; 13605 break;
13149 case ScriptBaseClass.OBJECT_POS: 13606 case ScriptBaseClass.OBJECT_POS:
13150 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 13607 Vector3 opos = obj.AbsolutePosition;
13608 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
13151 break; 13609 break;
13152 case ScriptBaseClass.OBJECT_ROT: 13610 case ScriptBaseClass.OBJECT_ROT:
13153 Quaternion rot = Quaternion.Identity; 13611 Quaternion rot = Quaternion.Identity;
@@ -13220,9 +13678,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13220 // The value returned in SL for normal prims is prim count 13678 // The value returned in SL for normal prims is prim count
13221 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 13679 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
13222 break; 13680 break;
13223 // The following 3 costs I have intentionaly coded to return zero. They are part of 13681
13224 // "Land Impact" calculations. These calculations are probably not applicable 13682 // 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: 13683 case ScriptBaseClass.OBJECT_SERVER_COST:
13227 // The linden calculation is here 13684 // The linden calculation is here
13228 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 13685 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -13230,16 +13687,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13230 ret.Add(new LSL_Float(0)); 13687 ret.Add(new LSL_Float(0));
13231 break; 13688 break;
13232 case ScriptBaseClass.OBJECT_STREAMING_COST: 13689 case ScriptBaseClass.OBJECT_STREAMING_COST:
13233 // The linden calculation is here 13690 // The value returned in SL for normal prims is prim count * 0.06
13234 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 13691 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; 13692 break;
13238 case ScriptBaseClass.OBJECT_PHYSICS_COST: 13693 case ScriptBaseClass.OBJECT_PHYSICS_COST:
13239 // The linden calculation is here 13694 // The value returned in SL for normal prims is prim count
13240 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 13695 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; 13696 break;
13244 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 13697 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
13245 ret.Add(new LSL_Float(0)); 13698 ret.Add(new LSL_Float(0));
@@ -13522,12 +13975,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13522 13975
13523 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 13976 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
13524 { 13977 {
13525 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 13978 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
13979
13980 LSL_List result = new LSL_List();
13526 13981
13527 if (obj != null && obj.OwnerID == m_host.OwnerID) 13982 if (obj != null && obj.OwnerID == m_host.OwnerID)
13528 return GetEntityParams(obj, rules); 13983 {
13984 LSL_List remaining = GetPrimParams(obj, rules, ref result);
13529 13985
13530 return new LSL_List(); 13986 while (remaining.Length > 2)
13987 {
13988 int linknumber = remaining.GetLSLIntegerItem(0);
13989 rules = remaining.GetSublist(1, -1);
13990 List<SceneObjectPart> parts = GetLinkParts(linknumber);
13991
13992 foreach (SceneObjectPart part in parts)
13993 remaining = GetPrimParams(part, rules, ref result);
13994 }
13995 }
13996
13997 return result;
13531 } 13998 }
13532 13999
13533 public void print(string str) 14000 public void print(string str)
@@ -13539,6 +14006,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13539 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 14006 ossl.CheckThreatLevel(ThreatLevel.High, "print");
13540 m_log.Info("LSL print():" + str); 14007 m_log.Info("LSL print():" + str);
13541 } 14008 }
14009 }
14010
14011 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
14012 {
14013 List<SceneObjectPart> parts = GetLinkParts(link);
14014 if (parts.Count < 1)
14015 return 0;
14016
14017 return GetNumberOfSides(parts[0]);
13542 } 14018 }
13543 14019
13544 private string Name2Username(string name) 14020 private string Name2Username(string name)
@@ -13583,7 +14059,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13583 14059
13584 return rq.ToString(); 14060 return rq.ToString();
13585 } 14061 }
13586 14062/*
14063 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
14064 {
14065 m_SayShoutCount = 0;
14066 }
14067*/
13587 private struct Tri 14068 private struct Tri
13588 { 14069 {
13589 public Vector3 p1; 14070 public Vector3 p1;
@@ -13732,9 +14213,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13732 14213
13733 ContactResult result = new ContactResult (); 14214 ContactResult result = new ContactResult ();
13734 result.ConsumerID = group.LocalId; 14215 result.ConsumerID = group.LocalId;
13735 result.Depth = intersection.distance; 14216// result.Depth = intersection.distance;
13736 result.Normal = intersection.normal; 14217 result.Normal = intersection.normal;
13737 result.Pos = intersection.ipoint; 14218 result.Pos = intersection.ipoint;
14219 result.Depth = Vector3.Mag(rayStart - result.Pos);
13738 14220
13739 contacts.Add(result); 14221 contacts.Add(result);
13740 }); 14222 });
@@ -13867,6 +14349,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13867 14349
13868 return contacts[0]; 14350 return contacts[0];
13869 } 14351 }
14352/*
14353 // not done:
14354 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
14355 {
14356 ContactResult[] contacts = null;
14357 World.ForEachSOG(delegate(SceneObjectGroup group)
14358 {
14359 if (m_host.ParentGroup == group)
14360 return;
14361
14362 if (group.IsAttachment)
14363 return;
14364
14365 if(group.RootPart.PhysActor != null)
14366 return;
14367
14368 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
14369 });
14370 return contacts;
14371 }
14372*/
13870 14373
13871 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 14374 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
13872 { 14375 {
@@ -13917,7 +14420,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13917 if (dist == 0) 14420 if (dist == 0)
13918 return list; 14421 return list;
13919 14422
13920 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull; 14423 RayFilterFlags rayfilter = RayFilterFlags.BackFaceCull;
13921 if (checkTerrain) 14424 if (checkTerrain)
13922 rayfilter |= RayFilterFlags.land; 14425 rayfilter |= RayFilterFlags.land;
13923// if (checkAgents) 14426// if (checkAgents)
@@ -13994,18 +14497,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13994 } 14497 }
13995 } 14498 }
13996 14499
14500 // Double check this
13997 if (checkTerrain) 14501 if (checkTerrain)
13998 { 14502 {
13999 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 14503 bool skipGroundCheck = false;
14000 if (groundContact != null) 14504
14001 results.Add((ContactResult)groundContact); 14505 foreach (ContactResult c in results)
14506 {
14507 if (c.ConsumerID == 0) // Physics gave us a ground collision
14508 skipGroundCheck = true;
14509 }
14510
14511 if (!skipGroundCheck)
14512 {
14513 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
14514 if (groundContact != null)
14515 results.Add((ContactResult)groundContact);
14516 }
14002 } 14517 }
14003 14518
14004 results.Sort(delegate(ContactResult a, ContactResult b) 14519 results.Sort(delegate(ContactResult a, ContactResult b)
14005 { 14520 {
14006 return a.Depth.CompareTo(b.Depth); 14521 return a.Depth.CompareTo(b.Depth);
14007 }); 14522 });
14008 14523
14009 int values = 0; 14524 int values = 0;
14010 SceneObjectGroup thisgrp = m_host.ParentGroup; 14525 SceneObjectGroup thisgrp = m_host.ParentGroup;
14011 14526
@@ -14062,6 +14577,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14062 14577
14063 return list; 14578 return list;
14064 } 14579 }
14580
14065 14581
14066 /// <summary> 14582 /// <summary>
14067 /// Implementation of llCastRay similar to SL 2015-04-21. 14583 /// Implementation of llCastRay similar to SL 2015-04-21.
@@ -14086,7 +14602,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14086 UUID userId = UUID.Zero; 14602 UUID userId = UUID.Zero;
14087 int msAvailable = 0; 14603 int msAvailable = 0;
14088 // Throttle per owner when attachment or "vehicle" (sat upon) 14604 // Throttle per owner when attachment or "vehicle" (sat upon)
14089 if (m_host.ParentGroup.IsAttachment || m_host.ParentGroup.GetSittingAvatars().Count > 0) 14605 if (m_host.ParentGroup.IsAttachment || m_host.ParentGroup.GetSittingAvatarsCount() > 0)
14090 { 14606 {
14091 userId = m_host.OwnerID; 14607 userId = m_host.OwnerID;
14092 msAvailable = m_msPerAvatarInCastRay; 14608 msAvailable = m_msPerAvatarInCastRay;
@@ -14964,7 +15480,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14964 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 15480 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
14965 if (!isAccount) return 0; 15481 if (!isAccount) return 0;
14966 if (estate.HasAccess(id)) return 1; 15482 if (estate.HasAccess(id)) return 1;
14967 if (estate.IsBanned(id)) 15483 if (estate.IsBanned(id, World.GetUserFlags(id)))
14968 estate.RemoveBan(id); 15484 estate.RemoveBan(id);
14969 estate.AddEstateUser(id); 15485 estate.AddEstateUser(id);
14970 break; 15486 break;
@@ -14983,14 +15499,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14983 break; 15499 break;
14984 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 15500 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
14985 if (!isAccount) return 0; 15501 if (!isAccount) return 0;
14986 if (estate.IsBanned(id)) return 1; 15502 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
14987 EstateBan ban = new EstateBan(); 15503 EstateBan ban = new EstateBan();
14988 ban.EstateID = estate.EstateID; 15504 ban.EstateID = estate.EstateID;
14989 ban.BannedUserID = id; 15505 ban.BannedUserID = id;
14990 estate.AddBan(ban); 15506 estate.AddBan(ban);
14991 break; 15507 break;
14992 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 15508 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
14993 if (!isAccount || !estate.IsBanned(id)) return 0; 15509 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
14994 estate.RemoveBan(id); 15510 estate.RemoveBan(id);
14995 break; 15511 break;
14996 default: return 0; 15512 default: return 0;
@@ -15049,13 +15565,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
15049 public void llCollisionSprite(string impact_sprite) 15565 public void llCollisionSprite(string impact_sprite)
15050 { 15566 {
15051 m_host.AddScriptLPS(1); 15567 m_host.AddScriptLPS(1);
15052 NotImplemented("llCollisionSprite"); 15568 // Viewer 2.0 broke this and it's likely LL has no intention
15569 // of fixing it. Therefore, letting this be a NOP seems appropriate.
15053 } 15570 }
15054 15571
15055 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 15572 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
15056 { 15573 {
15057 m_host.AddScriptLPS(1); 15574 m_host.AddScriptLPS(1);
15058 NotImplemented("llGodLikeRezObject"); 15575
15576 if (!World.Permissions.IsGod(m_host.OwnerID))
15577 NotImplemented("llGodLikeRezObject");
15578
15579 AssetBase rezAsset = World.AssetService.Get(inventory);
15580 if (rezAsset == null)
15581 {
15582 llSay(0, "Asset not found");
15583 return;
15584 }
15585
15586 SceneObjectGroup group = null;
15587
15588 try
15589 {
15590 string xmlData = Utils.BytesToString(rezAsset.Data);
15591 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
15592 }
15593 catch
15594 {
15595 llSay(0, "Asset not found");
15596 return;
15597 }
15598
15599 if (group == null)
15600 {
15601 llSay(0, "Asset not found");
15602 return;
15603 }
15604
15605 group.RootPart.AttachPoint = group.RootPart.Shape.State;
15606 group.RootPart.AttachedPos = group.AbsolutePosition;
15607
15608 group.ResetIDs();
15609
15610 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
15611 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
15612 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
15613 group.ScheduleGroupForFullUpdate();
15614
15615 // objects rezzed with this method are die_at_edge by default.
15616 group.RootPart.SetDieAtEdge(true);
15617
15618 group.ResumeScripts();
15619
15620 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
15621 "object_rez", new Object[] {
15622 new LSL_String(
15623 group.RootPart.UUID.ToString()) },
15624 new DetectParams[0]));
15059 } 15625 }
15060 15626
15061 public LSL_String llTransferLindenDollars(string destination, int amount) 15627 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -15106,8 +15672,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
15106 return; 15672 return;
15107 } 15673 }
15108 15674
15675 string reason;
15109 bool result = money.ObjectGiveMoney( 15676 bool result = money.ObjectGiveMoney(
15110 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 15677 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn, out reason);
15111 15678
15112 if (result) 15679 if (result)
15113 { 15680 {
@@ -15115,7 +15682,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
15115 return; 15682 return;
15116 } 15683 }
15117 15684
15118 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS"; 15685 replydata = reason;
15119 } 15686 }
15120 finally 15687 finally
15121 { 15688 {
@@ -15132,6 +15699,815 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
15132 } 15699 }
15133 15700
15134 #endregion 15701 #endregion
15702
15703
15704 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
15705 {
15706 //This is a special version of SetPrimParams to deal with avatars which are sitting on the linkset.
15707
15708 int idx = 0;
15709 int idxStart = 0;
15710
15711 bool positionChanged = false;
15712 try
15713 {
15714 while (idx < rules.Length)
15715 {
15716 ++rulesParsed;
15717 int code = rules.GetLSLIntegerItem(idx++);
15718
15719 int remain = rules.Length - idx;
15720 idxStart = idx;
15721
15722 switch (code)
15723 {
15724 case (int)ScriptBaseClass.PRIM_POSITION:
15725 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
15726 {
15727 if (remain < 1)
15728 return new LSL_List();
15729
15730 LSL_Vector v;
15731 v = rules.GetVector3Item(idx++);
15732
15733 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
15734
15735 v = v + 2 * sitOffset;
15736
15737 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
15738 positionChanged = true;
15739 }
15740 break;
15741
15742 case (int)ScriptBaseClass.PRIM_ROTATION:
15743 {
15744 if (remain < 1)
15745 return new LSL_List();
15746
15747 Quaternion r;
15748 r = rules.GetQuaternionItem(idx++);
15749
15750 av.Rotation = m_host.GetWorldRotation() * r;
15751 positionChanged = true;
15752 }
15753 break;
15754
15755 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
15756 {
15757 if (remain < 1)
15758 return new LSL_List();
15759
15760 LSL_Rotation r;
15761 r = rules.GetQuaternionItem(idx++);
15762
15763 av.Rotation = r;
15764 positionChanged = true;
15765 }
15766 break;
15767
15768 // parse rest doing nothing but number of parameters error check
15769 case (int)ScriptBaseClass.PRIM_SIZE:
15770 case (int)ScriptBaseClass.PRIM_MATERIAL:
15771 case (int)ScriptBaseClass.PRIM_PHANTOM:
15772 case (int)ScriptBaseClass.PRIM_PHYSICS:
15773 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
15774 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
15775 case (int)ScriptBaseClass.PRIM_NAME:
15776 case (int)ScriptBaseClass.PRIM_DESC:
15777 if (remain < 1)
15778 return new LSL_List();
15779 idx++;
15780 break;
15781
15782 case (int)ScriptBaseClass.PRIM_GLOW:
15783 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
15784 case (int)ScriptBaseClass.PRIM_TEXGEN:
15785 if (remain < 2)
15786 return new LSL_List();
15787 idx += 2;
15788 break;
15789
15790 case (int)ScriptBaseClass.PRIM_TYPE:
15791 if (remain < 3)
15792 return new LSL_List();
15793 code = (int)rules.GetLSLIntegerItem(idx++);
15794 remain = rules.Length - idx;
15795 switch (code)
15796 {
15797 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
15798 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
15799 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
15800 if (remain < 6)
15801 return new LSL_List();
15802 idx += 6;
15803 break;
15804
15805 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
15806 if (remain < 5)
15807 return new LSL_List();
15808 idx += 5;
15809 break;
15810
15811 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
15812 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
15813 case (int)ScriptBaseClass.PRIM_TYPE_RING:
15814 if (remain < 11)
15815 return new LSL_List();
15816 idx += 11;
15817 break;
15818
15819 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
15820 if (remain < 2)
15821 return new LSL_List();
15822 idx += 2;
15823 break;
15824 }
15825 break;
15826
15827 case (int)ScriptBaseClass.PRIM_COLOR:
15828 case (int)ScriptBaseClass.PRIM_TEXT:
15829 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
15830 case (int)ScriptBaseClass.PRIM_OMEGA:
15831 if (remain < 3)
15832 return new LSL_List();
15833 idx += 3;
15834 break;
15835
15836 case (int)ScriptBaseClass.PRIM_TEXTURE:
15837 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
15838 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
15839 if (remain < 5)
15840 return new LSL_List();
15841 idx += 5;
15842 break;
15843
15844 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
15845 if (remain < 7)
15846 return new LSL_List();
15847
15848 idx += 7;
15849 break;
15850
15851 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
15852 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
15853 return new LSL_List();
15854
15855 return rules.GetSublist(idx, -1);
15856 }
15857 }
15858 }
15859 catch (InvalidCastException e)
15860 {
15861 Error(originFunc,string.Format(
15862 " error running rule #{1}: arg #{2} ",
15863 rulesParsed, idx - idxStart) + e.Message);
15864 }
15865 finally
15866 {
15867 if (positionChanged)
15868 av.SendTerseUpdateToAllClients();
15869 }
15870 return new LSL_List();
15871 }
15872
15873 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
15874 {
15875 // avatars case
15876 // replies as SL wiki
15877
15878// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
15879 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
15880
15881 int idx = 0;
15882 while (idx < rules.Length)
15883 {
15884 int code = (int)rules.GetLSLIntegerItem(idx++);
15885 int remain = rules.Length - idx;
15886
15887 switch (code)
15888 {
15889 case (int)ScriptBaseClass.PRIM_MATERIAL:
15890 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
15891 break;
15892
15893 case (int)ScriptBaseClass.PRIM_PHYSICS:
15894 res.Add(new LSL_Integer(0));
15895 break;
15896
15897 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
15898 res.Add(new LSL_Integer(0));
15899 break;
15900
15901 case (int)ScriptBaseClass.PRIM_PHANTOM:
15902 res.Add(new LSL_Integer(0));
15903 break;
15904
15905 case (int)ScriptBaseClass.PRIM_POSITION:
15906 Vector3 pos;
15907
15908 if (sitPart.ParentGroup.RootPart != null)
15909 {
15910 pos = avatar.OffsetPosition;
15911
15912 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
15913 pos -= sitOffset;
15914
15915 SceneObjectPart sitroot = sitPart.ParentGroup.RootPart;
15916 pos = sitroot.AbsolutePosition + pos * sitroot.GetWorldRotation();
15917 }
15918 else
15919 pos = avatar.AbsolutePosition;
15920
15921 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
15922 break;
15923
15924 case (int)ScriptBaseClass.PRIM_SIZE:
15925 Vector3 s = avatar.Appearance.AvatarSize;
15926 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
15927
15928 break;
15929
15930 case (int)ScriptBaseClass.PRIM_ROTATION:
15931 res.Add(new LSL_Rotation(avatar.GetWorldRotation()));
15932 break;
15933
15934 case (int)ScriptBaseClass.PRIM_TYPE:
15935 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
15936 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
15937 res.Add(new LSL_Vector(0f,1.0f,0f));
15938 res.Add(new LSL_Float(0.0f));
15939 res.Add(new LSL_Vector(0, 0, 0));
15940 res.Add(new LSL_Vector(1.0f,1.0f,0f));
15941 res.Add(new LSL_Vector(0, 0, 0));
15942 break;
15943
15944 case (int)ScriptBaseClass.PRIM_TEXTURE:
15945 if (remain < 1)
15946 return new LSL_List();
15947
15948 int face = (int)rules.GetLSLIntegerItem(idx++);
15949 if (face == ScriptBaseClass.ALL_SIDES)
15950 {
15951 for (face = 0; face < 21; face++)
15952 {
15953 res.Add(new LSL_String(""));
15954 res.Add(new LSL_Vector(0,0,0));
15955 res.Add(new LSL_Vector(0,0,0));
15956 res.Add(new LSL_Float(0.0));
15957 }
15958 }
15959 else
15960 {
15961 if (face >= 0 && face < 21)
15962 {
15963 res.Add(new LSL_String(""));
15964 res.Add(new LSL_Vector(0,0,0));
15965 res.Add(new LSL_Vector(0,0,0));
15966 res.Add(new LSL_Float(0.0));
15967 }
15968 }
15969 break;
15970
15971 case (int)ScriptBaseClass.PRIM_COLOR:
15972 if (remain < 1)
15973 return new LSL_List();
15974
15975 face = (int)rules.GetLSLIntegerItem(idx++);
15976
15977 if (face == ScriptBaseClass.ALL_SIDES)
15978 {
15979 for (face = 0; face < 21; face++)
15980 {
15981 res.Add(new LSL_Vector(0,0,0));
15982 res.Add(new LSL_Float(0));
15983 }
15984 }
15985 else
15986 {
15987 res.Add(new LSL_Vector(0,0,0));
15988 res.Add(new LSL_Float(0));
15989 }
15990 break;
15991
15992 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
15993 if (remain < 1)
15994 return new LSL_List();
15995 face = (int)rules.GetLSLIntegerItem(idx++);
15996
15997 if (face == ScriptBaseClass.ALL_SIDES)
15998 {
15999 for (face = 0; face < 21; face++)
16000 {
16001 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
16002 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
16003 }
16004 }
16005 else
16006 {
16007 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
16008 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
16009 }
16010 break;
16011
16012 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
16013 if (remain < 1)
16014 return new LSL_List();
16015 face = (int)rules.GetLSLIntegerItem(idx++);
16016
16017 if (face == ScriptBaseClass.ALL_SIDES)
16018 {
16019 for (face = 0; face < 21; face++)
16020 {
16021 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
16022 }
16023 }
16024 else
16025 {
16026 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
16027 }
16028 break;
16029
16030 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
16031 res.Add(new LSL_Integer(0));
16032 res.Add(new LSL_Integer(0));// softness
16033 res.Add(new LSL_Float(0.0f)); // gravity
16034 res.Add(new LSL_Float(0.0f)); // friction
16035 res.Add(new LSL_Float(0.0f)); // wind
16036 res.Add(new LSL_Float(0.0f)); // tension
16037 res.Add(new LSL_Vector(0f,0f,0f));
16038 break;
16039
16040 case (int)ScriptBaseClass.PRIM_TEXGEN:
16041 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
16042 if (remain < 1)
16043 return new LSL_List();
16044 face = (int)rules.GetLSLIntegerItem(idx++);
16045
16046 if (face == ScriptBaseClass.ALL_SIDES)
16047 {
16048 for (face = 0; face < 21; face++)
16049 {
16050 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
16051 }
16052 }
16053 else
16054 {
16055 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
16056 }
16057 break;
16058
16059 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
16060 res.Add(new LSL_Integer(0));
16061 res.Add(new LSL_Vector(0f,0f,0f));
16062 res.Add(new LSL_Float(0f)); // intensity
16063 res.Add(new LSL_Float(0f)); // radius
16064 res.Add(new LSL_Float(0f)); // falloff
16065 break;
16066
16067 case (int)ScriptBaseClass.PRIM_GLOW:
16068 if (remain < 1)
16069 return new LSL_List();
16070 face = (int)rules.GetLSLIntegerItem(idx++);
16071
16072 if (face == ScriptBaseClass.ALL_SIDES)
16073 {
16074 for (face = 0; face < 21; face++)
16075 {
16076 res.Add(new LSL_Float(0f));
16077 }
16078 }
16079 else
16080 {
16081 res.Add(new LSL_Float(0f));
16082 }
16083 break;
16084
16085 case (int)ScriptBaseClass.PRIM_TEXT:
16086 res.Add(new LSL_String(""));
16087 res.Add(new LSL_Vector(0f,0f,0f));
16088 res.Add(new LSL_Float(1.0f));
16089 break;
16090
16091 case (int)ScriptBaseClass.PRIM_NAME:
16092 res.Add(new LSL_String(avatar.Name));
16093 break;
16094
16095 case (int)ScriptBaseClass.PRIM_DESC:
16096 res.Add(new LSL_String(""));
16097 break;
16098
16099 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
16100 Quaternion lrot = avatar.Rotation;
16101 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
16102 break;
16103
16104 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
16105 Vector3 lpos = avatar.OffsetPosition;
16106 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
16107 lpos -= lsitOffset;
16108
16109 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
16110 break;
16111
16112 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
16113 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
16114 return new LSL_List();
16115
16116 return rules.GetSublist(idx, -1);
16117 }
16118 }
16119
16120 return new LSL_List();
16121 }
16122
16123 public void llSetAnimationOverride(LSL_String animState, LSL_String anim)
16124 {
16125 string state = String.Empty;
16126
16127 foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL)
16128 {
16129 if (kvp.Value.ToLower() == ((string)animState).ToLower())
16130 {
16131 state = kvp.Key;
16132 break;
16133 }
16134 }
16135
16136 if (state == String.Empty)
16137 {
16138 llShout(ScriptBaseClass.DEBUG_CHANNEL, "Invalid animation state " + animState);
16139 return;
16140 }
16141
16142 if (m_item.PermsGranter == UUID.Zero)
16143 {
16144 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16145 return;
16146 }
16147
16148 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS) == 0)
16149 {
16150 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16151 return;
16152 }
16153
16154 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
16155
16156 if (presence == null)
16157 return;
16158
16159 UUID animID;
16160
16161 animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation);
16162
16163 if (animID == UUID.Zero)
16164 {
16165 String animupper = ((string)anim).ToUpperInvariant();
16166 DefaultAvatarAnimations.AnimsUUID.TryGetValue(animupper, out animID);
16167 }
16168
16169 if (animID == UUID.Zero)
16170 {
16171 llShout(ScriptBaseClass.DEBUG_CHANNEL, "Animation not found");
16172 return;
16173 }
16174
16175 presence.SetAnimationOverride(state, animID);
16176 }
16177
16178 public void llResetAnimationOverride(LSL_String animState)
16179 {
16180 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
16181 if (presence == null)
16182 return;
16183
16184 if (m_item.PermsGranter == UUID.Zero)
16185 {
16186 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16187 return;
16188 }
16189
16190 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS) == 0)
16191 {
16192 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16193 return;
16194 }
16195
16196 if (animState == "ALL")
16197 {
16198 presence.SetAnimationOverride("ALL", UUID.Zero);
16199 return;
16200 }
16201
16202 string state = String.Empty;
16203
16204 foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL)
16205 {
16206 if (kvp.Value.ToLower() == ((string)animState).ToLower())
16207 {
16208 state = kvp.Key;
16209 break;
16210 }
16211 }
16212
16213 if (state == String.Empty)
16214 {
16215 return;
16216 }
16217
16218 presence.SetAnimationOverride(state, UUID.Zero);
16219 }
16220
16221 public LSL_String llGetAnimationOverride(LSL_String animState)
16222 {
16223 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
16224 if (presence == null)
16225 return String.Empty;
16226
16227 if (m_item.PermsGranter == UUID.Zero)
16228 {
16229 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16230 return String.Empty;
16231 }
16232
16233 if ((m_item.PermsMask & (ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS | ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION)) == 0)
16234 {
16235 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16236 return String.Empty;
16237 }
16238
16239 string state = String.Empty;
16240
16241 foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL)
16242 {
16243 if (kvp.Value.ToLower() == ((string)animState).ToLower())
16244 {
16245 state = kvp.Key;
16246 break;
16247 }
16248 }
16249
16250 if (state == String.Empty)
16251 {
16252 return String.Empty;
16253 }
16254
16255 UUID animID = presence.GetAnimationOverride(state);
16256 if (animID == UUID.Zero)
16257 return animState;
16258
16259 foreach (KeyValuePair<string, UUID> kvp in DefaultAvatarAnimations.AnimsUUID)
16260 {
16261 if (kvp.Value == animID)
16262 return kvp.Key.ToLower();
16263 }
16264
16265 foreach (TaskInventoryItem item in m_host.Inventory.GetInventoryItems())
16266 {
16267 if (item.AssetID == animID)
16268 return item.Name;
16269 }
16270
16271 return String.Empty;
16272 }
16273
16274 public LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers)
16275 {
16276 OSD o = OSDParser.DeserializeJson(json);
16277 OSD specVal = JsonGetSpecific(o, specifiers, 0);
16278
16279 return specVal.AsString();
16280 }
16281
16282 public LSL_List llJson2List(LSL_String json)
16283 {
16284 try
16285 {
16286 OSD o = OSDParser.DeserializeJson(json);
16287 return (LSL_List)ParseJsonNode(o);
16288 }
16289 catch (Exception)
16290 {
16291 return new LSL_List(ScriptBaseClass.JSON_INVALID);
16292 }
16293 }
16294
16295 private object ParseJsonNode(OSD node)
16296 {
16297 if (node.Type == OSDType.Integer)
16298 return new LSL_Integer(node.AsInteger());
16299 if (node.Type == OSDType.Boolean)
16300 return new LSL_Integer(node.AsBoolean() ? 1 : 0);
16301 if (node.Type == OSDType.Real)
16302 return new LSL_Float(node.AsReal());
16303 if (node.Type == OSDType.UUID || node.Type == OSDType.String)
16304 return new LSL_String(node.AsString());
16305 if (node.Type == OSDType.Array)
16306 {
16307 LSL_List resp = new LSL_List();
16308 OSDArray ar = node as OSDArray;
16309 foreach (OSD o in ar)
16310 resp.Add(ParseJsonNode(o));
16311 return resp;
16312 }
16313 if (node.Type == OSDType.Map)
16314 {
16315 LSL_List resp = new LSL_List();
16316 OSDMap ar = node as OSDMap;
16317 foreach (KeyValuePair<string, OSD> o in ar)
16318 {
16319 resp.Add(new LSL_String(o.Key));
16320 resp.Add(ParseJsonNode(o.Value));
16321 }
16322 return resp;
16323 }
16324 throw new Exception(ScriptBaseClass.JSON_INVALID);
16325 }
16326
16327 public LSL_String llList2Json(LSL_String type, LSL_List values)
16328 {
16329 try
16330 {
16331 if (type == ScriptBaseClass.JSON_ARRAY)
16332 {
16333 OSDArray array = new OSDArray();
16334 foreach (object o in values.Data)
16335 {
16336 array.Add(ListToJson(o));
16337 }
16338 return OSDParser.SerializeJsonString(array);
16339 }
16340 else if (type == ScriptBaseClass.JSON_OBJECT)
16341 {
16342 OSDMap map = new OSDMap();
16343 for (int i = 0; i < values.Data.Length; i += 2)
16344 {
16345 if (!(values.Data[i] is LSL_String))
16346 return ScriptBaseClass.JSON_INVALID;
16347 map.Add(((LSL_String)values.Data[i]).m_string, ListToJson(values.Data[i + 1]));
16348 }
16349 return OSDParser.SerializeJsonString(map);
16350 }
16351 return ScriptBaseClass.JSON_INVALID;
16352 }
16353 catch (Exception ex)
16354 {
16355 return ex.Message;
16356 }
16357 }
16358
16359 private OSD ListToJson(object o)
16360 {
16361 if (o is LSL_Float)
16362 return OSD.FromReal(((LSL_Float)o).value);
16363 if (o is LSL_Integer)
16364 {
16365 int i = ((LSL_Integer)o).value;
16366 if (i == 0)
16367 return OSD.FromBoolean(false);
16368 else if (i == 1)
16369 return OSD.FromBoolean(true);
16370 return OSD.FromInteger(i);
16371 }
16372 if (o is LSL_Rotation)
16373 return OSD.FromString(((LSL_Rotation)o).ToString());
16374 if (o is LSL_Vector)
16375 return OSD.FromString(((LSL_Vector)o).ToString());
16376 if (o is LSL_String)
16377 {
16378 string str = ((LSL_String)o).m_string;
16379 if (str == ScriptBaseClass.JSON_NULL)
16380 return new OSD();
16381 return OSD.FromString(str);
16382 }
16383 throw new Exception(ScriptBaseClass.JSON_INVALID);
16384 }
16385
16386 private OSD JsonGetSpecific(OSD o, LSL_List specifiers, int i)
16387 {
16388 object spec = specifiers.Data[i];
16389 OSD nextVal = null;
16390 if (o is OSDArray)
16391 {
16392 if (spec is LSL_Integer)
16393 nextVal = ((OSDArray)o)[((LSL_Integer)spec).value];
16394 }
16395 if (o is OSDMap)
16396 {
16397 if (spec is LSL_String)
16398 nextVal = ((OSDMap)o)[((LSL_String)spec).m_string];
16399 }
16400 if (nextVal != null)
16401 {
16402 if (specifiers.Data.Length - 1 > i)
16403 return JsonGetSpecific(nextVal, specifiers, i + 1);
16404 }
16405 return nextVal;
16406 }
16407
16408 public LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value)
16409 {
16410 try
16411 {
16412 OSD o = OSDParser.DeserializeJson(json);
16413 JsonSetSpecific(o, specifiers, 0, value);
16414 return OSDParser.SerializeJsonString(o);
16415 }
16416 catch (Exception)
16417 {
16418 }
16419 return ScriptBaseClass.JSON_INVALID;
16420 }
16421
16422 private void JsonSetSpecific(OSD o, LSL_List specifiers, int i, LSL_String val)
16423 {
16424 object spec = specifiers.Data[i];
16425 // 20131224 not used object specNext = i+1 == specifiers.Data.Length ? null : specifiers.Data[i+1];
16426 OSD nextVal = null;
16427 if (o is OSDArray)
16428 {
16429 OSDArray array = ((OSDArray)o);
16430 if (spec is LSL_Integer)
16431 {
16432 int v = ((LSL_Integer)spec).value;
16433 if (v >= array.Count)
16434 array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val));
16435 else
16436 nextVal = ((OSDArray)o)[v];
16437 }
16438 else if (spec is LSL_String && ((LSL_String)spec) == ScriptBaseClass.JSON_APPEND)
16439 array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val));
16440 }
16441 if (o is OSDMap)
16442 {
16443 if (spec is LSL_String)
16444 {
16445 OSDMap map = ((OSDMap)o);
16446 if (map.ContainsKey(((LSL_String)spec).m_string))
16447 nextVal = map[((LSL_String)spec).m_string];
16448 else
16449 map.Add(((LSL_String)spec).m_string, JsonBuildRestOfSpec(specifiers, i + 1, val));
16450 }
16451 }
16452 if (nextVal != null)
16453 {
16454 if (specifiers.Data.Length - 1 > i)
16455 {
16456 JsonSetSpecific(nextVal, specifiers, i + 1, val);
16457 return;
16458 }
16459 }
16460 }
16461
16462 private OSD JsonBuildRestOfSpec(LSL_List specifiers, int i, LSL_String val)
16463 {
16464 object spec = i >= specifiers.Data.Length ? null : specifiers.Data[i];
16465 // 20131224 not used object specNext = i+1 >= specifiers.Data.Length ? null : specifiers.Data[i+1];
16466
16467 if (spec == null)
16468 return OSD.FromString(val);
16469
16470 if (spec is LSL_Integer ||
16471 (spec is LSL_String && ((LSL_String)spec) == ScriptBaseClass.JSON_APPEND))
16472 {
16473 OSDArray array = new OSDArray();
16474 array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val));
16475 return array;
16476 }
16477 else if (spec is LSL_String)
16478 {
16479 OSDMap map = new OSDMap();
16480 map.Add((LSL_String)spec, JsonBuildRestOfSpec(specifiers, i + 1, val));
16481 return map;
16482 }
16483 return new OSD();
16484 }
16485
16486 public LSL_String llJsonValueType(LSL_String json, LSL_List specifiers)
16487 {
16488 OSD o = OSDParser.DeserializeJson(json);
16489 OSD specVal = JsonGetSpecific(o, specifiers, 0);
16490 if (specVal == null)
16491 return ScriptBaseClass.JSON_INVALID;
16492 switch (specVal.Type)
16493 {
16494 case OSDType.Array:
16495 return ScriptBaseClass.JSON_ARRAY;
16496 case OSDType.Boolean:
16497 return specVal.AsBoolean() ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE;
16498 case OSDType.Integer:
16499 case OSDType.Real:
16500 return ScriptBaseClass.JSON_NUMBER;
16501 case OSDType.Map:
16502 return ScriptBaseClass.JSON_OBJECT;
16503 case OSDType.String:
16504 case OSDType.UUID:
16505 return ScriptBaseClass.JSON_STRING;
16506 case OSDType.Unknown:
16507 return ScriptBaseClass.JSON_NULL;
16508 }
16509 return ScriptBaseClass.JSON_INVALID;
16510 }
15135 } 16511 }
15136 16512
15137 public class NotecardCache 16513 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..29f5a83 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)
@@ -3025,7 +3114,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3025 if (appearanceModule != null) 3114 if (appearanceModule != null)
3026 { 3115 {
3027 appearanceModule.SaveBakedTextures(sp.UUID); 3116 appearanceModule.SaveBakedTextures(sp.UUID);
3028 OSDMap appearancePacked = sp.Appearance.Pack(); 3117 EntityTransferContext ctx = new EntityTransferContext();
3118 OSDMap appearancePacked = sp.Appearance.Pack(ctx);
3029 3119
3030 TaskInventoryItem item 3120 TaskInventoryItem item
3031 = SaveNotecard(notecard, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true); 3121 = SaveNotecard(notecard, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true);
@@ -3185,7 +3275,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3185 { 3275 {
3186 Scene scene = m_ScriptEngine.World; 3276 Scene scene = m_ScriptEngine.World;
3187 GridRegion region = scene.GridService.GetRegionByUUID(UUID.Zero, World.RegionInfo.RegionID); 3277 GridRegion region = scene.GridService.GetRegionByUUID(UUID.Zero, World.RegionInfo.RegionID);
3188 return new LSL_Vector((float)region.RegionSizeX, (float)region.RegionSizeX, Constants.RegionHeight); 3278 return new LSL_Vector((float)region.RegionSizeX, (float)region.RegionSizeY, (float)Constants.RegionHeight);
3189 } 3279 }
3190 } 3280 }
3191 3281
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);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index e02d35e..e44a106 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
39 40
40namespace OpenSim.Region.ScriptEngine.Shared 41namespace OpenSim.Region.ScriptEngine.Shared
@@ -120,6 +121,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
120 Type = 0; 121 Type = 0;
121 Velocity = new LSL_Types.Vector3(); 122 Velocity = new LSL_Types.Vector3();
122 initializeSurfaceTouch(); 123 initializeSurfaceTouch();
124 Country = String.Empty;
123 } 125 }
124 126
125 public UUID Key; 127 public UUID Key;
@@ -151,6 +153,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
151 private int touchFace; 153 private int touchFace;
152 public int TouchFace { get { return touchFace; } } 154 public int TouchFace { get { return touchFace; } }
153 155
156 public string Country;
157
154 // This can be done in two places including the constructor 158 // This can be done in two places including the constructor
155 // so be carefull what gets added here 159 // so be carefull what gets added here
156 private void initializeSurfaceTouch() 160 private void initializeSurfaceTouch()
@@ -198,6 +202,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
198 return; 202 return;
199 203
200 Name = presence.Firstname + " " + presence.Lastname; 204 Name = presence.Firstname + " " + presence.Lastname;
205 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
206 if (account != null)
207 Country = account.UserCountry;
208
201 Owner = Key; 209 Owner = Key;
202 Position = new LSL_Types.Vector3(presence.AbsolutePosition); 210 Position = new LSL_Types.Vector3(presence.AbsolutePosition);
203 Rotation = new LSL_Types.Quaternion( 211 Rotation = new LSL_Types.Quaternion(
@@ -207,22 +215,27 @@ namespace OpenSim.Region.ScriptEngine.Shared
207 presence.Rotation.W); 215 presence.Rotation.W);
208 Velocity = new LSL_Types.Vector3(presence.Velocity); 216 Velocity = new LSL_Types.Vector3(presence.Velocity);
209 217
210 if (presence.PresenceType != PresenceType.Npc) 218 Type = 0x01; // Avatar
211 { 219 if (presence.PresenceType == PresenceType.Npc)
212 Type = AGENT; 220 Type = 0x20;
213 } 221
214 else 222 // Cope Impl. We don't use OS_NPC.
215 { 223 //if (presence.PresenceType != PresenceType.Npc)
216 Type = OS_NPC; 224 //{
217 225 // Type = AGENT;
218 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 226 //}
219 INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); 227 //else
220 228 //{
221 if (npcData.SenseAsAgent) 229 // Type = OS_NPC;
222 { 230
223 Type |= AGENT; 231 // INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
224 } 232 // INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
225 } 233
234 // if (npcData.SenseAsAgent)
235 // {
236 // Type |= AGENT;
237 // }
238 //}
226 239
227 if (presence.Velocity != Vector3.Zero) 240 if (presence.Velocity != Vector3.Zero)
228 Type |= ACTIVE; 241 Type |= ACTIVE;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index fa6e6fc..674144b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -51,7 +51,8 @@ using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
51using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 51using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
52using OpenSim.Region.ScriptEngine.Shared.CodeTools; 52using OpenSim.Region.ScriptEngine.Shared.CodeTools;
53using OpenSim.Region.ScriptEngine.Interfaces; 53using OpenSim.Region.ScriptEngine.Interfaces;
54using System.Diagnostics; 54
55using System.Diagnostics; //for [DebuggerNonUserCode]
55 56
56namespace OpenSim.Region.ScriptEngine.Shared.Instance 57namespace OpenSim.Region.ScriptEngine.Shared.Instance
57{ 58{
@@ -256,8 +257,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
256 StartParam = startParam; 257 StartParam = startParam;
257 m_MaxScriptQueue = maxScriptQueue; 258 m_MaxScriptQueue = maxScriptQueue;
258 m_postOnRez = postOnRez; 259 m_postOnRez = postOnRez;
259 m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; 260 m_AttachedAvatar = part.ParentGroup.AttachedAvatar;
260 m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; 261 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID;
261 262
262 m_SaveState = StatePersistedHere; 263 m_SaveState = StatePersistedHere;
263 264
@@ -456,27 +457,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
456 PostEvent(new EventParams("attach", 457 PostEvent(new EventParams("attach",
457 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); 458 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0]));
458 } 459 }
460
459 } 461 }
460 } 462 }
461 463
462 private void ReleaseControls() 464 private void ReleaseControls()
463 { 465 {
464 int permsMask; 466 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
465 UUID permsGranter; 467
466 lock (Part.TaskInventory) 468 if (part != null)
467 { 469 {
468 if (!Part.TaskInventory.ContainsKey(ItemID)) 470 int permsMask;
471 UUID permsGranter;
472 part.TaskInventory.LockItemsForRead(true);
473 if (!part.TaskInventory.ContainsKey(ItemID))
474 {
475 part.TaskInventory.LockItemsForRead(false);
469 return; 476 return;
477 }
478 permsGranter = part.TaskInventory[ItemID].PermsGranter;
479 permsMask = part.TaskInventory[ItemID].PermsMask;
480 part.TaskInventory.LockItemsForRead(false);
470 481
471 permsGranter = Part.TaskInventory[ItemID].PermsGranter; 482 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
472 permsMask = Part.TaskInventory[ItemID].PermsMask; 483 {
473 } 484 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
474 485 if (presence != null)
475 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 486 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
476 { 487 }
477 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
478 if (presence != null)
479 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
480 } 488 }
481 } 489 }
482 490
@@ -639,6 +647,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
639 return true; 647 return true;
640 } 648 }
641 649
650 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
642 public void SetState(string state) 651 public void SetState(string state)
643 { 652 {
644 if (state == State) 653 if (state == State)
@@ -764,6 +773,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
764 /// <returns></returns> 773 /// <returns></returns>
765 public object EventProcessor() 774 public object EventProcessor()
766 { 775 {
776 EventParams data = null;
767 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 777 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
768 if (!Running) 778 if (!Running)
769 return 0; 779 return 0;
@@ -850,7 +860,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
850 Part.ParentGroup.UUID, 860 Part.ParentGroup.UUID,
851 Part.AbsolutePosition, 861 Part.AbsolutePosition,
852 Part.ParentGroup.Scene.Name); 862 Part.ParentGroup.Scene.Name);
853
854 AsyncCommandManager.StateChange(Engine, 863 AsyncCommandManager.StateChange(Engine,
855 LocalID, ItemID); 864 LocalID, ItemID);
856 // we are effectively in the new state now, so we can resume queueing 865 // we are effectively in the new state now, so we can resume queueing
@@ -867,6 +876,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
867 // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", 876 // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
868 // PrimName, ScriptName, data.EventName, State); 877 // PrimName, ScriptName, data.EventName, State);
869 878
879
870 try 880 try
871 { 881 {
872 m_CurrentEvent = data.EventName; 882 m_CurrentEvent = data.EventName;
@@ -931,15 +941,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
931 catch (Exception) 941 catch (Exception)
932 { 942 {
933 } 943 }
934 // catch (Exception e2) // LEGIT: User Scripting
935 // {
936 // m_log.Error("[SCRIPT]: "+
937 // "Error displaying error in-world: " +
938 // e2.ToString());
939 // m_log.Error("[SCRIPT]: " +
940 // "Errormessage: Error compiling script:\r\n" +
941 // e.ToString());
942 // }
943 } 944 }
944 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) 945 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
945 { 946 {
@@ -1012,15 +1013,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1012 ReleaseControls(); 1013 ReleaseControls();
1013 1014
1014 Stop(timeout); 1015 Stop(timeout);
1015 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 1016 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
1016 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 1017 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
1018 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
1019 part.CollisionSound = UUID.Zero;
1017 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 1020 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
1021
1022 m_TimerQueued = false;
1023 m_StateChangeInProgress = false;
1018 EventQueue.Clear(); 1024 EventQueue.Clear();
1025
1019 m_Script.ResetVars(); 1026 m_Script.ResetVars();
1020 StartParam = 0; 1027 StartParam = 0;
1021 State = "default"; 1028 State = "default";
1022 1029
1023 Part.SetScriptEvents(ItemID, 1030
1031 part.SetScriptEvents(ItemID,
1024 (int)m_Script.GetStateEventFlags(State)); 1032 (int)m_Script.GetStateEventFlags(State));
1025 if (running) 1033 if (running)
1026 Start(); 1034 Start();
@@ -1031,6 +1039,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1031 new Object[0], new DetectParams[0])); 1039 new Object[0], new DetectParams[0]));
1032 } 1040 }
1033 1041
1042 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
1034 public void ApiResetScript() 1043 public void ApiResetScript()
1035 { 1044 {
1036 // bool running = Running; 1045 // bool running = Running;
@@ -1039,17 +1048,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1039 ReleaseControls(); 1048 ReleaseControls();
1040 1049
1041 m_Script.ResetVars(); 1050 m_Script.ResetVars();
1042 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 1051 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
1043 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 1052 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
1053 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
1054 part.CollisionSound = UUID.Zero;
1044 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 1055 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
1045 1056
1057 m_TimerQueued = false;
1058 m_StateChangeInProgress = false;
1046 EventQueue.Clear(); 1059 EventQueue.Clear();
1047 m_Script.ResetVars(); 1060 m_Script.ResetVars();
1048 string oldState = State; 1061 string oldState = State;
1049 StartParam = 0; 1062 StartParam = 0;
1050 State = "default"; 1063 State = "default";
1051 1064
1052 Part.SetScriptEvents(ItemID, 1065 part.SetScriptEvents(ItemID,
1053 (int)m_Script.GetStateEventFlags(State)); 1066 (int)m_Script.GetStateEventFlags(State));
1054 1067
1055 if (m_CurrentEvent != "state_entry" || oldState != "default") 1068 if (m_CurrentEvent != "state_entry" || oldState != "default")
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 0ca5ff3..d501979 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -100,21 +100,32 @@ namespace OpenSim.Region.ScriptEngine.Shared
100 100
101 #region Overriders 101 #region Overriders
102 102
103 public static implicit operator Boolean(Vector3 vec)
104 {
105 if (vec.x != 0)
106 return true;
107 if (vec.y != 0)
108 return true;
109 if (vec.z != 0)
110 return true;
111 return false;
112 }
113
103 public override string ToString() 114 public override string ToString()
104 { 115 {
105 string s=String.Format(Culture.FormatProvider,"<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 116 string s = String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
106 return s; 117 return s;
107 } 118 }
108 119
109 public static explicit operator LSLString(Vector3 vec) 120 public static explicit operator LSLString(Vector3 vec)
110 { 121 {
111 string s=String.Format(Culture.FormatProvider,"<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 122 string s = String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
112 return new LSLString(s); 123 return new LSLString(s);
113 } 124 }
114 125
115 public static explicit operator string(Vector3 vec) 126 public static explicit operator string(Vector3 vec)
116 { 127 {
117 string s=String.Format(Culture.FormatProvider,"<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 128 string s = String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
118 return s; 129 return s;
119 } 130 }
120 131
@@ -397,6 +408,18 @@ namespace OpenSim.Region.ScriptEngine.Shared
397 #endregion 408 #endregion
398 409
399 #region Overriders 410 #region Overriders
411 public static implicit operator Boolean(Quaternion q)
412 {
413 if (q.x != 0)
414 return true;
415 if (q.y != 0)
416 return true;
417 if (q.z != 0)
418 return true;
419 if (q.s != 1.0f)
420 return true;
421 return false;
422 }
400 423
401 public override int GetHashCode() 424 public override int GetHashCode()
402 { 425 {
@@ -414,19 +437,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
414 437
415 public override string ToString() 438 public override string ToString()
416 { 439 {
417 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 440 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
418 return st; 441 return st;
419 } 442 }
420 443
421 public static explicit operator string(Quaternion r) 444 public static explicit operator string(Quaternion r)
422 { 445 {
423 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 446 string s=String.Format(Culture.FormatProvider,"<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
424 return s; 447 return s;
425 } 448 }
426 449
427 public static explicit operator LSLString(Quaternion r) 450 public static explicit operator LSLString(Quaternion r)
428 { 451 {
429 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 452 string s=String.Format(Culture.FormatProvider,"<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
430 return new LSLString(s); 453 return new LSLString(s);
431 } 454 }
432 455
@@ -537,7 +560,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
537 else if (o is LSL_Types.LSLFloat) 560 else if (o is LSL_Types.LSLFloat)
538 size += 8; 561 size += 8;
539 else if (o is LSL_Types.LSLString) 562 else if (o is LSL_Types.LSLString)
540 size += ((LSL_Types.LSLString)o).m_string.Length; 563 size += ((LSL_Types.LSLString)o).m_string == null ? 0 : ((LSL_Types.LSLString)o).m_string.Length;
541 else if (o is LSL_Types.key) 564 else if (o is LSL_Types.key)
542 size += ((LSL_Types.key)o).value.Length; 565 size += ((LSL_Types.key)o).value.Length;
543 else if (o is LSL_Types.Vector3) 566 else if (o is LSL_Types.Vector3)
@@ -546,6 +569,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
546 size += 64; 569 size += 64;
547 else if (o is int) 570 else if (o is int)
548 size += 4; 571 size += 4;
572 else if (o is uint)
573 size += 4;
549 else if (o is string) 574 else if (o is string)
550 size += ((string)o).Length; 575 size += ((string)o).Length;
551 else if (o is float) 576 else if (o is float)
@@ -719,6 +744,11 @@ namespace OpenSim.Region.ScriptEngine.Shared
719 Data = tmp; 744 Data = tmp;
720 } 745 }
721 746
747 public static implicit operator Boolean(list l)
748 {
749 return l.Length != 0;
750 }
751
722 public static list operator +(list a, LSLString s) 752 public static list operator +(list a, LSLString s)
723 { 753 {
724 a.ExtendAndAdd(s); 754 a.ExtendAndAdd(s);
@@ -755,7 +785,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
755 int lb = -1; 785 int lb = -1;
756 try { la = a.Length; } 786 try { la = a.Length; }
757 catch (NullReferenceException) { } 787 catch (NullReferenceException) { }
758 try {lb = b.Length;} 788 try { lb = b.Length; }
759 catch (NullReferenceException) { } 789 catch (NullReferenceException) { }
760 790
761 return la != lb; 791 return la != lb;
@@ -1023,6 +1053,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
1023 stride = 1; 1053 stride = 1;
1024 } 1054 }
1025 1055
1056 if ((Data.Length % stride) != 0)
1057 return new list(ret);
1058
1026 // we can optimize here in the case where stride == 1 and the list 1059 // we can optimize here in the case where stride == 1 and the list
1027 // consists of homogeneous types 1060 // consists of homogeneous types
1028 1061
@@ -1537,8 +1570,6 @@ namespace OpenSim.Region.ScriptEngine.Shared
1537 } 1570 }
1538 } 1571 }
1539 1572
1540
1541
1542 static public implicit operator String(LSLString s) 1573 static public implicit operator String(LSLString s)
1543 { 1574 {
1544 return s.m_string; 1575 return s.m_string;
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
index 0ff2da3..ad775ff 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
@@ -245,6 +245,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
245 DetectParams d = new DetectParams(); 245 DetectParams d = new DetectParams();
246 d.Key =detobj.keyUUID; 246 d.Key =detobj.keyUUID;
247 d.Populate(myScriptEngine.World); 247 d.Populate(myScriptEngine.World);
248 d.LinkNum = detobj.linkNumber; // do it here since currently linknum is collided part
248 det.Add(d); 249 det.Add(d);
249 } 250 }
250 251
@@ -265,6 +266,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
265 DetectParams d = new DetectParams(); 266 DetectParams d = new DetectParams();
266 d.Key =detobj.keyUUID; 267 d.Key =detobj.keyUUID;
267 d.Populate(myScriptEngine.World); 268 d.Populate(myScriptEngine.World);
269 d.LinkNum = detobj.linkNumber; // do it here since currently linknum is collided part
268 det.Add(d); 270 det.Add(d);
269 } 271 }
270 272
@@ -284,6 +286,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
284 DetectParams d = new DetectParams(); 286 DetectParams d = new DetectParams();
285 d.Key =detobj.keyUUID; 287 d.Key =detobj.keyUUID;
286 d.Populate(myScriptEngine.World); 288 d.Populate(myScriptEngine.World);
289 d.LinkNum = detobj.linkNumber; // do it here since currently linknum is collided part
287 det.Add(d); 290 det.Add(d);
288 } 291 }
289 292
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEnginePersistenceTests.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEnginePersistenceTests.cs
index 2ef4058..07470d6 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEnginePersistenceTests.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEnginePersistenceTests.cs
@@ -43,6 +43,7 @@ using OpenSim.Tests.Common;
43 43
44namespace OpenSim.Region.ScriptEngine.Tests 44namespace OpenSim.Region.ScriptEngine.Tests
45{ 45{
46 /*
46 [TestFixture] 47 [TestFixture]
47 public class XEnginePersistenceTests : OpenSimTestCase 48 public class XEnginePersistenceTests : OpenSimTestCase
48 { 49 {
@@ -149,4 +150,5 @@ namespace OpenSim.Region.ScriptEngine.Tests
149 scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, rezzedSo); 150 scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, rezzedSo);
150 } 151 }
151 } 152 }
153 */
152} \ No newline at end of file 154} \ No newline at end of file