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.cs4332
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs162
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.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.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs17
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs95
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs7
-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.cs82
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/EventManager.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/Tests/XEnginePersistenceTests.cs2
23 files changed, 3484 insertions, 1709 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..3f523a4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,7 +24,7 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
@@ -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,57 @@ 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
544 switch (linkType)
545 {
546 case ScriptBaseClass.LINK_SET:
547 return avs;
548
549 case ScriptBaseClass.LINK_ROOT:
550 return ret;
551
552 case ScriptBaseClass.LINK_ALL_OTHERS:
553 return avs;
554
555 case ScriptBaseClass.LINK_ALL_CHILDREN:
556 return avs;
557
558 case ScriptBaseClass.LINK_THIS:
559 return ret;
560
561 default:
562 if (linkType < 0)
563 return ret;
564
565 int partCount = m_host.ParentGroup.GetPartCount();
566
567 if (linkType <= partCount)
568 {
569 return ret;
570 }
571 else
572 {
573 linkType = linkType - partCount;
574 if (linkType > avs.Count)
575 {
576 return ret;
577 }
578 else
579 {
580 ret.Add(avs[linkType-1]);
581 return ret;
582 }
583 }
584 }
585 }
586
496 /// <summary> 587 /// <summary>
497 /// Get a given link entity from a linkset (linked objects and any sitting avatars). 588 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
498 /// </summary> 589 /// </summary>
@@ -526,7 +617,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
526 } 617 }
527 618
528 int actualPrimCount = part.ParentGroup.PrimCount; 619 int actualPrimCount = part.ParentGroup.PrimCount;
529 List<ScenePresence> sittingAvatars = part.ParentGroup.GetSittingAvatars(); 620 List<UUID> sittingAvatars = part.ParentGroup.GetSittingAvatars();
530 int adjustedPrimCount = actualPrimCount + sittingAvatars.Count; 621 int adjustedPrimCount = actualPrimCount + sittingAvatars.Count;
531 622
532 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single 623 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
@@ -555,7 +646,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
555 } 646 }
556 else 647 else
557 { 648 {
558 return sittingAvatars[linknum - actualPrimCount - 1]; 649 ScenePresence sp = World.GetScenePresence(sittingAvatars[linknum - actualPrimCount - 1]);
650 if (sp != null)
651 return sp;
652 else
653 return null;
559 } 654 }
560 } 655 }
561 else 656 else
@@ -572,6 +667,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
572 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 667 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
573 { 668 {
574 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 669 List<SceneObjectPart> ret = new List<SceneObjectPart>();
670 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
671 return ret;
575 ret.Add(part); 672 ret.Add(part);
576 673
577 switch (linkType) 674 switch (linkType)
@@ -719,8 +816,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
719 public LSL_Float llFrand(double mag) 816 public LSL_Float llFrand(double mag)
720 { 817 {
721 m_host.AddScriptLPS(1); 818 m_host.AddScriptLPS(1);
722 819 lock (Util.RandomClass)
723 return Util.RandomClass.NextDouble() * mag; 820 {
821 return Util.RandomClass.NextDouble() * mag;
822 }
724 } 823 }
725 824
726 public LSL_Integer llFloor(double f) 825 public LSL_Integer llFloor(double f)
@@ -771,31 +870,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
771 870
772 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 871 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
773 872
774 /// <summary> 873 // Utility function for llRot2Euler
775 /// Convert an LSL rotation to a Euler vector. 874
776 /// </summary> 875 // normalize an angle between -PI and PI (-180 to +180 degrees)
777 /// <remarks> 876 protected double NormalizeAngle(double angle)
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 { 877 {
785 m_host.AddScriptLPS(1); 878 if (angle > -Math.PI && angle < Math.PI)
879 return angle;
880
881 int numPis = (int)(Math.PI / angle);
882 double remainder = angle - Math.PI * numPis;
883 if (numPis % 2 == 1)
884 return Math.PI - angle;
885 return remainder;
886 }
786 887
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. 888 public LSL_Vector llRot2Euler(LSL_Rotation q1)
788 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 889 {
789 if (m == 0.0) return new LSL_Vector(); 890 m_host.AddScriptLPS(1);
790 double x = Math.Atan2(-v.y, v.z); 891 LSL_Vector eul = new LSL_Vector();
791 double sin = v.x / m;
792 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
793 double y = Math.Asin(sin);
794 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
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)));
796 double z = Math.Atan2(v.y, v.x);
797 892
798 return new LSL_Vector(x, y, z); 893 double sqw = q1.s*q1.s;
894 double sqx = q1.x*q1.x;
895 double sqy = q1.z*q1.z;
896 double sqz = q1.y*q1.y;
897 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
898 double test = q1.x*q1.z + q1.y*q1.s;
899 if (test > 0.4999*unit) { // singularity at north pole
900 eul.z = 2 * Math.Atan2(q1.x,q1.s);
901 eul.y = Math.PI/2;
902 eul.x = 0;
903 return eul;
904 }
905 if (test < -0.4999*unit) { // singularity at south pole
906 eul.z = -2 * Math.Atan2(q1.x,q1.s);
907 eul.y = -Math.PI/2;
908 eul.x = 0;
909 return eul;
910 }
911 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
912 eul.y = Math.Asin(2*test/unit);
913 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
914 return eul;
799 } 915 }
800 916
801 /* From wiki: 917 /* From wiki:
@@ -848,18 +964,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
848 m_host.AddScriptLPS(1); 964 m_host.AddScriptLPS(1);
849 965
850 double x,y,z,s; 966 double x,y,z,s;
851 967 v.x *= 0.5;
852 double c1 = Math.Cos(v.x * 0.5); 968 v.y *= 0.5;
853 double c2 = Math.Cos(v.y * 0.5); 969 v.z *= 0.5;
854 double c3 = Math.Cos(v.z * 0.5); 970 double c1 = Math.Cos(v.x);
855 double s1 = Math.Sin(v.x * 0.5); 971 double c2 = Math.Cos(v.y);
856 double s2 = Math.Sin(v.y * 0.5); 972 double c1c2 = c1 * c2;
857 double s3 = Math.Sin(v.z * 0.5); 973 double s1 = Math.Sin(v.x);
858 974 double s2 = Math.Sin(v.y);
859 x = s1 * c2 * c3 + c1 * s2 * s3; 975 double s1s2 = s1 * s2;
860 y = c1 * s2 * c3 - s1 * c2 * s3; 976 double c1s2 = c1 * s2;
861 z = s1 * s2 * c3 + c1 * c2 * s3; 977 double s1c2 = s1 * c2;
862 s = c1 * c2 * c3 - s1 * s2 * s3; 978 double c3 = Math.Cos(v.z);
979 double s3 = Math.Sin(v.z);
980
981 x = s1c2 * c3 + c1s2 * s3;
982 y = c1s2 * c3 - s1c2 * s3;
983 z = s1s2 * c3 + c1c2 * s3;
984 s = c1c2 * c3 - s1s2 * s3;
863 985
864 return new LSL_Rotation(x, y, z, s); 986 return new LSL_Rotation(x, y, z, s);
865 } 987 }
@@ -997,77 +1119,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
997 { 1119 {
998 //A and B should both be normalized 1120 //A and B should both be normalized
999 m_host.AddScriptLPS(1); 1121 m_host.AddScriptLPS(1);
1000 LSL_Rotation rotBetween; 1122 /* 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, 1123 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
1002 // continue calculation. 1124
1003 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 1125 double dotProduct = LSL_Vector.Dot(a, b);
1126 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
1127 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
1128 double angle = Math.Acos(dotProduct / magProduct);
1129 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
1130 double s = Math.Sin(angle / 2);
1131
1132 double x = axis.x * s;
1133 double y = axis.y * s;
1134 double z = axis.z * s;
1135 double w = Math.Cos(angle / 2);
1136
1137 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
1138 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
1139
1140 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
1141 */
1142
1143 // This method mimics the 180 errors found in SL
1144 // See www.euclideanspace.com... angleBetween
1145 LSL_Vector vec_a = a;
1146 LSL_Vector vec_b = b;
1147
1148 // Eliminate zero length
1149 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
1150 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
1151 if (vec_a_mag < 0.00001 ||
1152 vec_b_mag < 0.00001)
1004 { 1153 {
1005 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 1154 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
1006 } 1155 }
1007 else 1156
1157 // Normalize
1158 vec_a = llVecNorm(vec_a);
1159 vec_b = llVecNorm(vec_b);
1160
1161 // Calculate axis and rotation angle
1162 LSL_Vector axis = vec_a % vec_b;
1163 LSL_Float cos_theta = vec_a * vec_b;
1164
1165 // Check if parallel
1166 if (cos_theta > 0.99999)
1008 { 1167 {
1009 a = LSL_Vector.Norm(a); 1168 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
1010 b = LSL_Vector.Norm(b); 1169 }
1011 double dotProduct = LSL_Vector.Dot(a, b); 1170
1012 // There are two degenerate cases possible. These are for vectors 180 or 1171 // Check if anti-parallel
1013 // 0 degrees apart. These have to be detected and handled individually. 1172 else if (cos_theta < -0.99999)
1014 // 1173 {
1015 // Check for vectors 180 degrees apart. 1174 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. 1175 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
1017 if (dotProduct < -0.9999999f) 1176 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
1018 { 1177 }
1019 // First assume X axis is orthogonal to the vectors. 1178 else // other rotation
1020 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 1179 {
1021 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 1180 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 1181 axis = llVecNorm(axis);
1023 // a rotation in an undesired direction. 1182 double x, y, z, s, t;
1024 if (LSL_Vector.Mag(orthoVector) > 0.0001) 1183 s = Math.Cos(theta);
1025 { 1184 t = Math.Sin(theta);
1026 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 1185 x = axis.x * t;
1027 } 1186 y = axis.y * t;
1028 // If the magnitude of the vector was near zero, then assume the X axis is not 1187 z = axis.z * t;
1029 // orthogonal and use the Z axis instead. 1188 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 } 1189 }
1068 return rotBetween;
1069 } 1190 }
1070 1191
1071 public void llWhisper(int channelID, string text) 1192 public void llWhisper(int channelID, string text)
1072 { 1193 {
1073 m_host.AddScriptLPS(1); 1194 m_host.AddScriptLPS(1);
@@ -1083,10 +1204,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1083 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 1204 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
1084 } 1205 }
1085 1206
1207 private void CheckSayShoutTime()
1208 {
1209 DateTime now = DateTime.UtcNow;
1210 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
1211 {
1212 m_lastSayShoutCheck = now;
1213 m_SayShoutCount = 0;
1214 }
1215 else
1216 m_SayShoutCount++;
1217 }
1218
1086 public void llSay(int channelID, string text) 1219 public void llSay(int channelID, string text)
1087 { 1220 {
1088 m_host.AddScriptLPS(1); 1221 m_host.AddScriptLPS(1);
1089 1222
1223 if (channelID == 0)
1224// m_SayShoutCount++;
1225 CheckSayShoutTime();
1226
1227 if (m_SayShoutCount >= 11)
1228 ScriptSleep(2000);
1229
1090 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 1230 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
1091 { 1231 {
1092 Console.WriteLine(text); 1232 Console.WriteLine(text);
@@ -1109,6 +1249,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1109 { 1249 {
1110 m_host.AddScriptLPS(1); 1250 m_host.AddScriptLPS(1);
1111 1251
1252 if (channelID == 0)
1253// m_SayShoutCount++;
1254 CheckSayShoutTime();
1255
1256 if (m_SayShoutCount >= 11)
1257 ScriptSleep(2000);
1258
1112 if (text.Length > 1023) 1259 if (text.Length > 1023)
1113 text = text.Substring(0, 1023); 1260 text = text.Substring(0, 1023);
1114 1261
@@ -1143,16 +1290,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1143 1290
1144 public void llRegionSayTo(string target, int channel, string msg) 1291 public void llRegionSayTo(string target, int channel, string msg)
1145 { 1292 {
1293 string error = String.Empty;
1294
1146 if (msg.Length > 1023) 1295 if (msg.Length > 1023)
1147 msg = msg.Substring(0, 1023); 1296 msg = msg.Substring(0, 1023);
1148 1297
1149 m_host.AddScriptLPS(1); 1298 m_host.AddScriptLPS(1);
1150 1299
1151 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
1152 {
1153 return;
1154 }
1155
1156 UUID TargetID; 1300 UUID TargetID;
1157 UUID.TryParse(target, out TargetID); 1301 UUID.TryParse(target, out TargetID);
1158 1302
@@ -1161,7 +1305,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1161 1305
1162 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1306 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
1163 if (wComm != null) 1307 if (wComm != null)
1164 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1308 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error));
1165 } 1309 }
1166 1310
1167 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1311 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1417,10 +1561,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1417 return detectedParams.TouchUV; 1561 return detectedParams.TouchUV;
1418 } 1562 }
1419 1563
1564 [DebuggerNonUserCode]
1420 public virtual void llDie() 1565 public virtual void llDie()
1421 { 1566 {
1422 m_host.AddScriptLPS(1); 1567 m_host.AddScriptLPS(1);
1423 throw new SelfDeleteException(); 1568 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1424 } 1569 }
1425 1570
1426 public LSL_Float llGround(LSL_Vector offset) 1571 public LSL_Float llGround(LSL_Vector offset)
@@ -1491,6 +1636,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1491 1636
1492 public void llSetStatus(int status, int value) 1637 public void llSetStatus(int status, int value)
1493 { 1638 {
1639 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1640 return;
1494 m_host.AddScriptLPS(1); 1641 m_host.AddScriptLPS(1);
1495 1642
1496 int statusrotationaxis = 0; 1643 int statusrotationaxis = 0;
@@ -1502,6 +1649,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1502 SceneObjectGroup group = m_host.ParentGroup; 1649 SceneObjectGroup group = m_host.ParentGroup;
1503 bool allow = true; 1650 bool allow = true;
1504 1651
1652 int maxprims = World.m_linksetPhysCapacity;
1653 bool checkShape = (maxprims > 0 && group.PrimCount > maxprims);
1654
1505 foreach (SceneObjectPart part in group.Parts) 1655 foreach (SceneObjectPart part in group.Parts)
1506 { 1656 {
1507 if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) 1657 if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys)
@@ -1509,11 +1659,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1509 allow = false; 1659 allow = false;
1510 break; 1660 break;
1511 } 1661 }
1662 if (checkShape && part.PhysicsShapeType != (byte)PhysicsShapeType.None)
1663 {
1664 if (--maxprims < 0)
1665 {
1666 allow = false;
1667 break;
1668 }
1669 }
1512 } 1670 }
1513 1671
1514 if (!allow) 1672 if (!allow)
1515 return; 1673 return;
1516 1674
1675 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1676 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1677 return;
1678
1517 m_host.ScriptSetPhysicsStatus(true); 1679 m_host.ScriptSetPhysicsStatus(true);
1518 } 1680 }
1519 else 1681 else
@@ -1712,12 +1874,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1712 { 1874 {
1713 m_host.AddScriptLPS(1); 1875 m_host.AddScriptLPS(1);
1714 1876
1877 SetColor(m_host, color, face);
1878 }
1879
1880 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1881 {
1882 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1883 return;
1884
1885 Primitive.TextureEntry tex = part.Shape.Textures;
1886 Color4 texcolor;
1887 if (face >= 0 && face < GetNumberOfSides(part))
1888 {
1889 texcolor = tex.CreateFace((uint)face).RGBA;
1890 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1891 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1892 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1893 tex.FaceTextures[face].RGBA = texcolor;
1894 part.UpdateTextureEntry(tex.GetBytes());
1895 return;
1896 }
1897 else if (face == ScriptBaseClass.ALL_SIDES)
1898 {
1899 for (uint i = 0; i < GetNumberOfSides(part); i++)
1900 {
1901 if (tex.FaceTextures[i] != null)
1902 {
1903 texcolor = tex.FaceTextures[i].RGBA;
1904 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1905 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1906 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1907 tex.FaceTextures[i].RGBA = texcolor;
1908 }
1909 texcolor = tex.DefaultTexture.RGBA;
1910 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1911 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1912 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1913 tex.DefaultTexture.RGBA = texcolor;
1914 }
1915 part.UpdateTextureEntry(tex.GetBytes());
1916 return;
1917 }
1918
1715 if (face == ScriptBaseClass.ALL_SIDES) 1919 if (face == ScriptBaseClass.ALL_SIDES)
1716 face = SceneObjectPart.ALL_SIDES; 1920 face = SceneObjectPart.ALL_SIDES;
1717 1921
1718 m_host.SetFaceColorAlpha(face, color, null); 1922 m_host.SetFaceColorAlpha(face, color, null);
1719 } 1923 }
1720 1924
1925 /*
1721 public void llSetContentType(LSL_Key id, LSL_Integer type) 1926 public void llSetContentType(LSL_Key id, LSL_Integer type)
1722 { 1927 {
1723 m_host.AddScriptLPS(1); 1928 m_host.AddScriptLPS(1);
@@ -1784,9 +1989,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1784 break; 1989 break;
1785 } 1990 }
1786 } 1991 }
1992 */
1787 1993
1788 public void SetTexGen(SceneObjectPart part, int face,int style) 1994 public void SetTexGen(SceneObjectPart part, int face,int style)
1789 { 1995 {
1996 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1997 return;
1998
1790 Primitive.TextureEntry tex = part.Shape.Textures; 1999 Primitive.TextureEntry tex = part.Shape.Textures;
1791 MappingType textype; 2000 MappingType textype;
1792 textype = MappingType.Default; 2001 textype = MappingType.Default;
@@ -1817,6 +2026,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1817 2026
1818 public void SetGlow(SceneObjectPart part, int face, float glow) 2027 public void SetGlow(SceneObjectPart part, int face, float glow)
1819 { 2028 {
2029 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2030 return;
2031
1820 Primitive.TextureEntry tex = part.Shape.Textures; 2032 Primitive.TextureEntry tex = part.Shape.Textures;
1821 if (face >= 0 && face < GetNumberOfSides(part)) 2033 if (face >= 0 && face < GetNumberOfSides(part))
1822 { 2034 {
@@ -1842,6 +2054,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1842 2054
1843 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 2055 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1844 { 2056 {
2057 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2058 return;
1845 2059
1846 Shininess sval = new Shininess(); 2060 Shininess sval = new Shininess();
1847 2061
@@ -1892,6 +2106,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1892 2106
1893 public void SetFullBright(SceneObjectPart part, int face, bool bright) 2107 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1894 { 2108 {
2109 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2110 return;
2111
1895 Primitive.TextureEntry tex = part.Shape.Textures; 2112 Primitive.TextureEntry tex = part.Shape.Textures;
1896 if (face >= 0 && face < GetNumberOfSides(part)) 2113 if (face >= 0 && face < GetNumberOfSides(part))
1897 { 2114 {
@@ -1952,13 +2169,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1952 m_host.AddScriptLPS(1); 2169 m_host.AddScriptLPS(1);
1953 2170
1954 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2171 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1955 2172 if (parts.Count > 0)
1956 foreach (SceneObjectPart part in parts) 2173 {
1957 SetAlpha(part, alpha, face); 2174 try
2175 {
2176 foreach (SceneObjectPart part in parts)
2177 SetAlpha(part, alpha, face);
2178 }
2179 finally
2180 {
2181 }
2182 }
1958 } 2183 }
1959 2184
1960 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 2185 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1961 { 2186 {
2187 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2188 return;
2189
1962 Primitive.TextureEntry tex = part.Shape.Textures; 2190 Primitive.TextureEntry tex = part.Shape.Textures;
1963 Color4 texcolor; 2191 Color4 texcolor;
1964 if (face >= 0 && face < GetNumberOfSides(part)) 2192 if (face >= 0 && face < GetNumberOfSides(part))
@@ -2011,7 +2239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2011 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 2239 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
2012 float wind, float tension, LSL_Vector Force) 2240 float wind, float tension, LSL_Vector Force)
2013 { 2241 {
2014 if (part == null) 2242 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2015 return; 2243 return;
2016 2244
2017 if (flexi) 2245 if (flexi)
@@ -2052,7 +2280,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2052 /// <param name="falloff"></param> 2280 /// <param name="falloff"></param>
2053 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 2281 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
2054 { 2282 {
2055 if (part == null) 2283 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2056 return; 2284 return;
2057 2285
2058 if (light) 2286 if (light)
@@ -2085,11 +2313,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2085 Primitive.TextureEntry tex = part.Shape.Textures; 2313 Primitive.TextureEntry tex = part.Shape.Textures;
2086 Color4 texcolor; 2314 Color4 texcolor;
2087 LSL_Vector rgb = new LSL_Vector(); 2315 LSL_Vector rgb = new LSL_Vector();
2316 int nsides = GetNumberOfSides(part);
2317
2088 if (face == ScriptBaseClass.ALL_SIDES) 2318 if (face == ScriptBaseClass.ALL_SIDES)
2089 { 2319 {
2090 int i; 2320 int i;
2091 2321 for (i = 0; i < nsides; i++)
2092 for (i = 0 ; i < GetNumberOfSides(part); i++)
2093 { 2322 {
2094 texcolor = tex.GetFace((uint)i).RGBA; 2323 texcolor = tex.GetFace((uint)i).RGBA;
2095 rgb.x += texcolor.R; 2324 rgb.x += texcolor.R;
@@ -2097,14 +2326,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2097 rgb.z += texcolor.B; 2326 rgb.z += texcolor.B;
2098 } 2327 }
2099 2328
2100 rgb.x /= (float)GetNumberOfSides(part); 2329 float invnsides = 1.0f / (float)nsides;
2101 rgb.y /= (float)GetNumberOfSides(part); 2330
2102 rgb.z /= (float)GetNumberOfSides(part); 2331 rgb.x *= invnsides;
2332 rgb.y *= invnsides;
2333 rgb.z *= invnsides;
2103 2334
2104 return rgb; 2335 return rgb;
2105 } 2336 }
2106 2337 if (face >= 0 && face < nsides)
2107 if (face >= 0 && face < GetNumberOfSides(part))
2108 { 2338 {
2109 texcolor = tex.GetFace((uint)face).RGBA; 2339 texcolor = tex.GetFace((uint)face).RGBA;
2110 rgb.x = texcolor.R; 2340 rgb.x = texcolor.R;
@@ -2131,15 +2361,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2131 m_host.AddScriptLPS(1); 2361 m_host.AddScriptLPS(1);
2132 2362
2133 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2363 List<SceneObjectPart> parts = GetLinkParts(linknumber);
2134 2364 if (parts.Count > 0)
2135 foreach (SceneObjectPart part in parts) 2365 {
2136 SetTexture(part, texture, face); 2366 try
2137 2367 {
2368 foreach (SceneObjectPart part in parts)
2369 SetTexture(part, texture, face);
2370 }
2371 finally
2372 {
2373 }
2374 }
2138 ScriptSleep(m_sleepMsOnSetLinkTexture); 2375 ScriptSleep(m_sleepMsOnSetLinkTexture);
2139 } 2376 }
2140 2377
2141 protected void SetTexture(SceneObjectPart part, string texture, int face) 2378 protected void SetTexture(SceneObjectPart part, string texture, int face)
2142 { 2379 {
2380 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2381 return;
2382
2143 UUID textureID = new UUID(); 2383 UUID textureID = new UUID();
2144 2384
2145 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 2385 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
@@ -2184,6 +2424,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2184 2424
2185 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2425 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
2186 { 2426 {
2427 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2428 return;
2429
2187 Primitive.TextureEntry tex = part.Shape.Textures; 2430 Primitive.TextureEntry tex = part.Shape.Textures;
2188 if (face >= 0 && face < GetNumberOfSides(part)) 2431 if (face >= 0 && face < GetNumberOfSides(part))
2189 { 2432 {
@@ -2220,6 +2463,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2220 2463
2221 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2464 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
2222 { 2465 {
2466 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2467 return;
2468
2223 Primitive.TextureEntry tex = part.Shape.Textures; 2469 Primitive.TextureEntry tex = part.Shape.Textures;
2224 if (face >= 0 && face < GetNumberOfSides(part)) 2470 if (face >= 0 && face < GetNumberOfSides(part))
2225 { 2471 {
@@ -2256,6 +2502,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2256 2502
2257 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2503 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
2258 { 2504 {
2505 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2506 return;
2507
2259 Primitive.TextureEntry tex = part.Shape.Textures; 2508 Primitive.TextureEntry tex = part.Shape.Textures;
2260 if (face >= 0 && face < GetNumberOfSides(part)) 2509 if (face >= 0 && face < GetNumberOfSides(part))
2261 { 2510 {
@@ -2397,7 +2646,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2397 return end; 2646 return end;
2398 } 2647 }
2399 2648
2400 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2649 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2401 { 2650 {
2402 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2651 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2403 return fromPos; 2652 return fromPos;
@@ -2413,9 +2662,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2413 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2662 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2414 targetPos.z = ground; 2663 targetPos.z = ground;
2415 } 2664 }
2416 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2665 if (adjust)
2666 return SetPosAdjust(fromPos, targetPos);
2417 2667
2418 return real_vec; 2668 return targetPos;
2419 } 2669 }
2420 2670
2421 /// <summary> 2671 /// <summary>
@@ -2426,27 +2676,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2426 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2676 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2427 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2677 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2428 { 2678 {
2429 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2679 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2680 return;
2681
2430 LSL_Vector currentPos = GetPartLocalPos(part); 2682 LSL_Vector currentPos = GetPartLocalPos(part);
2683 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2431 2684
2432 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2433 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2434 2685
2435 if (part.ParentGroup.RootPart == part) 2686 if (part.ParentGroup.RootPart == part)
2436 { 2687 {
2437 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2438 targetPos.z = ground;
2439 SceneObjectGroup parent = part.ParentGroup; 2688 SceneObjectGroup parent = part.ParentGroup;
2440 parent.UpdateGroupPosition(!adjust ? targetPos : 2689 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2441 SetPosAdjust(currentPos, targetPos)); 2690 return;
2691 Util.FireAndForget(delegate(object x) {
2692 parent.UpdateGroupPosition((Vector3)toPos);
2693 });
2442 } 2694 }
2443 else 2695 else
2444 { 2696 {
2445 part.OffsetPosition = !adjust ? targetPos : 2697 part.OffsetPosition = (Vector3)toPos;
2446 SetPosAdjust(currentPos, targetPos); 2698// SceneObjectGroup parent = part.ParentGroup;
2447 SceneObjectGroup parent = part.ParentGroup; 2699// parent.HasGroupChanged = true;
2448 parent.HasGroupChanged = true; 2700// parent.ScheduleGroupForTerseUpdate();
2449 parent.ScheduleGroupForTerseUpdate(); 2701 part.ScheduleTerseUpdate();
2450 } 2702 }
2451 } 2703 }
2452 2704
@@ -2475,13 +2727,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2475 else 2727 else
2476 { 2728 {
2477 if (part.ParentGroup.IsAttachment) 2729 if (part.ParentGroup.IsAttachment)
2478 {
2479 pos = part.AttachedPos; 2730 pos = part.AttachedPos;
2480 }
2481 else 2731 else
2482 {
2483 pos = part.AbsolutePosition; 2732 pos = part.AbsolutePosition;
2484 }
2485 } 2733 }
2486 2734
2487// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2735// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2493,8 +2741,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2493 { 2741 {
2494 m_host.AddScriptLPS(1); 2742 m_host.AddScriptLPS(1);
2495 2743
2744
2745 // Teravus: if (m_host.ParentID == 0) is bug code because the ParentID for the Avatar will cause this to be nonzero for root prim attachments
2746 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2747 // to fix the scripted rotations we also have to check to see if the root part localid is the same as the host's localid.
2748 // RootPart != null should shortcircuit
2749
2496 // try to let this work as in SL... 2750 // try to let this work as in SL...
2497 if (m_host.ParentID == 0) 2751 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2498 { 2752 {
2499 // special case: If we are root, rotate complete SOG to new rotation 2753 // special case: If we are root, rotate complete SOG to new rotation
2500 SetRot(m_host, rot); 2754 SetRot(m_host, rot);
@@ -2521,25 +2775,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2521 2775
2522 protected void SetRot(SceneObjectPart part, Quaternion rot) 2776 protected void SetRot(SceneObjectPart part, Quaternion rot)
2523 { 2777 {
2524 part.UpdateRotation(rot); 2778 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. 2779 return;
2526 2780
2527//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2781 bool isroot = (part == part.ParentGroup.RootPart);
2528// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2782 bool isphys;
2529 2783
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; 2784 PhysicsActor pa = part.PhysActor;
2538 2785
2539 if (pa != null && !pa.IsPhysical) 2786 // keep using physactor ideia of isphysical
2787 // it should be SOP ideia of that
2788 // not much of a issue with ubitODE
2789 if (pa != null && pa.IsPhysical)
2790 isphys = true;
2791 else
2792 isphys = false;
2793
2794 // SL doesn't let scripts rotate root of physical linksets
2795 if (isroot && isphys)
2796 return;
2797
2798 part.UpdateRotation(rot);
2799
2800 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2801 // so do a nasty update of parts positions if is a root part rotation
2802 if (isroot && pa != null) // with if above implies non physical root part
2540 { 2803 {
2541 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2804 part.ParentGroup.ResetChildPrimPhysicsPositions();
2542 } 2805 }
2806 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2807 {
2808 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2809 if (sittingavas.Count > 0)
2810 {
2811 foreach (ScenePresence av in sittingavas)
2812 {
2813 if (isroot || part.LocalId == av.ParentID)
2814 av.SendTerseUpdateToAllClients();
2815 }
2816 }
2817 }
2543 } 2818 }
2544 2819
2545 /// <summary> 2820 /// <summary>
@@ -2556,6 +2831,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2556 2831
2557 m_host.AddScriptLPS(1); 2832 m_host.AddScriptLPS(1);
2558 Quaternion q = m_host.GetWorldRotation(); 2833 Quaternion q = m_host.GetWorldRotation();
2834
2835 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2836 {
2837 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2838 if (avatar != null)
2839 {
2840 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2841 q = avatar.CameraRotation * q; // Mouselook
2842 else
2843 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2844 }
2845 }
2846
2559 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2847 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2560 } 2848 }
2561 2849
@@ -2583,14 +2871,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2583 return new LSL_Rotation(q); 2871 return new LSL_Rotation(q);
2584 } 2872 }
2585 2873
2586 return new LSL_Rotation(part.GetWorldRotation()); 2874 q = part.GetWorldRotation();
2875 if (part.ParentGroup.AttachmentPoint != 0)
2876 {
2877 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2878 if (avatar != null)
2879 {
2880 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2881 q = avatar.CameraRotation * q; // Mouselook
2882 else
2883 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2884 }
2885 }
2886
2887 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2587 } 2888 }
2588 2889
2589 public LSL_Rotation llGetLocalRot() 2890 public LSL_Rotation llGetLocalRot()
2590 { 2891 {
2591 m_host.AddScriptLPS(1); 2892 return GetPartLocalRot(m_host);
2893 }
2592 2894
2593 return new LSL_Rotation(m_host.RotationOffset); 2895 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2896 {
2897 m_host.AddScriptLPS(1);
2898 Quaternion rot = part.RotationOffset;
2899 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2594 } 2900 }
2595 2901
2596 public void llSetForce(LSL_Vector force, int local) 2902 public void llSetForce(LSL_Vector force, int local)
@@ -2620,32 +2926,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2620 return force; 2926 return force;
2621 } 2927 }
2622 2928
2623 public void llSetVelocity(LSL_Vector velocity, int local)
2624 {
2625 m_host.AddScriptLPS(1);
2626
2627 if (!m_host.ParentGroup.IsDeleted)
2628 {
2629 if (local != 0)
2630 velocity *= llGetRot();
2631
2632 m_host.ParentGroup.RootPart.Velocity = velocity;
2633 }
2634 }
2635
2636 public void llSetAngularVelocity(LSL_Vector angularVelocity, int local)
2637 {
2638 m_host.AddScriptLPS(1);
2639
2640 if (!m_host.ParentGroup.IsDeleted)
2641 {
2642 if (local != 0)
2643 angularVelocity *= llGetRot();
2644
2645 m_host.ParentGroup.RootPart.AngularVelocity = angularVelocity;
2646 }
2647 }
2648
2649 public LSL_Integer llTarget(LSL_Vector position, double range) 2929 public LSL_Integer llTarget(LSL_Vector position, double range)
2650 { 2930 {
2651 m_host.AddScriptLPS(1); 2931 m_host.AddScriptLPS(1);
@@ -2696,16 +2976,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2696 m_host.ApplyImpulse(v, local != 0); 2976 m_host.ApplyImpulse(v, local != 0);
2697 } 2977 }
2698 2978
2979
2699 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2980 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2700 { 2981 {
2701 m_host.AddScriptLPS(1); 2982 m_host.AddScriptLPS(1);
2702 m_host.ApplyAngularImpulse(force, local != 0); 2983 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2703 } 2984 }
2704 2985
2705 public void llSetTorque(LSL_Vector torque, int local) 2986 public void llSetTorque(LSL_Vector torque, int local)
2706 { 2987 {
2707 m_host.AddScriptLPS(1); 2988 m_host.AddScriptLPS(1);
2708 m_host.SetAngularImpulse(torque, local != 0); 2989 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2709 } 2990 }
2710 2991
2711 public LSL_Vector llGetTorque() 2992 public LSL_Vector llGetTorque()
@@ -2722,20 +3003,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2722 llSetTorque(torque, local); 3003 llSetTorque(torque, local);
2723 } 3004 }
2724 3005
3006 public void llSetVelocity(LSL_Vector vel, int local)
3007 {
3008 m_host.AddScriptLPS(1);
3009 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
3010 }
3011
2725 public LSL_Vector llGetVel() 3012 public LSL_Vector llGetVel()
2726 { 3013 {
2727 m_host.AddScriptLPS(1); 3014 m_host.AddScriptLPS(1);
2728 3015
2729 Vector3 vel; 3016 Vector3 vel = Vector3.Zero;
2730 3017
2731 if (m_host.ParentGroup.IsAttachment) 3018 if (m_host.ParentGroup.IsAttachment)
2732 { 3019 {
2733 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 3020 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2734 vel = avatar.GetWorldVelocity(); 3021 if (avatar != null)
3022 vel = avatar.GetWorldVelocity();
2735 } 3023 }
2736 else 3024 else
2737 { 3025 {
2738 vel = m_host.Velocity; 3026 vel = m_host.ParentGroup.RootPart.Velocity;
2739 } 3027 }
2740 3028
2741 return new LSL_Vector(vel); 3029 return new LSL_Vector(vel);
@@ -2748,11 +3036,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2748 return new LSL_Vector(m_host.Acceleration); 3036 return new LSL_Vector(m_host.Acceleration);
2749 } 3037 }
2750 3038
2751 public LSL_Vector llGetOmega() 3039 public void llSetAngularVelocity(LSL_Vector avel, int local)
2752 { 3040 {
2753 m_host.AddScriptLPS(1); 3041 m_host.AddScriptLPS(1);
3042 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
3043 }
2754 3044
2755 return new LSL_Vector(m_host.AngularVelocity); 3045 public LSL_Vector llGetOmega()
3046 {
3047 m_host.AddScriptLPS(1);
3048 Vector3 avel = m_host.AngularVelocity;
3049 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2756 } 3050 }
2757 3051
2758 public LSL_Float llGetTimeOfDay() 3052 public LSL_Float llGetTimeOfDay()
@@ -2806,7 +3100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2806 m_SoundModule.SendSound( 3100 m_SoundModule.SendSound(
2807 m_host.UUID, 3101 m_host.UUID,
2808 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), 3102 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound),
2809 volume, false, m_host.SoundQueueing ? (byte)SoundFlags.Queue : (byte)SoundFlags.None, 3103 volume, false, 0,
2810 0, false, false); 3104 0, false, false);
2811 } 3105 }
2812 } 3106 }
@@ -2817,7 +3111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2817 if (m_SoundModule != null) 3111 if (m_SoundModule != null)
2818 { 3112 {
2819 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 3113 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
2820 volume, 20, false); 3114 volume, 20, false,false);
2821 } 3115 }
2822 } 3116 }
2823 3117
@@ -2827,16 +3121,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2827 if (m_SoundModule != null) 3121 if (m_SoundModule != null)
2828 { 3122 {
2829 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 3123 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
2830 volume, 20, true); 3124 volume, 20, true, false);
2831 } 3125 }
2832 } 3126 }
2833 3127
2834 public void llLoopSoundSlave(string sound, double volume) 3128 public void llLoopSoundSlave(string sound, double volume)
2835 { 3129 {
2836 m_host.AddScriptLPS(1); 3130 m_host.AddScriptLPS(1);
2837 lock (m_host.ParentGroup.LoopSoundSlavePrims) 3131 if (m_SoundModule != null)
2838 { 3132 {
2839 m_host.ParentGroup.LoopSoundSlavePrims.Add(m_host); 3133 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
3134 volume, 20, false, true);
2840 } 3135 }
2841 } 3136 }
2842 3137
@@ -3111,7 +3406,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3111 return src.ToLower(); 3406 return src.ToLower();
3112 } 3407 }
3113 3408
3114 public void llGiveMoney(string destination, int amount) 3409 public LSL_Integer llGiveMoney(string destination, int amount)
3115 { 3410 {
3116 Util.FireAndForget(x => 3411 Util.FireAndForget(x =>
3117 { 3412 {
@@ -3142,9 +3437,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3142 return; 3437 return;
3143 } 3438 }
3144 3439
3440 string reason;
3145 money.ObjectGiveMoney( 3441 money.ObjectGiveMoney(
3146 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3442
3443 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero, out reason);
3147 }, null, "LSL_Api.llGiveMoney"); 3444 }, null, "LSL_Api.llGiveMoney");
3445
3446 return 0;
3148 } 3447 }
3149 3448
3150 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3449 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -3177,6 +3476,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3177 3476
3178 public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) 3477 public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
3179 { 3478 {
3479 doObjectRez(inventory, pos, vel, rot, param, true);
3480 }
3481
3482 public void doObjectRez(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param, bool atRoot)
3483 {
3180 m_host.AddScriptLPS(1); 3484 m_host.AddScriptLPS(1);
3181 3485
3182 Util.FireAndForget(x => 3486 Util.FireAndForget(x =>
@@ -3203,15 +3507,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3203 return; 3507 return;
3204 } 3508 }
3205 3509
3206 // need the magnitude later 3510 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 3511
3211 // If either of these are null, then there was an unknown error. 3512 // If either of these are null, then there was an unknown error.
3212 if (new_groups == null) 3513 if (new_groups == null)
3213 return; 3514 return;
3214 3515
3516 bool notAttachment = !m_host.ParentGroup.IsAttachment;
3517
3215 foreach (SceneObjectGroup group in new_groups) 3518 foreach (SceneObjectGroup group in new_groups)
3216 { 3519 {
3217 // objects rezzed with this method are die_at_edge by default. 3520 // objects rezzed with this method are die_at_edge by default.
@@ -3225,21 +3528,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3225 group.RootPart.UUID.ToString()) }, 3528 group.RootPart.UUID.ToString()) },
3226 new DetectParams[0])); 3529 new DetectParams[0]));
3227 3530
3228 float groupmass = group.GetMass(); 3531 if (notAttachment)
3532 {
3533 float groupmass = group.GetMass();
3229 3534
3230 PhysicsActor pa = group.RootPart.PhysActor; 3535 PhysicsActor pa = group.RootPart.PhysActor;
3231 3536
3232 //Recoil. 3537 //Recoil.
3233 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3538 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
3234 {
3235 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
3236 if (recoil != Vector3.Zero)
3237 { 3539 {
3238 llApplyImpulse(recoil, 0); 3540 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
3541 if (recoil != Vector3.Zero)
3542 {
3543 llApplyImpulse(recoil, 0);
3544 }
3239 } 3545 }
3240 } 3546 }
3241 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3547 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3242 } 3548 }
3549
3243 }, null, "LSL_Api.llRezAtRoot"); 3550 }, null, "LSL_Api.llRezAtRoot");
3244 3551
3245 //ScriptSleep((int)((groupmass * velmag) / 10)); 3552 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -3248,38 +3555,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3248 3555
3249 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) 3556 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
3250 { 3557 {
3251 llRezAtRoot(inventory, pos, vel, rot, param); 3558 doObjectRez(inventory, pos, vel, rot, param, false);
3252 } 3559 }
3253 3560
3254 public void llLookAt(LSL_Vector target, double strength, double damping) 3561 public void llLookAt(LSL_Vector target, double strength, double damping)
3255 { 3562 {
3256 m_host.AddScriptLPS(1); 3563 m_host.AddScriptLPS(1);
3257 // Determine where we are looking from
3258 LSL_Vector from = llGetPos();
3259 3564
3260 // normalized direction to target 3565 // Get the normalized vector to the target
3261 LSL_Vector dir = llVecNorm(target - from); 3566 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 3567
3269 // compute rotation based on orthogonal axes 3568 // Get the bearing (yaw)
3270 LSL_Rotation rot = new LSL_Rotation(0.0, 0.707107, 0.0, 0.707107) * llAxes2Rot(dir, left, up); 3569 LSL_Vector a1 = new LSL_Vector(0,0,0);
3570 a1.z = llAtan2(d1.y, d1.x);
3271 3571
3272 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3572 // Get the elevation (pitch)
3273 // set the rotation of the object, copy that behavior 3573 LSL_Vector a2 = new LSL_Vector(0,0,0);
3274 PhysicsActor pa = m_host.PhysActor; 3574 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
3275 3575
3276 if (m_host.ParentGroup.IsAttachment || strength == 0 || pa == null || !pa.IsPhysical) 3576 LSL_Rotation r1 = llEuler2Rot(a1);
3577 LSL_Rotation r2 = llEuler2Rot(a2);
3578 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
3579
3580 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
3277 { 3581 {
3278 llSetRot(rot); 3582 // Do nothing if either value is 0 (this has been checked in SL)
3583 if (strength <= 0.0 || damping <= 0.0)
3584 return;
3585
3586 llSetRot(r3 * r2 * r1);
3279 } 3587 }
3280 else 3588 else
3281 { 3589 {
3282 m_host.StartLookAt(rot, (float)strength, (float)damping); 3590 if (strength == 0)
3591 {
3592 llSetRot(r3 * r2 * r1);
3593 return;
3594 }
3595
3596 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
3283 } 3597 }
3284 } 3598 }
3285 3599
@@ -3325,22 +3639,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3325 } 3639 }
3326 else 3640 else
3327 { 3641 {
3328 if (m_host.IsRoot) 3642 // new SL always returns object mass
3329 { 3643// if (m_host.IsRoot)
3644// {
3330 return m_host.ParentGroup.GetMass(); 3645 return m_host.ParentGroup.GetMass();
3331 } 3646// }
3332 else 3647// else
3333 { 3648// {
3334 return m_host.GetMass(); 3649// return m_host.GetMass();
3335 } 3650// }
3336 } 3651 }
3337 } 3652 }
3338 3653
3339 public LSL_Float llGetMassMKS() 3654 public LSL_Float llGetMassMKS()
3340 { 3655 {
3341 // this is what the wiki says it does! 3656 return 100f * llGetMass();
3342 // http://wiki.secondlife.com/wiki/LlGetMassMKS
3343 return llGetMass() * 100.0;
3344 } 3657 }
3345 3658
3346 public void llCollisionFilter(string name, string id, int accept) 3659 public void llCollisionFilter(string name, string id, int accept)
@@ -3390,8 +3703,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3390 { 3703 {
3391 // Unregister controls from Presence 3704 // Unregister controls from Presence
3392 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3705 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3393 // Remove Take Control permission.
3394 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3395 } 3706 }
3396 } 3707 }
3397 } 3708 }
@@ -3419,7 +3730,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3419 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3730 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3420 3731
3421 if (attachmentsModule != null) 3732 if (attachmentsModule != null)
3422 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true); 3733 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3423 else 3734 else
3424 return false; 3735 return false;
3425 } 3736 }
@@ -3449,9 +3760,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3449 { 3760 {
3450 m_host.AddScriptLPS(1); 3761 m_host.AddScriptLPS(1);
3451 3762
3452// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3453// return;
3454
3455 if (m_item.PermsGranter != m_host.OwnerID) 3763 if (m_item.PermsGranter != m_host.OwnerID)
3456 return; 3764 return;
3457 3765
@@ -3495,7 +3803,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3495 public void llInstantMessage(string user, string message) 3803 public void llInstantMessage(string user, string message)
3496 { 3804 {
3497 m_host.AddScriptLPS(1); 3805 m_host.AddScriptLPS(1);
3498 3806 UUID result;
3807 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3808 {
3809 Error("llInstantMessage","An invalid key was passed to llInstantMessage");
3810 ScriptSleep(2000);
3811 return;
3812 }
3813
3499 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3814 // 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, 3815 // 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. 3816 // but I don't think we have a list of scenes available from here.
@@ -3505,31 +3820,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3505 3820
3506 // TODO: figure out values for client, fromSession, and imSessionID 3821 // 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()); 3822 // client.SendInstantMessage(m_host.UUID, fromSession, message, user, imSessionID, m_host.Name, AgentManager.InstantMessageDialog.MessageFromAgent, (uint)Util.UnixTimeSinceEpoch());
3823 UUID friendTransactionID = UUID.Random();
3508 3824
3825 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3826
3509 GridInstantMessage msg = new GridInstantMessage(); 3827 GridInstantMessage msg = new GridInstantMessage();
3510 msg.fromAgentID = new Guid(m_host.OwnerID.ToString()); // fromAgentID.Guid; 3828 msg.fromAgentID = new Guid(m_host.OwnerID.ToString()); // fromAgentID.Guid;
3511 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3829 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 3830 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); 3831 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3514// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3832 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
3515 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3833
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) 3834 if (message != null && message.Length > 1024)
3526 msg.message = message.Substring(0, 1024); 3835 msg.message = message.Substring(0, 1024);
3527 else 3836 else
3528 msg.message = message; 3837 msg.message = message;
3529 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3838 msg.dialog = (byte)19; // MessageFromObject
3530 msg.fromGroup = false;// fromGroup; 3839 msg.fromGroup = false;// fromGroup;
3531 msg.offline = (byte)0; //offline; 3840 msg.offline = (byte)0; //offline;
3532 msg.ParentEstateID = 0; //ParentEstateID; 3841 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3533 msg.Position = new Vector3(m_host.AbsolutePosition); 3842 msg.Position = new Vector3(m_host.AbsolutePosition);
3534 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3843 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3535 3844
@@ -3832,11 +4141,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3832 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 4141 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3833 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 4142 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3834 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 4143 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3835 ScriptBaseClass.PERMISSION_ATTACH; 4144 ScriptBaseClass.PERMISSION_ATTACH |
4145 ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS;
3836 } 4146 }
3837 else 4147 else
3838 { 4148 {
3839 if (m_host.ParentGroup.GetSittingAvatars().SingleOrDefault(sp => sp.UUID == agentID) != null) 4149 if (m_host.ParentGroup.GetSittingAvatars().SingleOrDefault(id => id == agentID) != null)
3840 { 4150 {
3841 // When agent is sitting, certain permissions are implicit if requested from sitting agent 4151 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3842 implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 4152 implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
@@ -3849,15 +4159,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3849 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 4159 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3850 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 4160 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3851 } 4161 }
4162 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
4163 {
4164 implicitPerms = perm;
4165 }
3852 } 4166 }
3853 4167
3854 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 4168 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3855 { 4169 {
3856 lock (m_host.TaskInventory) 4170 m_host.TaskInventory.LockItemsForWrite(true);
3857 { 4171 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3858 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 4172 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3859 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 4173 m_host.TaskInventory.LockItemsForWrite(false);
3860 }
3861 4174
3862 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 4175 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3863 "run_time_permissions", new Object[] { 4176 "run_time_permissions", new Object[] {
@@ -3901,11 +4214,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3901 4214
3902 if (!m_waitingForScriptAnswer) 4215 if (!m_waitingForScriptAnswer)
3903 { 4216 {
3904 lock (m_host.TaskInventory) 4217 m_host.TaskInventory.LockItemsForWrite(true);
3905 { 4218 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3906 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 4219 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3907 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 4220 m_host.TaskInventory.LockItemsForWrite(false);
3908 }
3909 4221
3910 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 4222 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3911 m_waitingForScriptAnswer=true; 4223 m_waitingForScriptAnswer=true;
@@ -3934,14 +4246,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3934 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 4246 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3935 llReleaseControls(); 4247 llReleaseControls();
3936 4248
3937 lock (m_host.TaskInventory) 4249 m_host.TaskInventory.LockItemsForWrite(true);
3938 { 4250 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3939 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 4251 m_host.TaskInventory.LockItemsForWrite(false);
3940 } 4252
3941 4253 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3942 m_ScriptEngine.PostScriptEvent( 4254 "run_time_permissions", new Object[] {
3943 m_item.ItemID, 4255 new LSL_Integer(answer) },
3944 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 4256 new DetectParams[0]));
3945 } 4257 }
3946 4258
3947 public LSL_String llGetPermissionsKey() 4259 public LSL_String llGetPermissionsKey()
@@ -3980,15 +4292,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3980 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 4292 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3981 { 4293 {
3982 List<SceneObjectPart> parts = GetLinkParts(linknumber); 4294 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3983 4295 if (parts.Count > 0)
3984 foreach (SceneObjectPart part in parts) 4296 {
3985 part.SetFaceColorAlpha(face, color, null); 4297 try
4298 {
4299 foreach (SceneObjectPart part in parts)
4300 part.SetFaceColorAlpha(face, color, null);
4301 }
4302 finally
4303 {
4304 }
4305 }
3986 } 4306 }
3987 4307
3988 public void llCreateLink(string target, int parent) 4308 public void llCreateLink(string target, int parent)
3989 { 4309 {
3990 m_host.AddScriptLPS(1); 4310 m_host.AddScriptLPS(1);
3991 4311
4312 UUID targetID;
4313
4314 if (!UUID.TryParse(target, out targetID))
4315 return;
4316
3992 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4317 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3993 && !m_automaticLinkPermission) 4318 && !m_automaticLinkPermission)
3994 { 4319 {
@@ -4104,10 +4429,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4104 // Restructuring Multiple Prims. 4429 // Restructuring Multiple Prims.
4105 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4430 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
4106 parts.Remove(parentPrim.RootPart); 4431 parts.Remove(parentPrim.RootPart);
4107 foreach (SceneObjectPart part in parts) 4432 if (parts.Count > 0)
4108 { 4433 {
4109 parentPrim.DelinkFromGroup(part.LocalId, true); 4434 try
4435 {
4436 foreach (SceneObjectPart part in parts)
4437 {
4438 parentPrim.DelinkFromGroup(part.LocalId, true);
4439 }
4440 }
4441 finally
4442 {
4443 }
4110 } 4444 }
4445
4111 parentPrim.HasGroupChanged = true; 4446 parentPrim.HasGroupChanged = true;
4112 parentPrim.ScheduleGroupForFullUpdate(); 4447 parentPrim.ScheduleGroupForFullUpdate();
4113 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4448 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -4116,12 +4451,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4116 { 4451 {
4117 SceneObjectPart newRoot = parts[0]; 4452 SceneObjectPart newRoot = parts[0];
4118 parts.Remove(newRoot); 4453 parts.Remove(newRoot);
4119 foreach (SceneObjectPart part in parts) 4454
4455 try
4120 { 4456 {
4121 // Required for linking 4457 foreach (SceneObjectPart part in parts)
4122 part.ClearUpdateSchedule(); 4458 {
4123 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4459 part.ClearUpdateSchedule();
4460 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4461 }
4124 } 4462 }
4463 finally
4464 {
4465 }
4466
4467
4125 newRoot.ParentGroup.HasGroupChanged = true; 4468 newRoot.ParentGroup.HasGroupChanged = true;
4126 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4469 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
4127 } 4470 }
@@ -4142,13 +4485,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4142 { 4485 {
4143 m_host.AddScriptLPS(1); 4486 m_host.AddScriptLPS(1);
4144 4487
4145 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4488 TaskInventoryItem item = m_item;
4489
4490 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4146 && !m_automaticLinkPermission) 4491 && !m_automaticLinkPermission)
4147 { 4492 {
4148 Error("llBreakAllLinks", "PERMISSION_CHANGE_LINKS permission not set"); 4493 Error("llBreakAllLinks","Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4149 return; 4494 return;
4150 } 4495 }
4151
4152 BreakAllLinks(); 4496 BreakAllLinks();
4153 } 4497 }
4154 4498
@@ -4173,13 +4517,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4173 public LSL_String llGetLinkKey(int linknum) 4517 public LSL_String llGetLinkKey(int linknum)
4174 { 4518 {
4175 m_host.AddScriptLPS(1); 4519 m_host.AddScriptLPS(1);
4520 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
4521 if (part != null)
4522 {
4523 return part.UUID.ToString();
4524 }
4525 else
4526 {
4527 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4528 {
4529 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4176 4530
4177 ISceneEntity entity = GetLinkEntity(m_host, linknum); 4531 if (linknum < 0)
4532 return UUID.Zero.ToString();
4178 4533
4179 if (entity != null) 4534 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4180 return entity.UUID.ToString(); 4535 if (avatars.Count > linknum)
4181 else 4536 {
4182 return ScriptBaseClass.NULL_KEY; 4537 return avatars[linknum].UUID.ToString();
4538 }
4539 }
4540 return UUID.Zero.ToString();
4541 }
4183 } 4542 }
4184 4543
4185 /// <summary> 4544 /// <summary>
@@ -4238,17 +4597,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4238 m_host.AddScriptLPS(1); 4597 m_host.AddScriptLPS(1);
4239 int count = 0; 4598 int count = 0;
4240 4599
4241 lock (m_host.TaskInventory) 4600 m_host.TaskInventory.LockItemsForRead(true);
4601 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4242 { 4602 {
4243 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4603 if (inv.Value.Type == type || type == -1)
4244 { 4604 {
4245 if (inv.Value.Type == type || type == -1) 4605 count = count + 1;
4246 {
4247 count = count + 1;
4248 }
4249 } 4606 }
4250 } 4607 }
4251 4608
4609 m_host.TaskInventory.LockItemsForRead(false);
4252 return count; 4610 return count;
4253 } 4611 }
4254 4612
@@ -4257,16 +4615,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4257 m_host.AddScriptLPS(1); 4615 m_host.AddScriptLPS(1);
4258 ArrayList keys = new ArrayList(); 4616 ArrayList keys = new ArrayList();
4259 4617
4260 lock (m_host.TaskInventory) 4618 m_host.TaskInventory.LockItemsForRead(true);
4619 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4261 { 4620 {
4262 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4621 if (inv.Value.Type == type || type == -1)
4263 { 4622 {
4264 if (inv.Value.Type == type || type == -1) 4623 keys.Add(inv.Value.Name);
4265 {
4266 keys.Add(inv.Value.Name);
4267 }
4268 } 4624 }
4269 } 4625 }
4626 m_host.TaskInventory.LockItemsForRead(false);
4270 4627
4271 if (keys.Count == 0) 4628 if (keys.Count == 0)
4272 { 4629 {
@@ -4336,6 +4693,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4336 } 4693 }
4337 } 4694 }
4338 } 4695 }
4696
4339 // destination is an avatar 4697 // destination is an avatar
4340 string message; 4698 string message;
4341 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId, out message); 4699 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId, out message);
@@ -4346,27 +4704,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4346 return; 4704 return;
4347 } 4705 }
4348 4706
4349 if (m_TransferModule != null) 4707 byte[] bucket = new byte[1];
4350 { 4708 bucket[0] = (byte)item.Type;
4351 byte[] bucket = new byte[1]; 4709 //byte[] objBytes = agentItem.ID.GetBytes();
4352 bucket[0] = (byte)item.Type; 4710 //Array.Copy(objBytes, 0, bucket, 1, 16);
4353 4711
4354 GridInstantMessage msg = new GridInstantMessage(World, 4712 GridInstantMessage msg = new GridInstantMessage(World,
4355 m_host.OwnerID, m_host.Name, destId, 4713 m_host.OwnerID, m_host.Name, destId,
4356 (byte)InstantMessageDialog.TaskInventoryOffered, 4714 (byte)InstantMessageDialog.TaskInventoryOffered,
4357 false, item.Name+". "+m_host.Name+" is located at "+ 4715 false, item.Name+". "+m_host.Name+" is located at "+
4358 World.RegionInfo.RegionName+" "+ 4716 World.RegionInfo.RegionName+" "+
4359 m_host.AbsolutePosition.ToString(), 4717 m_host.AbsolutePosition.ToString(),
4360 agentItem.ID, true, m_host.AbsolutePosition, 4718 agentItem.ID, true, m_host.AbsolutePosition,
4361 bucket, true); 4719 bucket, true);
4362 4720
4363 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4721 ScenePresence sp;
4364 }
4365 4722
4723 if (World.TryGetScenePresence(destId, out sp))
4724 {
4725 sp.ControllingClient.SendInstantMessage(msg);
4726 }
4727 else
4728 {
4729 if (m_TransferModule != null)
4730 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4731 }
4732
4733 //This delay should only occur when giving inventory to avatars.
4366 ScriptSleep(m_sleepMsOnGiveInventory); 4734 ScriptSleep(m_sleepMsOnGiveInventory);
4367 } 4735 }
4368 } 4736 }
4369 4737
4738 [DebuggerNonUserCode]
4370 public void llRemoveInventory(string name) 4739 public void llRemoveInventory(string name)
4371 { 4740 {
4372 m_host.AddScriptLPS(1); 4741 m_host.AddScriptLPS(1);
@@ -4421,14 +4790,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4421 { 4790 {
4422 m_host.AddScriptLPS(1); 4791 m_host.AddScriptLPS(1);
4423 4792
4424 UUID uuid = (UUID)id; 4793 UUID uuid;
4425 PresenceInfo pinfo = null; 4794 if (UUID.TryParse(id, out uuid))
4426 UserAccount account;
4427
4428 UserInfoCacheEntry ce;
4429
4430 lock (m_userInfoCache)
4431 { 4795 {
4796 PresenceInfo pinfo = null;
4797 UserAccount account;
4798
4799 UserInfoCacheEntry ce;
4432 if (!m_userInfoCache.TryGetValue(uuid, out ce)) 4800 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4433 { 4801 {
4434 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4802 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
@@ -4454,7 +4822,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4454 ce.time = Util.EnvironmentTickCount(); 4822 ce.time = Util.EnvironmentTickCount();
4455 ce.account = account; 4823 ce.account = account;
4456 ce.pinfo = pinfo; 4824 ce.pinfo = pinfo;
4457
4458 m_userInfoCache[uuid] = ce; 4825 m_userInfoCache[uuid] = ce;
4459 } 4826 }
4460 else 4827 else
@@ -4463,78 +4830,74 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4463 return UUID.Zero.ToString(); 4830 return UUID.Zero.ToString();
4464 4831
4465 account = ce.account; 4832 account = ce.account;
4833 pinfo = ce.pinfo;
4834 }
4466 4835
4467 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) 4836 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4468 >= LlRequestAgentDataCacheTimeoutMs) 4837 {
4838 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4839 if (pinfos != null && pinfos.Length > 0)
4469 { 4840 {
4470 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4841 foreach (PresenceInfo p in pinfos)
4471 if (pinfos != null && pinfos.Length > 0)
4472 { 4842 {
4473 foreach (PresenceInfo p in pinfos) 4843 if (p.RegionID != UUID.Zero)
4474 { 4844 {
4475 if (p.RegionID != UUID.Zero) 4845 pinfo = p;
4476 {
4477 pinfo = p;
4478 }
4479 } 4846 }
4480 } 4847 }
4481 else
4482 {
4483 pinfo = null;
4484 }
4485
4486 ce.time = Util.EnvironmentTickCount();
4487 ce.pinfo = pinfo;
4488 } 4848 }
4489 else 4849 else
4490 { 4850 pinfo = null;
4491 pinfo = ce.pinfo; 4851
4492 } 4852 ce.time = Util.EnvironmentTickCount();
4853 ce.pinfo = pinfo;
4493 } 4854 }
4494 }
4495 4855
4496 string reply = String.Empty; 4856 string reply = String.Empty;
4497 4857
4498 switch (data) 4858 switch (data)
4499 { 4859 {
4500 case ScriptBaseClass.DATA_ONLINE: 4860 case 1: // DATA_ONLINE (0|1)
4501 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4861 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4502 reply = "1"; 4862 reply = "1";
4503 else 4863 else
4504 reply = "0"; 4864 reply = "0";
4505 break; 4865 break;
4506 case ScriptBaseClass.DATA_NAME: // (First Last) 4866 case 2: // DATA_NAME (First Last)
4507 reply = account.FirstName + " " + account.LastName; 4867 reply = account.FirstName + " " + account.LastName;
4508 break; 4868 break;
4509 case ScriptBaseClass.DATA_BORN: // (YYYY-MM-DD) 4869 case 3: // DATA_BORN (YYYY-MM-DD)
4510 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4870 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4511 born = born.AddSeconds(account.Created); 4871 born = born.AddSeconds(account.Created);
4512 reply = born.ToString("yyyy-MM-dd"); 4872 reply = born.ToString("yyyy-MM-dd");
4513 break; 4873 break;
4514 case ScriptBaseClass.DATA_RATING: // (0,0,0,0,0,0) 4874 case 4: // DATA_RATING (0,0,0,0,0,0)
4515 reply = "0,0,0,0,0,0"; 4875 reply = "0,0,0,0,0,0";
4516 break; 4876 break;
4517 case 7: // DATA_USERLEVEL (integer). This is not available in LL and so has no constant. 4877 case 8: // DATA_PAYINFO (0|1|2|3)
4518 reply = account.UserLevel.ToString(); 4878 reply = "0";
4519 break; 4879 break;
4520 case ScriptBaseClass.DATA_PAYINFO: // (0|1|2|3) 4880 default:
4521 reply = "0"; 4881 return UUID.Zero.ToString(); // Raise no event
4522 break; 4882 }
4523 default:
4524 return UUID.Zero.ToString(); // Raise no event
4525 }
4526 4883
4527 UUID rq = UUID.Random(); 4884 UUID rq = UUID.Random();
4528 4885
4529 UUID tid = AsyncCommands. 4886 UUID tid = AsyncCommands.
4530 DataserverPlugin.RegisterRequest(m_host.LocalId, 4887 DataserverPlugin.RegisterRequest(m_host.LocalId,
4531 m_item.ItemID, rq.ToString()); 4888 m_item.ItemID, rq.ToString());
4532 4889
4533 AsyncCommands. 4890 AsyncCommands.
4534 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4891 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4535 4892
4536 ScriptSleep(m_sleepMsOnRequestAgentData); 4893 ScriptSleep(m_sleepMsOnRequestAgentData);
4537 return tid.ToString(); 4894 return tid.ToString();
4895 }
4896 else
4897 {
4898 Error("llRequestAgentData","Invalid UUID passed to llRequestAgentData.");
4899 }
4900 return "";
4538 } 4901 }
4539 4902
4540 public LSL_String llRequestInventoryData(string name) 4903 public LSL_String llRequestInventoryData(string name)
@@ -4588,12 +4951,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4588 if (UUID.TryParse(agent, out agentId)) 4951 if (UUID.TryParse(agent, out agentId))
4589 { 4952 {
4590 ScenePresence presence = World.GetScenePresence(agentId); 4953 ScenePresence presence = World.GetScenePresence(agentId);
4591 if (presence != null) 4954 if (presence != null && presence.PresenceType != PresenceType.Npc)
4592 { 4955 {
4956 // agent must not be a god
4957 if (presence.UserLevel >= 200) return;
4958
4593 // agent must be over the owners land 4959 // agent must be over the owners land
4594 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4960 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4595 { 4961 {
4596 World.TeleportClientHome(agentId, presence.ControllingClient); 4962 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4963 {
4964 // They can't be teleported home for some reason
4965 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4966 if (regionInfo != null)
4967 {
4968 World.RequestTeleportLocation(
4969 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4970 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4971 }
4972 }
4597 } 4973 }
4598 } 4974 }
4599 } 4975 }
@@ -4611,20 +4987,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4611 ScenePresence presence = World.GetScenePresence(agentId); 4987 ScenePresence presence = World.GetScenePresence(agentId);
4612 if (presence != null && presence.PresenceType != PresenceType.Npc) 4988 if (presence != null && presence.PresenceType != PresenceType.Npc)
4613 { 4989 {
4614 // agent must not be a god
4615 if (presence.GodLevel >= 200) return;
4616
4617 if (destination == String.Empty) 4990 if (destination == String.Empty)
4618 destination = World.RegionInfo.RegionName; 4991 destination = World.RegionInfo.RegionName;
4619 4992
4620 // agent must be over the owners land 4993 if (m_item.PermsGranter == agentId)
4621 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4994 {
4995 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4996 {
4997 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4998 }
4999 }
5000
5001 // agent must be wearing the object
5002 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4622 { 5003 {
4623 DoLLTeleport(presence, destination, targetPos, targetLookAt); 5004 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4624 } 5005 }
4625 else // or must be wearing the prim 5006 else
4626 { 5007 {
4627 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 5008 // agent must not be a god
5009 if (presence.GodLevel >= 200) return;
5010
5011 // agent must be over the owners land
5012 ILandObject agentLand = World.LandChannel.GetLandObject(presence.AbsolutePosition);
5013 ILandObject objectLand = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
5014 if (m_host.OwnerID == objectLand.LandData.OwnerID && m_host.OwnerID == agentLand.LandData.OwnerID)
4628 { 5015 {
4629 DoLLTeleport(presence, destination, targetPos, targetLookAt); 5016 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4630 } 5017 }
@@ -4642,20 +5029,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4642 5029
4643 if (UUID.TryParse(agent, out agentId)) 5030 if (UUID.TryParse(agent, out agentId))
4644 { 5031 {
5032 // This function is owner only!
5033 if (m_host.OwnerID != agentId)
5034 return;
5035
4645 ScenePresence presence = World.GetScenePresence(agentId); 5036 ScenePresence presence = World.GetScenePresence(agentId);
5037
5038 // Can't TP sitting avatars
5039 if (presence.ParentID != 0) // Sitting
5040 return;
5041
4646 if (presence != null && presence.PresenceType != PresenceType.Npc) 5042 if (presence != null && presence.PresenceType != PresenceType.Npc)
4647 { 5043 {
4648 // agent must not be a god 5044 if (m_item.PermsGranter == agentId)
4649 if (presence.GodLevel >= 200) return;
4650
4651 // agent must be over the owners land
4652 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4653 {
4654 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4655 }
4656 else // or must be wearing the prim
4657 { 5045 {
4658 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 5046 // If attached using llAttachToAvatarTemp, cowardly refuse
5047 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.ParentGroup.FromItemID == UUID.Zero)
5048 return;
5049
5050 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4659 { 5051 {
4660 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 5052 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4661 } 5053 }
@@ -4732,9 +5124,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4732 { 5124 {
4733 m_host.AddScriptLPS(1); 5125 m_host.AddScriptLPS(1);
4734 5126
5127 if(impact_sound == "")
5128 {
5129 m_host.CollisionSoundVolume = (float)impact_volume;
5130 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
5131 m_host.CollisionSoundType = 0;
5132 return;
5133 }
4735 // TODO: Parameter check logic required. 5134 // TODO: Parameter check logic required.
4736 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 5135 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4737 m_host.CollisionSoundVolume = (float)impact_volume; 5136 m_host.CollisionSoundVolume = (float)impact_volume;
5137 m_host.CollisionSoundType = 1;
4738 } 5138 }
4739 5139
4740 public LSL_String llGetAnimation(string id) 5140 public LSL_String llGetAnimation(string id)
@@ -4748,14 +5148,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4748 5148
4749 if (m_host.RegionHandle == presence.RegionHandle) 5149 if (m_host.RegionHandle == presence.RegionHandle)
4750 { 5150 {
4751 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4752
4753 if (presence != null) 5151 if (presence != null)
4754 { 5152 {
4755 AnimationSet currentAnims = presence.Animator.Animations; 5153// if (presence.SitGround)
4756 string currentAnimationState = String.Empty; 5154// return "Sitting on Ground";
4757 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 5155// if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4758 return currentAnimationState; 5156// return "Sitting";
5157
5158 string movementAnimation = presence.Animator.CurrentMovementAnimation;
5159 string lslMovementAnimation;
5160
5161 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
5162 return lslMovementAnimation;
4759 } 5163 }
4760 } 5164 }
4761 5165
@@ -4903,7 +5307,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4903 { 5307 {
4904 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 5308 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4905 float distance_term = distance * distance * distance; // Script Energy 5309 float distance_term = distance * distance * distance; // Script Energy
4906 float pusher_mass = m_host.GetMass(); 5310 // use total object mass and not part
5311 float pusher_mass = m_host.ParentGroup.GetMass();
4907 5312
4908 float PUSH_ATTENUATION_DISTANCE = 17f; 5313 float PUSH_ATTENUATION_DISTANCE = 17f;
4909 float PUSH_ATTENUATION_SCALE = 5f; 5314 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4938,7 +5343,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4938 { 5343 {
4939 if (local != 0) 5344 if (local != 0)
4940 { 5345 {
4941 applied_linear_impulse *= m_host.GetWorldRotation(); 5346// applied_linear_impulse *= m_host.GetWorldRotation();
5347 applied_linear_impulse *= pusheeav.GetWorldRotation();
4942 } 5348 }
4943 5349
4944 pa.AddForce(applied_linear_impulse, true); 5350 pa.AddForce(applied_linear_impulse, true);
@@ -5292,14 +5698,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5292 { 5698 {
5293 m_host.AddScriptLPS(1); 5699 m_host.AddScriptLPS(1);
5294 5700
5295 if (src == null) 5701 return src.Length;
5296 {
5297 return 0;
5298 }
5299 else
5300 {
5301 return src.Length;
5302 }
5303 } 5702 }
5304 5703
5305 public LSL_Integer llList2Integer(LSL_List src, int index) 5704 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5370,7 +5769,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5370 else if (src.Data[index] is LSL_Float) 5769 else if (src.Data[index] is LSL_Float)
5371 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5770 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5372 else if (src.Data[index] is LSL_String) 5771 else if (src.Data[index] is LSL_String)
5373 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5772 {
5773 string str = ((LSL_String) src.Data[index]).m_string;
5774 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5775 if (m != Match.Empty)
5776 {
5777 str = m.Value;
5778 double d = 0.0;
5779 if (!Double.TryParse(str, out d))
5780 return 0.0;
5781
5782 return d;
5783 }
5784 return 0.0;
5785 }
5374 return Convert.ToDouble(src.Data[index]); 5786 return Convert.ToDouble(src.Data[index]);
5375 } 5787 }
5376 catch (FormatException) 5788 catch (FormatException)
@@ -5674,7 +6086,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5674 } 6086 }
5675 } 6087 }
5676 } 6088 }
5677 else { 6089 else
6090 {
5678 object[] array = new object[src.Length]; 6091 object[] array = new object[src.Length];
5679 Array.Copy(src.Data, 0, array, 0, src.Length); 6092 Array.Copy(src.Data, 0, array, 0, src.Length);
5680 result = new LSL_List(array); 6093 result = new LSL_List(array);
@@ -5781,7 +6194,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5781 public LSL_Integer llGetRegionAgentCount() 6194 public LSL_Integer llGetRegionAgentCount()
5782 { 6195 {
5783 m_host.AddScriptLPS(1); 6196 m_host.AddScriptLPS(1);
5784 return new LSL_Integer(World.GetRootAgentCount()); 6197
6198 int count = 0;
6199 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
6200 count++;
6201 });
6202
6203 return new LSL_Integer(count);
5785 } 6204 }
5786 6205
5787 public LSL_Vector llGetRegionCorner() 6206 public LSL_Vector llGetRegionCorner()
@@ -5853,6 +6272,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5853 { 6272 {
5854 return ""; 6273 return "";
5855 } 6274 }
6275
5856 } 6276 }
5857 6277
5858 /// <summary> 6278 /// <summary>
@@ -5928,17 +6348,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5928 { 6348 {
5929 for (int i = 0; i < length; i++) 6349 for (int i = 0; i < length; i++)
5930 { 6350 {
6351 int needle = llGetListEntryType(test, 0).value;
6352 int haystack = llGetListEntryType(src, i).value;
6353
5931 // Why this piece of insanity? This is because most script constants are C# value types (e.g. int) 6354 // 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 6355 // 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. 6356 // 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. 6357 // 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)). 6358 // 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])) 6359 if ((needle == haystack) && (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i])))
5937 { 6360 {
5938 int j; 6361 int j;
5939 for (j = 1; j < test.Length; j++) 6362 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]))) 6363 {
6364 needle = llGetListEntryType(test, j).value;
6365 haystack = llGetListEntryType(src, i+j).value;
6366
6367 if ((needle != haystack) || (!(src.Data[i+j].Equals(test.Data[j]) || test.Data[j].Equals(src.Data[i+j]))))
5941 break; 6368 break;
6369 }
5942 6370
5943 if (j == test.Length) 6371 if (j == test.Length)
5944 { 6372 {
@@ -6087,6 +6515,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6087 flags |= ScriptBaseClass.AGENT_AWAY; 6515 flags |= ScriptBaseClass.AGENT_AWAY;
6088 } 6516 }
6089 6517
6518 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6519 UUID[] anims = agent.Animator.GetAnimationArray();
6520 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6521 {
6522 flags |= ScriptBaseClass.AGENT_BUSY;
6523 }
6524
6090 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6525 // 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) 6526 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
6092 { 6527 {
@@ -6134,6 +6569,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6134 flags |= ScriptBaseClass.AGENT_SITTING; 6569 flags |= ScriptBaseClass.AGENT_SITTING;
6135 } 6570 }
6136 6571
6572 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6573 {
6574 flags |= ScriptBaseClass.AGENT_MALE;
6575 }
6576
6137 return flags; 6577 return flags;
6138 } 6578 }
6139 6579
@@ -6288,9 +6728,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6288 6728
6289 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6729 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6290 6730
6291 foreach (SceneObjectPart part in parts) 6731 try
6732 {
6733 foreach (SceneObjectPart part in parts)
6734 {
6735 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6736 }
6737 }
6738 finally
6292 { 6739 {
6293 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6294 } 6740 }
6295 } 6741 }
6296 6742
@@ -6344,13 +6790,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6344 6790
6345 if (m_host.OwnerID == land.LandData.OwnerID) 6791 if (m_host.OwnerID == land.LandData.OwnerID)
6346 { 6792 {
6347 World.TeleportClientHome(agentID, presence.ControllingClient); 6793 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6794 presence.TeleportWithMomentum(p, null);
6795 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
6348 } 6796 }
6349 } 6797 }
6350 } 6798 }
6351 ScriptSleep(m_sleepMsOnEjectFromLand); 6799 ScriptSleep(m_sleepMsOnEjectFromLand);
6352 } 6800 }
6353 6801
6802 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6803 {
6804 return ParseString2List(str, separators, in_spacers, false);
6805 }
6806
6354 public LSL_Integer llOverMyLand(string id) 6807 public LSL_Integer llOverMyLand(string id)
6355 { 6808 {
6356 m_host.AddScriptLPS(1); 6809 m_host.AddScriptLPS(1);
@@ -6403,26 +6856,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6403 } 6856 }
6404 else 6857 else
6405 { 6858 {
6406 agentSize = GetAgentSize(avatar); 6859// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6860 Vector3 s = avatar.Appearance.AvatarSize;
6861 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
6407 } 6862 }
6408
6409 return agentSize; 6863 return agentSize;
6410 } 6864 }
6411 6865
6412 public LSL_Integer llSameGroup(string agent) 6866 public LSL_Integer llSameGroup(string id)
6413 { 6867 {
6414 m_host.AddScriptLPS(1); 6868 m_host.AddScriptLPS(1);
6415 UUID agentId = new UUID(); 6869 UUID uuid = new UUID();
6416 if (!UUID.TryParse(agent, out agentId)) 6870 if (!UUID.TryParse(id, out uuid))
6417 return new LSL_Integer(0); 6871 return new LSL_Integer(0);
6418 ScenePresence presence = World.GetScenePresence(agentId); 6872
6419 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6873 // Check if it's a group key
6420 return new LSL_Integer(0); 6874 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); 6875 return new LSL_Integer(1);
6424 else 6876
6877 // We got passed a UUID.Zero
6878 if (uuid == UUID.Zero)
6879 return new LSL_Integer(0);
6880
6881 // Handle the case where id names an avatar
6882 ScenePresence presence = World.GetScenePresence(uuid);
6883 if (presence != null)
6884 {
6885 if (presence.IsChildAgent)
6886 return new LSL_Integer(0);
6887
6888 IClientAPI client = presence.ControllingClient;
6889 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6890 return new LSL_Integer(1);
6891
6425 return new LSL_Integer(0); 6892 return new LSL_Integer(0);
6893 }
6894
6895 // Handle object case
6896 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6897 if (part != null)
6898 {
6899 // This will handle both deed and non-deed and also the no
6900 // group case
6901 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6902 return new LSL_Integer(1);
6903
6904 return new LSL_Integer(0);
6905 }
6906
6907 return new LSL_Integer(0);
6426 } 6908 }
6427 6909
6428 public void llUnSit(string id) 6910 public void llUnSit(string id)
@@ -6433,11 +6915,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6433 if (UUID.TryParse(id, out key)) 6915 if (UUID.TryParse(id, out key))
6434 { 6916 {
6435 ScenePresence av = World.GetScenePresence(key); 6917 ScenePresence av = World.GetScenePresence(key);
6436 List<ScenePresence> sittingAvatars = m_host.ParentGroup.GetSittingAvatars(); 6918 List<UUID> sittingAvatars = m_host.ParentGroup.GetSittingAvatars();
6437 6919
6438 if (av != null) 6920 if (av != null)
6439 { 6921 {
6440 if (sittingAvatars.Contains(av)) 6922 if (sittingAvatars.Contains(key))
6441 { 6923 {
6442 // if the avatar is sitting on this object, then 6924 // if the avatar is sitting on this object, then
6443 // we can unsit them. We don't want random scripts unsitting random people 6925 // we can unsit them. We don't want random scripts unsitting random people
@@ -7236,6 +7718,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7236 7718
7237 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7719 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
7238 { 7720 {
7721 // LSL quaternions can normalize to 0, normal Quaternions can't.
7722 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7723 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7724
7239 part.SitTargetPosition = offset; 7725 part.SitTargetPosition = offset;
7240 part.SitTargetOrientation = rot; 7726 part.SitTargetOrientation = rot;
7241 part.ParentGroup.HasGroupChanged = true; 7727 part.ParentGroup.HasGroupChanged = true;
@@ -7290,7 +7776,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7290 UUID key; 7776 UUID key;
7291 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 7777 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
7292 7778
7293 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 7779 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false))
7294 { 7780 {
7295 int expires = 0; 7781 int expires = 0;
7296 if (hours != 0) 7782 if (hours != 0)
@@ -7441,8 +7927,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7441 Error("llDialog", "No more than 12 buttons can be shown"); 7927 Error("llDialog", "No more than 12 buttons can be shown");
7442 return; 7928 return;
7443 } 7929 }
7444 string[] buts = new string[buttons.Length]; 7930 int length = buttons.Length;
7445 for (int i = 0; i < buttons.Length; i++) 7931 if (length > 12)
7932 length = 12;
7933
7934 string[] buts = new string[length];
7935 for (int i = 0; i < length; i++)
7446 { 7936 {
7447 if (buttons.Data[i].ToString() == String.Empty) 7937 if (buttons.Data[i].ToString() == String.Empty)
7448 { 7938 {
@@ -7513,9 +8003,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7513 return; 8003 return;
7514 } 8004 }
7515 8005
7516 // the rest of the permission checks are done in RezScript, so check the pin there as well 8006 SceneObjectPart dest = World.GetSceneObjectPart(destId);
7517 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 8007 if (dest != null)
8008 {
8009 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
8010 {
8011 // the rest of the permission checks are done in RezScript, so check the pin there as well
8012 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
7518 8013
8014 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
8015 m_host.Inventory.RemoveInventoryItem(item.ItemID);
8016 }
8017 }
7519 // this will cause the delay even if the script pin or permissions were wrong - seems ok 8018 // this will cause the delay even if the script pin or permissions were wrong - seems ok
7520 ScriptSleep(m_sleepMsOnRemoteLoadScriptPin); 8019 ScriptSleep(m_sleepMsOnRemoteLoadScriptPin);
7521 } 8020 }
@@ -7589,19 +8088,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7589 public LSL_String llMD5String(string src, int nonce) 8088 public LSL_String llMD5String(string src, int nonce)
7590 { 8089 {
7591 m_host.AddScriptLPS(1); 8090 m_host.AddScriptLPS(1);
7592 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 8091 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
7593 } 8092 }
7594 8093
7595 public LSL_String llSHA1String(string src) 8094 public LSL_String llSHA1String(string src)
7596 { 8095 {
7597 m_host.AddScriptLPS(1); 8096 m_host.AddScriptLPS(1);
7598 return Util.SHA1Hash(src).ToLower(); 8097 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
7599 } 8098 }
7600 8099
7601 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 8100 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
7602 { 8101 {
7603 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 8102 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7604 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 8103 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
8104 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8105 return shapeBlock;
7605 8106
7606 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 8107 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
7607 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 8108 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -7706,6 +8207,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7706 // Prim type box, cylinder and prism. 8207 // 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) 8208 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 { 8209 {
8210 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8211 return;
8212
7709 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 8213 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7710 ObjectShapePacket.ObjectDataBlock shapeBlock; 8214 ObjectShapePacket.ObjectDataBlock shapeBlock;
7711 8215
@@ -7759,6 +8263,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7759 // Prim type sphere. 8263 // 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) 8264 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7761 { 8265 {
8266 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8267 return;
8268
7762 ObjectShapePacket.ObjectDataBlock shapeBlock; 8269 ObjectShapePacket.ObjectDataBlock shapeBlock;
7763 8270
7764 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 8271 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7805,6 +8312,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7805 // Prim type torus, tube and ring. 8312 // 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) 8313 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 { 8314 {
8315 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8316 return;
8317
7808 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 8318 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7809 ObjectShapePacket.ObjectDataBlock shapeBlock; 8319 ObjectShapePacket.ObjectDataBlock shapeBlock;
7810 8320
@@ -7940,6 +8450,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7940 // Prim type sculpt. 8450 // Prim type sculpt.
7941 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 8451 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7942 { 8452 {
8453 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8454 return;
8455
7943 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 8456 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7944 UUID sculptId; 8457 UUID sculptId;
7945 8458
@@ -7962,7 +8475,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7962 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 8475 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7963 { 8476 {
7964 // default 8477 // default
7965 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 8478 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7966 } 8479 }
7967 8480
7968 part.Shape.SetSculptProperties((byte)type, sculptId); 8481 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7995,9 +8508,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7995 SetLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 8508 SetLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7996 } 8509 }
7997 8510
7998 protected void SetLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 8511 private void SetLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7999 { 8512 {
8000 SetEntityParams(GetLinkEntities(linknumber), rules, originFunc); 8513 List<object> parts = new List<object>();
8514 List<SceneObjectPart> prims = GetLinkParts(linknumber);
8515 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
8516 foreach (SceneObjectPart p in prims)
8517 parts.Add(p);
8518 foreach (ScenePresence p in avatars)
8519 parts.Add(p);
8520
8521 LSL_List remaining = new LSL_List();
8522 uint rulesParsed = 0;
8523
8524 if (parts.Count > 0)
8525 {
8526 foreach (object part in parts)
8527 {
8528 if (part is SceneObjectPart)
8529 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
8530 else
8531 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
8532 }
8533
8534 while (remaining.Length > 2)
8535 {
8536 linknumber = remaining.GetLSLIntegerItem(0);
8537 rules = remaining.GetSublist(1, -1);
8538 parts.Clear();
8539 prims = GetLinkParts(linknumber);
8540 avatars = GetLinkAvatars(linknumber);
8541 foreach (SceneObjectPart p in prims)
8542 parts.Add(p);
8543 foreach (ScenePresence p in avatars)
8544 parts.Add(p);
8545
8546 remaining = new LSL_List();
8547 foreach (object part in parts)
8548 {
8549 if (part is SceneObjectPart)
8550 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
8551 else
8552 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
8553 }
8554 }
8555 }
8001 } 8556 }
8002 8557
8003 protected void SetEntityParams(List<ISceneEntity> entities, LSL_List rules, string originFunc) 8558 protected void SetEntityParams(List<ISceneEntity> entities, LSL_List rules, string originFunc)
@@ -8039,148 +8594,82 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8039 } 8594 }
8040 } 8595 }
8041 8596
8042 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
8043 {
8044 SceneObjectGroup group = m_host.ParentGroup;
8045 8597
8046 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical) 8598 public LSL_List llGetPhysicsMaterial()
8047 return; 8599 {
8048 if (group.IsAttachment) 8600 LSL_List result = new LSL_List();
8049 return;
8050
8051 if (frames.Data.Length > 0) // We are getting a new motion
8052 {
8053 if (group.RootPart.KeyframeMotion != null)
8054 group.RootPart.KeyframeMotion.Delete();
8055 group.RootPart.KeyframeMotion = null;
8056
8057 int idx = 0;
8058
8059 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
8060 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
8061
8062 while (idx < options.Data.Length)
8063 {
8064 int option = (int)options.GetLSLIntegerItem(idx++);
8065 int remain = options.Data.Length - idx;
8066
8067 switch (option)
8068 {
8069 case ScriptBaseClass.KFM_MODE:
8070 if (remain < 1)
8071 break;
8072 int modeval = (int)options.GetLSLIntegerItem(idx++);
8073 switch(modeval)
8074 {
8075 case ScriptBaseClass.KFM_FORWARD:
8076 mode = KeyframeMotion.PlayMode.Forward;
8077 break;
8078 case ScriptBaseClass.KFM_REVERSE:
8079 mode = KeyframeMotion.PlayMode.Reverse;
8080 break;
8081 case ScriptBaseClass.KFM_LOOP:
8082 mode = KeyframeMotion.PlayMode.Loop;
8083 break;
8084 case ScriptBaseClass.KFM_PING_PONG:
8085 mode = KeyframeMotion.PlayMode.PingPong;
8086 break;
8087 }
8088 break;
8089 case ScriptBaseClass.KFM_DATA:
8090 if (remain < 1)
8091 break;
8092 int dataval = (int)options.GetLSLIntegerItem(idx++);
8093 data = (KeyframeMotion.DataFormat)dataval;
8094 break;
8095 }
8096 }
8097
8098 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
8099
8100 idx = 0;
8101 8601
8102 int elemLength = 2; 8602 result.Add(new LSL_Float(m_host.GravityModifier));
8103 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation)) 8603 result.Add(new LSL_Float(m_host.Restitution));
8104 elemLength = 3; 8604 result.Add(new LSL_Float(m_host.Friction));
8605 result.Add(new LSL_Float(m_host.Density));
8105 8606
8106 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>(); 8607 return result;
8107 while (idx < frames.Data.Length) 8608 }
8108 {
8109 int remain = frames.Data.Length - idx;
8110 8609
8111 if (remain < elemLength) 8610 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
8112 break; 8611 float material_density, float material_friction,
8612 float material_restitution, float material_gravity_modifier)
8613 {
8614 ExtraPhysicsData physdata = new ExtraPhysicsData();
8615 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
8616 physdata.Density = part.Density;
8617 physdata.Friction = part.Friction;
8618 physdata.Bounce = part.Restitution;
8619 physdata.GravitationModifier = part.GravityModifier;
8113 8620
8114 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe(); 8621 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
8115 frame.Position = null; 8622 physdata.Density = material_density;
8116 frame.Rotation = null; 8623 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
8624 physdata.Friction = material_friction;
8625 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
8626 physdata.Bounce = material_restitution;
8627 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
8628 physdata.GravitationModifier = material_gravity_modifier;
8117 8629
8118 if ((data & KeyframeMotion.DataFormat.Translation) != 0) 8630 part.UpdateExtraPhysics(physdata);
8119 { 8631 }
8120 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
8121 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
8122 }
8123 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
8124 {
8125 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
8126 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
8127 q.Normalize();
8128 frame.Rotation = q;
8129 }
8130 8632
8131 float tempf = (float)frames.GetLSLFloatItem(idx++); 8633 public void llSetPhysicsMaterial(int material_bits,
8132 frame.TimeMS = (int)(tempf * 1000.0f); 8634 float material_gravity_modifier, float material_restitution,
8635 float material_friction, float material_density)
8636 {
8637 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8638 }
8133 8639
8134 keyframes.Add(frame); 8640 // vector up using libomv (c&p from sop )
8135 } 8641 // vector up rotated by r
8642 private Vector3 Zrot(Quaternion r)
8643 {
8644 double x, y, z, m;
8136 8645
8137 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray()); 8646 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
8138 group.RootPart.KeyframeMotion.Start(); 8647 if (Math.Abs(1.0 - m) > 0.000001)
8139 }
8140 else
8141 { 8648 {
8142 if (group.RootPart.KeyframeMotion == null) 8649 m = 1.0 / Math.Sqrt(m);
8143 return; 8650 r.X *= (float)m;
8144 8651 r.Y *= (float)m;
8145 if (options.Data.Length == 0) 8652 r.Z *= (float)m;
8146 { 8653 r.W *= (float)m;
8147 group.RootPart.KeyframeMotion.Stop(); 8654 }
8148 return;
8149 }
8150
8151 int idx = 0;
8152 8655
8153 while (idx < options.Data.Length) 8656 x = 2 * (r.X * r.Z + r.Y * r.W);
8154 { 8657 y = 2 * (-r.X * r.W + r.Y * r.Z);
8155 int option = (int)options.GetLSLIntegerItem(idx++); 8658 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
8156 8659
8157 switch (option) 8660 return new Vector3((float)x, (float)y, (float)z);
8158 {
8159 case ScriptBaseClass.KFM_COMMAND:
8160 int cmd = (int)options.GetLSLIntegerItem(idx++);
8161 switch (cmd)
8162 {
8163 case ScriptBaseClass.KFM_CMD_PLAY:
8164 group.RootPart.KeyframeMotion.Start();
8165 break;
8166 case ScriptBaseClass.KFM_CMD_STOP:
8167 group.RootPart.KeyframeMotion.Stop();
8168 break;
8169 case ScriptBaseClass.KFM_CMD_PAUSE:
8170 group.RootPart.KeyframeMotion.Pause();
8171 break;
8172 }
8173 break;
8174 }
8175 }
8176 }
8177 } 8661 }
8178 8662
8179 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 8663 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
8180 { 8664 {
8665 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8666 return new LSL_List();
8667
8181 int idx = 0; 8668 int idx = 0;
8182 int idxStart = 0; 8669 int idxStart = 0;
8183 8670
8671 SceneObjectGroup parentgrp = part.ParentGroup;
8672
8184 bool positionChanged = false; 8673 bool positionChanged = false;
8185 LSL_Vector currentPosition = GetPartLocalPos(part); 8674 LSL_Vector currentPosition = GetPartLocalPos(part);
8186 8675
@@ -8204,20 +8693,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8204 if (remain < 1) 8693 if (remain < 1)
8205 return new LSL_List(); 8694 return new LSL_List();
8206 8695
8207 try 8696 v=rules.GetVector3Item(idx++);
8208 { 8697 if (part.IsRoot && !part.ParentGroup.IsAttachment)
8209 v = rules.GetVector3Item(idx++); 8698 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
8210 } 8699 else
8211 catch(InvalidCastException) 8700 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
8212 {
8213 if(code == ScriptBaseClass.PRIM_POSITION)
8214 Error(originFunc, string.Format("Error running rule #{0} -> PRIM_POSITION: arg #{1} - parameter 1 must be vector", rulesParsed, idx - idxStart - 1));
8215 else
8216 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();
8218 }
8219 positionChanged = true; 8701 positionChanged = true;
8220 currentPosition = GetSetPosTarget(part, v, currentPosition);
8221 8702
8222 break; 8703 break;
8223 case ScriptBaseClass.PRIM_SIZE: 8704 case ScriptBaseClass.PRIM_SIZE:
@@ -8242,7 +8723,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8242 return new LSL_List(); 8723 return new LSL_List();
8243 } 8724 }
8244 // try to let this work as in SL... 8725 // try to let this work as in SL...
8245 if (part.ParentID == 0) 8726 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
8246 { 8727 {
8247 // special case: If we are root, rotate complete SOG to new rotation 8728 // special case: If we are root, rotate complete SOG to new rotation
8248 SetRot(part, q); 8729 SetRot(part, q);
@@ -9243,7 +9724,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9243 9724
9244 break; 9725 break;
9245 9726
9246 case ScriptBaseClass.PRIM_TEMP_ON_REZ: 9727 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
9728 if (remain < 5)
9729 return new LSL_List();
9730
9731 int material_bits = rules.GetLSLIntegerItem(idx++);
9732 float material_density = (float)rules.GetLSLFloatItem(idx++);
9733 float material_friction = (float)rules.GetLSLFloatItem(idx++);
9734 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
9735 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
9736
9737 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
9738
9739 break;
9740
9741 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
9247 if (remain < 1) 9742 if (remain < 1)
9248 return new LSL_List(); 9743 return new LSL_List();
9249 string temp = rules.Data[idx++].ToString(); 9744 string temp = rules.Data[idx++].ToString();
@@ -9437,14 +9932,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9437 if (part.ParentGroup.RootPart == part) 9932 if (part.ParentGroup.RootPart == part)
9438 { 9933 {
9439 SceneObjectGroup parent = part.ParentGroup; 9934 SceneObjectGroup parent = part.ParentGroup;
9440 parent.UpdateGroupPosition(currentPosition); 9935 Util.FireAndForget(delegate(object x) {
9936 parent.UpdateGroupPosition(currentPosition);
9937 });
9441 } 9938 }
9442 else 9939 else
9443 { 9940 {
9444 part.OffsetPosition = currentPosition; 9941 part.OffsetPosition = currentPosition;
9445 SceneObjectGroup parent = part.ParentGroup; 9942// SceneObjectGroup parent = part.ParentGroup;
9446 parent.HasGroupChanged = true; 9943// parent.HasGroupChanged = true;
9447 parent.ScheduleGroupForTerseUpdate(); 9944// parent.ScheduleGroupForTerseUpdate();
9945 part.ScheduleTerseUpdate();
9448 } 9946 }
9449 } 9947 }
9450 } 9948 }
@@ -9596,10 +10094,104 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9596 10094
9597 public LSL_String llXorBase64Strings(string str1, string str2) 10095 public LSL_String llXorBase64Strings(string str1, string str2)
9598 { 10096 {
10097 int padding = 0;
10098
10099 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
10100
10101 ScriptSleep(300);
9599 m_host.AddScriptLPS(1); 10102 m_host.AddScriptLPS(1);
9600 Deprecated("llXorBase64Strings", "Use llXorBase64 instead"); 10103
9601 ScriptSleep(m_sleepMsOnXorBase64Strings); 10104 if (str1 == String.Empty)
9602 return String.Empty; 10105 return String.Empty;
10106 if (str2 == String.Empty)
10107 return str1;
10108
10109 int len = str2.Length;
10110 if ((len % 4) != 0) // LL is EVIL!!!!
10111 {
10112 while (str2.EndsWith("="))
10113 str2 = str2.Substring(0, str2.Length - 1);
10114
10115 len = str2.Length;
10116 int mod = len % 4;
10117
10118 if (mod == 1)
10119 str2 = str2.Substring(0, str2.Length - 1);
10120 else if (mod == 2)
10121 str2 += "==";
10122 else if (mod == 3)
10123 str2 += "=";
10124 }
10125
10126 byte[] data1;
10127 byte[] data2;
10128 try
10129 {
10130 data1 = Convert.FromBase64String(str1);
10131 data2 = Convert.FromBase64String(str2);
10132 }
10133 catch (Exception)
10134 {
10135 return new LSL_String(String.Empty);
10136 }
10137
10138 // For cases where the decoded length of s2 is greater
10139 // than the decoded length of s1, simply perform a normal
10140 // decode and XOR
10141 //
10142 /*
10143 if (data2.Length >= data1.Length)
10144 {
10145 for (int pos = 0 ; pos < data1.Length ; pos++ )
10146 data1[pos] ^= data2[pos];
10147
10148 return Convert.ToBase64String(data1);
10149 }
10150 */
10151
10152 // Remove padding
10153 while (str1.EndsWith("="))
10154 {
10155 str1 = str1.Substring(0, str1.Length - 1);
10156 padding++;
10157 }
10158 while (str2.EndsWith("="))
10159 str2 = str2.Substring(0, str2.Length - 1);
10160
10161 byte[] d1 = new byte[str1.Length];
10162 byte[] d2 = new byte[str2.Length];
10163
10164 for (int i = 0 ; i < str1.Length ; i++)
10165 {
10166 int idx = b64.IndexOf(str1.Substring(i, 1));
10167 if (idx == -1)
10168 idx = 0;
10169 d1[i] = (byte)idx;
10170 }
10171
10172 for (int i = 0 ; i < str2.Length ; i++)
10173 {
10174 int idx = b64.IndexOf(str2.Substring(i, 1));
10175 if (idx == -1)
10176 idx = 0;
10177 d2[i] = (byte)idx;
10178 }
10179
10180 string output = String.Empty;
10181
10182 for (int pos = 0 ; pos < d1.Length ; pos++)
10183 output += b64[d1[pos] ^ d2[pos % d2.Length]];
10184
10185 // Here's a funny thing: LL blithely violate the base64
10186 // standard pretty much everywhere. Here, padding is
10187 // added only if the first input string had it, rather
10188 // than when the data actually needs it. This can result
10189 // in invalid base64 being returned. Go figure.
10190
10191 while (padding-- > 0)
10192 output += "=";
10193
10194 return output;
9603 } 10195 }
9604 10196
9605 public void llRemoteDataSetRegion() 10197 public void llRemoteDataSetRegion()
@@ -9724,8 +10316,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9724 public LSL_Integer llGetNumberOfPrims() 10316 public LSL_Integer llGetNumberOfPrims()
9725 { 10317 {
9726 m_host.AddScriptLPS(1); 10318 m_host.AddScriptLPS(1);
9727 10319 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
9728 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 10320
10321 return m_host.ParentGroup.PrimCount + avatarCount;
9729 } 10322 }
9730 10323
9731 /// <summary> 10324 /// <summary>
@@ -9742,646 +10335,191 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9742 public LSL_List llGetBoundingBox(string obj) 10335 public LSL_List llGetBoundingBox(string obj)
9743 { 10336 {
9744 m_host.AddScriptLPS(1); 10337 m_host.AddScriptLPS(1);
9745
9746 // Get target avatar if non-seated avatar or attachment, or prim and object
9747 UUID objID = UUID.Zero; 10338 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(); 10339 LSL_List result = new LSL_List();
9773 int groupCount = 0; 10340
9774 int partCount = 0; 10341 // If the ID is not valid, return null result
9775 int vertexCount = 0; 10342 if (!UUID.TryParse(obj, out objID))
9776 if (target == null && agent == null)
9777 { 10343 {
9778 result.Add(new LSL_Vector()); 10344 result.Add(new LSL_Vector());
9779 result.Add(new LSL_Vector()); 10345 result.Add(new LSL_Vector());
9780 if (m_addStatsInGetBoundingBox)
9781 result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount));
9782 return result; 10346 return result;
9783 } 10347 }
9784 Vector3 minPosition = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
9785 Vector3 maxPosition = new Vector3(float.MinValue, float.MinValue, float.MinValue);
9786 10348
9787 // Try to get a mesher 10349 // Check if this is an attached prim. If so, replace
9788 IRendering primMesher = null; 10350 // the UUID with the avatar UUID and report it's bounding box
9789 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); 10351 SceneObjectPart part = World.GetSceneObjectPart(objID);
9790 if (renderers.Count > 0) 10352 if (part != null && part.ParentGroup.IsAttachment)
9791 primMesher = RenderingLoader.LoadRenderer(renderers[0]); 10353 objID = part.ParentGroup.AttachedAvatar;
9792 10354
9793 // Get bounding box of just avatar, seated or not 10355 // Find out if this is an avatar ID. If so, return it's box
9794 if (agent != null) 10356 ScenePresence presence = World.GetScenePresence(objID);
9795 { 10357 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 { 10358 {
9817 // Merge bounding boxes of all parts (prims and mesh) 10359 // As per LSL Wiki, there is no difference between sitting
9818 foreach (SceneObjectPart part in group.Parts) 10360 // and standing avatar since server 1.36
9819 { 10361 LSL_Vector lower;
9820 bool hasParent = (!part.IsRoot); 10362 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 10363
9870 // When part is prim 10364 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 10365
9881 // When all else fails, try fallback to simple box 10366 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
9882 else 10367 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
9883 { 10368/*
9884 AddBoundingBoxOfSimpleBox(part.Scale * -0.5f, part.Scale * 0.5f, part.OffsetPosition, part.RotationOffset, hasParent, ref minPosition, ref maxPosition, ref vertexCount); 10369 {
9885 } 10370 // This is for ground sitting avatars
9886 } 10371 float height = presence.Appearance.AvatarHeight / 2.66666667f;
9887 partCount++; 10372 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
10373 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
10374 }
10375 else
10376 {
10377 // This is for standing/flying avatars
10378 float height = presence.Appearance.AvatarHeight / 2.0f;
10379 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
10380 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
9888 } 10381 }
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 10382
9899 bool hasParent = true; 10383 // Adjust to the documented error offsets (see LSL Wiki)
9900 // When requested or if no mesher, keep it simple 10384 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
9901 if (m_useSimpleBoxesInGetBoundingBox || primMesher == null) 10385 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
10386*/
9902 { 10387 {
9903 AddBoundingBoxOfSimpleBox(lower, upper, offset, sp.Rotation, hasParent, ref minPosition, ref maxPosition, ref vertexCount); 10388 // This is for ground sitting avatars TODO!
10389 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
10390 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
9904 } 10391 }
9905 // Do the full mounty
9906 else 10392 else
9907 { 10393 {
9908 // Prim shapes don't do center offsets, so add it here. 10394 // This is for standing/flying avatars
9909 offset = offset + (lower + upper) * 0.5f * sp.Rotation; 10395 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
9910 Primitive omvPrim = MakeOpenMetaversePrim(upper - lower, offset, sp.Rotation, ScriptBaseClass.PRIM_TYPE_SPHERE); 10396 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 } 10397 }
9915 partCount++;
9916 }
9917
9918 groupCount++;
9919
9920 // Return lower and upper bounding box corners
9921 result.Add(new LSL_Vector(minPosition));
9922 result.Add(new LSL_Vector(maxPosition));
9923 if (m_addStatsInGetBoundingBox)
9924 result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount));
9925
9926 primMesher = null;
9927 return result;
9928 }
9929
9930 /// <summary>
9931 /// Helper to calculate bounding box of an avatar.
9932 /// </summary>
9933 private void BoundingBoxOfScenePresence(ScenePresence sp, out Vector3 lower, out Vector3 upper)
9934 {
9935 // Adjust from OS model
9936 // avatar height = visual height - 0.2, bounding box height = visual height
9937 // to SL model
9938 // avatar height = visual height, bounding box height = visual height + 0.2
9939 float height = sp.Appearance.AvatarHeight + m_avatarHeightCorrection;
9940
9941 // According to avatar bounding box in SL 2015-04-18:
9942 // standing = <-0.275,-0.35,-0.1-0.5*h> : <0.275,0.35,0.1+0.5*h>
9943 // groundsitting = <-0.3875,-0.5,-0.05-0.375*h> : <0.3875,0.5,0.5>
9944 // sitting = <-0.5875,-0.35,-0.35-0.375*h> : <0.1875,0.35,-0.25+0.25*h>
9945
9946 // When avatar is sitting
9947 if (sp.ParentPart != null)
9948 {
9949 lower = new Vector3(m_lABB1SitX0, m_lABB1SitY0, m_lABB1SitZ0 + m_lABB1SitZ1 * height);
9950 upper = new Vector3(m_lABB2SitX0, m_lABB2SitY0, m_lABB2SitZ0 + m_lABB2SitZ1 * height);
9951 }
9952 // When avatar is groundsitting
9953 else if (sp.Animator.Animations.ImplicitDefaultAnimation.AnimID == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
9954 {
9955 lower = new Vector3(m_lABB1GrsX0, m_lABB1GrsY0, m_lABB1GrsZ0 + m_lABB1GrsZ1 * height);
9956 upper = new Vector3(m_lABB2GrsX0, m_lABB2GrsY0, m_lABB2GrsZ0 + m_lABB2GrsZ1 * height);
9957 }
9958 // When avatar is standing or flying
9959 else
9960 {
9961 lower = new Vector3(m_lABB1StdX0, m_lABB1StdY0, m_lABB1StdZ0 + m_lABB1StdZ1 * height);
9962 upper = new Vector3(m_lABB2StdX0, m_lABB2StdY0, m_lABB2StdZ0 + m_lABB2StdZ1 * height);
9963 }
9964 }
9965 10398
9966 /// <summary> 10399 if (lower.x > upper.x)
9967 /// Helper to approximate a part with a simple box. 10400 lower.x = upper.x;
9968 /// </summary> 10401 if (lower.y > upper.y)
9969 private void AddBoundingBoxOfSimpleBox(Vector3 corner1, Vector3 corner2, Vector3 offset, Quaternion rotation, bool hasParent, ref Vector3 lower, ref Vector3 upper, ref int count) 10402 lower.y = upper.y;
9970 { 10403 if (lower.z > upper.z)
9971 // Parse the 8 box corners 10404 lower.z = upper.z;
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 10405
9993 /// <summary> 10406 result.Add(lower);
9994 /// Helper to parse a meshed prim and needed especially 10407 result.Add(upper);
9995 /// for accuracy with tortured prims and sculpts. 10408 return result;
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 } 10409 }
10017 }
10018 10410
10019 /// <summary> 10411 part = World.GetSceneObjectPart(objID);
10020 /// Helper to parse mesh because no method exists 10412 // Currently only works for single prims without a sitting avatar
10021 /// to parse mesh assets to SimpleMesh. 10413 if (part != null)
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 { 10414 {
10027 // Parse each face in mesh 10415 float minX;
10028 // since vertex array isn't populated. 10416 float maxX;
10029 // This parses each unique vertex 3-6 times. 10417 float minY;
10030 foreach (Face face in mesh.Faces) 10418 float maxY;
10031 { 10419 float minZ;
10032 // Parse each vertex in face 10420 float maxZ;
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 10421
10050 /// <summary> 10422 // This BBox is in sim coordinates, with the offset being
10051 /// Helper to make up an OpenMetaverse prim 10423 // a contained point.
10052 /// needed to create mesh from parts. 10424 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
10053 /// </summary> 10425 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
10054 private Primitive MakeOpenMetaversePrim(Vector3 scale, Vector3 position, Quaternion rotation, int primType) 10426
10055 { 10427 minX -= offsets[0].X;
10056 // Initialize and set common parameters 10428 maxX -= offsets[0].X;
10057 Primitive prim = new OpenMetaverse.Primitive(); 10429 minY -= offsets[0].Y;
10058 prim.Scale = scale; 10430 maxY -= offsets[0].Y;
10059 prim.Position = position; 10431 minZ -= offsets[0].Z;
10060 prim.Rotation = rotation; 10432 maxZ -= offsets[0].Z;
10061 prim.PrimData.PathShearX = 0.0f; 10433
10062 prim.PrimData.PathShearY = 0.0f; 10434 LSL_Vector lower;
10063 prim.PrimData.PathBegin = 0.0f; 10435 LSL_Vector upper;
10064 prim.PrimData.PathEnd = 1.0f; 10436
10065 prim.PrimData.PathScaleX = 1.0f; 10437 // Adjust to the documented error offsets (see LSL Wiki)
10066 prim.PrimData.PathScaleY = 1.0f; 10438 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
10067 prim.PrimData.PathTaperX = 0.0f; 10439 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
10068 prim.PrimData.PathTaperY = 0.0f; 10440
10069 prim.PrimData.PathTwistBegin = 0.0f; 10441 if (lower.x > upper.x)
10070 prim.PrimData.PathTwist = 0.0f; 10442 lower.x = upper.x;
10071 prim.PrimData.ProfileBegin = 0.0f; 10443 if (lower.y > upper.y)
10072 prim.PrimData.ProfileEnd = 1.0f; 10444 lower.y = upper.y;
10073 prim.PrimData.ProfileHollow = 0.0f; 10445 if (lower.z > upper.z)
10074 prim.PrimData.ProfileCurve = (ProfileCurve)1; 10446 lower.z = upper.z;
10075 prim.PrimData.ProfileHole = (HoleType)0; 10447
10076 prim.PrimData.PathCurve = (PathCurve)16; 10448 result.Add(lower);
10077 prim.PrimData.PathRadiusOffset = 0.0f; 10449 result.Add(upper);
10078 prim.PrimData.PathRevolutions = 1.0f; 10450 return result;
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 } 10451 }
10141 10452
10142 return prim; 10453 // Not found so return empty values
10454 result.Add(new LSL_Vector());
10455 result.Add(new LSL_Vector());
10456 return result;
10143 } 10457 }
10144 10458
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() 10459 public LSL_Vector llGetGeometricCenter()
10153 { 10460 {
10154 // Subtract whatever position the root prim has to make it zero 10461 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 } 10462 }
10168 10463
10169 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 10464 public LSL_List llGetPrimitiveParams(LSL_List rules)
10170 { 10465 {
10171 LSL_List result = new LSL_List(); 10466 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 10467
10183 if (entity is SceneObjectPart) 10468 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 10469
10188 if (remaining == null || remaining.Length < 2) 10470 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
10189 return result;
10190 10471
10472 while ((object)remaining != null && remaining.Length > 2)
10473 {
10191 int linknumber = remaining.GetLSLIntegerItem(0); 10474 int linknumber = remaining.GetLSLIntegerItem(0);
10192 rules = remaining.GetSublist(1, -1); 10475 rules = remaining.GetSublist(1, -1);
10193 entity = GetLinkEntity(m_host, linknumber); 10476 List<SceneObjectPart> parts = GetLinkParts(linknumber);
10194 }
10195 }
10196 10477
10197 public LSL_List llGetPrimitiveParams(LSL_List rules) 10478 foreach (SceneObjectPart part in parts)
10198 { 10479 remaining = GetPrimParams(part, rules, ref result);
10199 m_host.AddScriptLPS(1); 10480 }
10200 10481
10201 return GetEntityParams(m_host, rules); 10482 return result;
10202 } 10483 }
10203 10484
10204 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 10485 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
10205 { 10486 {
10206 m_host.AddScriptLPS(1); 10487 m_host.AddScriptLPS(1);
10207 10488
10208 return GetEntityParams(GetLinkEntity(m_host, linknumber), rules); 10489 // acording to SL wiki this must indicate a single link number or link_root or link_this.
10209 } 10490 // keep other options as before
10210 10491
10211 public LSL_Vector GetAgentSize(ScenePresence sp) 10492 List<SceneObjectPart> parts;
10212 { 10493 List<ScenePresence> avatars;
10213 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); 10494
10214 } 10495 LSL_List res = new LSL_List();
10496 LSL_List remaining = new LSL_List();
10215 10497
10216 /// <summary> 10498 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 { 10499 {
10228 int code = (int)rules.GetLSLIntegerItem(idx++); 10500 parts = GetLinkParts(linknumber);
10229 int remain = rules.Length-idx; 10501 avatars = GetLinkAvatars(linknumber);
10230 10502
10231 switch (code) 10503 remaining = new LSL_List();
10504 foreach (SceneObjectPart part in parts)
10232 { 10505 {
10233 case (int)ScriptBaseClass.PRIM_MATERIAL: 10506 remaining = GetPrimParams(part, rules, ref res);
10234 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 10507 }
10235 break; 10508 foreach (ScenePresence avatar in avatars)
10236 10509 {
10237 case (int)ScriptBaseClass.PRIM_PHYSICS: 10510 remaining = GetPrimParams(avatar, rules, ref res);
10238 res.Add(ScriptBaseClass.FALSE); 10511 }
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 10512
10380 return rules.GetSublist(idx, -1); 10513 if (remaining.Length > 0)
10514 {
10515 linknumber = remaining.GetLSLIntegerItem(0);
10516 rules = remaining.GetSublist(1, -1);
10381 } 10517 }
10518 else
10519 break;
10382 } 10520 }
10383 10521
10384 return new LSL_List(); 10522 return res;
10385 } 10523 }
10386 10524
10387 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 10525 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
@@ -10420,19 +10558,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10420 break; 10558 break;
10421 10559
10422 case (int)ScriptBaseClass.PRIM_POSITION: 10560 case (int)ScriptBaseClass.PRIM_POSITION:
10423 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 10561 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
10424 10562 part.AbsolutePosition.Y,
10425 // For some reason, the part.AbsolutePosition.* values do not change if the 10563 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); 10564 res.Add(v);
10437 break; 10565 break;
10438 10566
@@ -10444,10 +10572,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10444 res.Add(GetPartRot(part)); 10572 res.Add(GetPartRot(part));
10445 break; 10573 break;
10446 10574
10447 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
10448 res.Add(new LSL_Integer((int)part.PhysicsShapeType));
10449 break;
10450
10451 case (int)ScriptBaseClass.PRIM_TYPE: 10575 case (int)ScriptBaseClass.PRIM_TYPE:
10452 // implementing box 10576 // implementing box
10453 PrimitiveBaseShape Shape = part.Shape; 10577 PrimitiveBaseShape Shape = part.Shape;
@@ -10541,7 +10665,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10541 Primitive.TextureEntry tex = part.Shape.Textures; 10665 Primitive.TextureEntry tex = part.Shape.Textures;
10542 if (face == ScriptBaseClass.ALL_SIDES) 10666 if (face == ScriptBaseClass.ALL_SIDES)
10543 { 10667 {
10544 for (face = 0 ; face < GetNumberOfSides(part); face++) 10668 for (face = 0; face < GetNumberOfSides(part); face++)
10545 { 10669 {
10546 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10670 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
10547 10671
@@ -10577,13 +10701,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10577 if (remain < 1) 10701 if (remain < 1)
10578 return new LSL_List(); 10702 return new LSL_List();
10579 10703
10580 face=(int)rules.GetLSLIntegerItem(idx++); 10704 face = (int)rules.GetLSLIntegerItem(idx++);
10581 10705
10582 tex = part.Shape.Textures; 10706 tex = part.Shape.Textures;
10583 Color4 texcolor; 10707 Color4 texcolor;
10584 if (face == ScriptBaseClass.ALL_SIDES) 10708 if (face == ScriptBaseClass.ALL_SIDES)
10585 { 10709 {
10586 for (face = 0 ; face < GetNumberOfSides(part); face++) 10710 for (face = 0; face < GetNumberOfSides(part); face++)
10587 { 10711 {
10588 texcolor = tex.GetFace((uint)face).RGBA; 10712 texcolor = tex.GetFace((uint)face).RGBA;
10589 res.Add(new LSL_Vector(texcolor.R, 10713 res.Add(new LSL_Vector(texcolor.R,
@@ -10606,30 +10730,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10606 if (remain < 1) 10730 if (remain < 1)
10607 return new LSL_List(); 10731 return new LSL_List();
10608 10732
10609 face=(int)rules.GetLSLIntegerItem(idx++); 10733 face = (int)rules.GetLSLIntegerItem(idx++);
10610 10734
10611 tex = part.Shape.Textures; 10735 tex = part.Shape.Textures;
10736 int shiny;
10612 if (face == ScriptBaseClass.ALL_SIDES) 10737 if (face == ScriptBaseClass.ALL_SIDES)
10613 { 10738 {
10614 for (face = 0; face < GetNumberOfSides(part); face++) 10739 for (face = 0; face < GetNumberOfSides(part); face++)
10615 { 10740 {
10616 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10741 Shininess shinyness = tex.GetFace((uint)face).Shiny;
10617 // Convert Shininess to PRIM_SHINY_* 10742 if (shinyness == Shininess.High)
10618 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 10743 {
10619 // PRIM_BUMP_* 10744 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
10620 res.Add(new LSL_Integer((int)texface.Bump)); 10745 }
10746 else if (shinyness == Shininess.Medium)
10747 {
10748 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
10749 }
10750 else if (shinyness == Shininess.Low)
10751 {
10752 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
10753 }
10754 else
10755 {
10756 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
10757 }
10758 res.Add(new LSL_Integer(shiny));
10759 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
10621 } 10760 }
10622 } 10761 }
10623 else 10762 else
10624 { 10763 {
10625 if (face >= 0 && face < GetNumberOfSides(part)) 10764 Shininess shinyness = tex.GetFace((uint)face).Shiny;
10765 if (shinyness == Shininess.High)
10626 { 10766 {
10627 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10767 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
10628 // Convert Shininess to PRIM_SHINY_* 10768 }
10629 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 10769 else if (shinyness == Shininess.Medium)
10630 // PRIM_BUMP_* 10770 {
10631 res.Add(new LSL_Integer((int)texface.Bump)); 10771 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
10772 }
10773 else if (shinyness == Shininess.Low)
10774 {
10775 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
10776 }
10777 else
10778 {
10779 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
10632 } 10780 }
10781 res.Add(new LSL_Integer(shiny));
10782 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
10633 } 10783 }
10634 break; 10784 break;
10635 10785
@@ -10640,21 +10790,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10640 face = (int)rules.GetLSLIntegerItem(idx++); 10790 face = (int)rules.GetLSLIntegerItem(idx++);
10641 10791
10642 tex = part.Shape.Textures; 10792 tex = part.Shape.Textures;
10793 int fullbright;
10643 if (face == ScriptBaseClass.ALL_SIDES) 10794 if (face == ScriptBaseClass.ALL_SIDES)
10644 { 10795 {
10645 for (face = 0; face < GetNumberOfSides(part); face++) 10796 for (face = 0; face < GetNumberOfSides(part); face++)
10646 { 10797 {
10647 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10798 if (tex.GetFace((uint)face).Fullbright == true)
10648 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 10799 {
10800 fullbright = ScriptBaseClass.TRUE;
10801 }
10802 else
10803 {
10804 fullbright = ScriptBaseClass.FALSE;
10805 }
10806 res.Add(new LSL_Integer(fullbright));
10649 } 10807 }
10650 } 10808 }
10651 else 10809 else
10652 { 10810 {
10653 if (face >= 0 && face < GetNumberOfSides(part)) 10811 if (tex.GetFace((uint)face).Fullbright == true)
10654 { 10812 {
10655 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10813 fullbright = ScriptBaseClass.TRUE;
10656 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
10657 } 10814 }
10815 else
10816 {
10817 fullbright = ScriptBaseClass.FALSE;
10818 }
10819 res.Add(new LSL_Integer(fullbright));
10658 } 10820 }
10659 break; 10821 break;
10660 10822
@@ -10676,27 +10838,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10676 break; 10838 break;
10677 10839
10678 case (int)ScriptBaseClass.PRIM_TEXGEN: 10840 case (int)ScriptBaseClass.PRIM_TEXGEN:
10841 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
10679 if (remain < 1) 10842 if (remain < 1)
10680 return new LSL_List(); 10843 return new LSL_List();
10681 10844
10682 face=(int)rules.GetLSLIntegerItem(idx++); 10845 face = (int)rules.GetLSLIntegerItem(idx++);
10683 10846
10684 tex = part.Shape.Textures; 10847 tex = part.Shape.Textures;
10685 if (face == ScriptBaseClass.ALL_SIDES) 10848 if (face == ScriptBaseClass.ALL_SIDES)
10686 { 10849 {
10687 for (face = 0; face < GetNumberOfSides(part); face++) 10850 for (face = 0; face < GetNumberOfSides(part); face++)
10688 { 10851 {
10689 MappingType texgen = tex.GetFace((uint)face).TexMapType; 10852 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
10690 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 10853 {
10691 res.Add(new LSL_Integer((uint)texgen >> 1)); 10854 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
10855 }
10856 else
10857 {
10858 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
10859 }
10692 } 10860 }
10693 } 10861 }
10694 else 10862 else
10695 { 10863 {
10696 if (face >= 0 && face < GetNumberOfSides(part)) 10864 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
10697 { 10865 {
10698 MappingType texgen = tex.GetFace((uint)face).TexMapType; 10866 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
10699 res.Add(new LSL_Integer((uint)texgen >> 1)); 10867 }
10868 else
10869 {
10870 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
10700 } 10871 }
10701 } 10872 }
10702 break; 10873 break;
@@ -10720,24 +10891,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10720 if (remain < 1) 10891 if (remain < 1)
10721 return new LSL_List(); 10892 return new LSL_List();
10722 10893
10723 face=(int)rules.GetLSLIntegerItem(idx++); 10894 face = (int)rules.GetLSLIntegerItem(idx++);
10724 10895
10725 tex = part.Shape.Textures; 10896 tex = part.Shape.Textures;
10897 float primglow;
10726 if (face == ScriptBaseClass.ALL_SIDES) 10898 if (face == ScriptBaseClass.ALL_SIDES)
10727 { 10899 {
10728 for (face = 0; face < GetNumberOfSides(part); face++) 10900 for (face = 0; face < GetNumberOfSides(part); face++)
10729 { 10901 {
10730 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 10902 primglow = tex.GetFace((uint)face).Glow;
10731 res.Add(new LSL_Float(texface.Glow)); 10903 res.Add(new LSL_Float(primglow));
10732 } 10904 }
10733 } 10905 }
10734 else 10906 else
10735 { 10907 {
10736 if (face >= 0 && face < GetNumberOfSides(part)) 10908 primglow = tex.GetFace((uint)face).Glow;
10737 { 10909 res.Add(new LSL_Float(primglow));
10738 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
10739 res.Add(new LSL_Float(texface.Glow));
10740 }
10741 } 10910 }
10742 break; 10911 break;
10743 10912
@@ -10747,17 +10916,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10747 res.Add(new LSL_Vector(textColor.R, 10916 res.Add(new LSL_Vector(textColor.R,
10748 textColor.G, 10917 textColor.G,
10749 textColor.B)); 10918 textColor.B));
10750 res.Add(new LSL_Float(1.0 - textColor.A)); 10919 res.Add(new LSL_Float(textColor.A));
10751 break; 10920 break;
10921
10752 case (int)ScriptBaseClass.PRIM_NAME: 10922 case (int)ScriptBaseClass.PRIM_NAME:
10753 res.Add(new LSL_String(part.Name)); 10923 res.Add(new LSL_String(part.Name));
10754 break; 10924 break;
10925
10755 case (int)ScriptBaseClass.PRIM_DESC: 10926 case (int)ScriptBaseClass.PRIM_DESC:
10756 res.Add(new LSL_String(part.Description)); 10927 res.Add(new LSL_String(part.Description));
10757 break; 10928 break;
10758 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 10929 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
10759 res.Add(new LSL_Rotation(part.RotationOffset)); 10930 res.Add(new LSL_Rotation(part.RotationOffset));
10760 break; 10931 break;
10932
10761 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 10933 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
10762 res.Add(new LSL_Vector(GetPartLocalPos(part))); 10934 res.Add(new LSL_Vector(GetPartLocalPos(part)));
10763 break; 10935 break;
@@ -10783,6 +10955,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10783 return new LSL_List(); 10955 return new LSL_List();
10784 } 10956 }
10785 10957
10958
10786 public LSL_List llGetPrimMediaParams(int face, LSL_List rules) 10959 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
10787 { 10960 {
10788 m_host.AddScriptLPS(1); 10961 m_host.AddScriptLPS(1);
@@ -11370,8 +11543,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11370 // The function returns an ordered list 11543 // The function returns an ordered list
11371 // representing the tokens found in the supplied 11544 // representing the tokens found in the supplied
11372 // sources string. If two successive tokenizers 11545 // sources string. If two successive tokenizers
11373 // are encountered, then a NULL entry is added 11546 // are encountered, then a null-string entry is
11374 // to the list. 11547 // added to the list.
11375 // 11548 //
11376 // It is a precondition that the source and 11549 // It is a precondition that the source and
11377 // toekizer lisst are non-null. If they are null, 11550 // toekizer lisst are non-null. If they are null,
@@ -11379,7 +11552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11379 // while their lengths are being determined. 11552 // while their lengths are being determined.
11380 // 11553 //
11381 // A small amount of working memoryis required 11554 // A small amount of working memoryis required
11382 // of approximately 8*#tokenizers. 11555 // of approximately 8*#tokenizers + 8*srcstrlen.
11383 // 11556 //
11384 // There are many ways in which this function 11557 // There are many ways in which this function
11385 // can be implemented, this implementation is 11558 // can be implemented, this implementation is
@@ -11395,155 +11568,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11395 // and eliminates redundant tokenizers as soon 11568 // and eliminates redundant tokenizers as soon
11396 // as is possible. 11569 // as is possible.
11397 // 11570 //
11398 // The implementation tries to avoid any copying 11571 // The implementation tries to minimize temporary
11399 // of arrays or other objects. 11572 // garbage generation.
11400 // </remarks> 11573 // </remarks>
11401 11574
11402 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 11575 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
11403 { 11576 {
11404 int beginning = 0; 11577 return ParseString2List(src, separators, spacers, true);
11405 int srclen = src.Length; 11578 }
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 11579
11420 LSL_List tokens = new LSL_List(); 11580 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
11581 {
11582 int srclen = src.Length;
11583 int seplen = separators.Length;
11584 object[] separray = separators.Data;
11585 int spclen = spacers.Length;
11586 object[] spcarray = spacers.Data;
11587 int dellen = 0;
11588 string[] delarray = new string[seplen+spclen];
11421 11589
11422 // All entries are initially valid 11590 int outlen = 0;
11591 string[] outarray = new string[srclen*2+1];
11423 11592
11424 for (int i = 0; i < mlen; i++) 11593 int i, j;
11425 active[i] = true; 11594 string d;
11426 11595
11427 offset[mlen] = srclen; 11596 m_host.AddScriptLPS(1);
11428 11597
11429 while (beginning < srclen) 11598 /*
11599 * Convert separator and spacer lists to C# strings.
11600 * Also filter out null strings so we don't hang.
11601 */
11602 for (i = 0; i < seplen; i ++)
11430 { 11603 {
11604 d = separray[i].ToString();
11605 if (d.Length > 0)
11606 {
11607 delarray[dellen++] = d;
11608 }
11609 }
11610 seplen = dellen;
11431 11611
11432 best = mlen; // as bad as it gets 11612 for (i = 0; i < spclen; i ++)
11613 {
11614 d = spcarray[i].ToString();
11615 if (d.Length > 0)
11616 {
11617 delarray[dellen++] = d;
11618 }
11619 }
11433 11620
11434 // Scan for separators 11621 /*
11622 * Scan through source string from beginning to end.
11623 */
11624 for (i = 0;;)
11625 {
11435 11626
11436 for (j = 0; j < seplen; j++) 11627 /*
11628 * Find earliest delimeter in src starting at i (if any).
11629 */
11630 int earliestDel = -1;
11631 int earliestSrc = srclen;
11632 string earliestStr = null;
11633 for (j = 0; j < dellen; j ++)
11437 { 11634 {
11438 if (separray[j].ToString() == String.Empty) 11635 d = delarray[j];
11439 active[j] = false; 11636 if (d != null)
11440
11441 if (active[j])
11442 { 11637 {
11443 // scan all of the markers 11638 int index = src.IndexOf(d, i);
11444 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 11639 if (index < 0)
11445 { 11640 {
11446 // not present at all 11641 delarray[j] = null; // delim nowhere in src, don't check it anymore
11447 active[j] = false;
11448 } 11642 }
11449 else 11643 else if (index < earliestSrc)
11450 { 11644 {
11451 // present and correct 11645 earliestSrc = index; // where delimeter starts in source string
11452 if (offset[j] < offset[best]) 11646 earliestDel = j; // where delimeter is in delarray[]
11453 { 11647 earliestStr = d; // the delimeter string from delarray[]
11454 // closest so far 11648 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 } 11649 }
11460 } 11650 }
11461 } 11651 }
11462 11652
11463 // Scan for spacers 11653 /*
11464 11654 * Output source string starting at i through start of earliest delimeter.
11465 if (offset[best] != beginning) 11655 */
11656 if (keepNulls || (earliestSrc > i))
11466 { 11657 {
11467 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 11658 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 } 11659 }
11492 11660
11493 // This is the normal exit from the scanning loop 11661 /*
11662 * If no delimeter found at or after i, we're done scanning.
11663 */
11664 if (earliestDel < 0) break;
11494 11665
11495 if (best == mlen) 11666 /*
11667 * If delimeter was a spacer, output the spacer.
11668 */
11669 if (earliestDel >= seplen)
11496 { 11670 {
11497 // no markers were found on this pass 11671 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 } 11672 }
11503 11673
11504 // Otherwise we just add the newly delimited token 11674 /*
11505 // and recalculate where the search should continue. 11675 * Look at rest of src string following delimeter.
11506 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 11676 */
11507 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 11677 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 } 11678 }
11521 11679
11522 // This an awkward an not very intuitive boundary case. If the 11680 /*
11523 // last substring is a tokenizer, then there is an implied trailing 11681 * 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 11682 */
11525 // arduous. Alternatively the 'break' could be replced with a return 11683 object[] outlist = new object[outlen];
11526 // but that's shabby programming. 11684 for (i = 0; i < outlen; i ++)
11527
11528 if ((beginning == srclen) && (keepNulls))
11529 { 11685 {
11530 if (srclen != 0) 11686 outlist[i] = new LSL_String(outarray[i]);
11531 tokens.Add(new LSL_String(""));
11532 } 11687 }
11533 11688 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 } 11689 }
11548 11690
11549 public LSL_Integer llGetObjectPermMask(int mask) 11691 public LSL_Integer llGetObjectPermMask(int mask)
@@ -11841,31 +11983,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11841 UUID key = new UUID(); 11983 UUID key = new UUID();
11842 if (UUID.TryParse(id, out key)) 11984 if (UUID.TryParse(id, out key))
11843 { 11985 {
11844 try 11986 // return total object mass
11845 { 11987 SceneObjectPart part = World.GetSceneObjectPart(key);
11846 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 11988 if (part != null)
11847 if (obj != null) 11989 return part.ParentGroup.GetMass();
11848 return (double)obj.GetMass(); 11990
11849 // the object is null so the key is for an avatar 11991 // the object is null so the key is for an avatar
11850 ScenePresence avatar = World.GetScenePresence(key); 11992 ScenePresence avatar = World.GetScenePresence(key);
11851 if (avatar != null) 11993 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 { 11994 {
11861 return 0; // The Object/Agent not in the region so just return zero 11995 if (avatar.IsChildAgent)
11996 {
11997 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
11998 // child agents have a mass of 1.0
11999 return 1;
12000 }
12001 else
12002 {
12003 return (double)avatar.GetMass();
12004 }
11862 } 12005 }
11863 } 12006 }
11864 return 0; 12007 return 0;
11865 } 12008 }
11866 12009
11867 /// <summary> 12010 /// <summary>
11868 /// illListReplaceList removes the sub-list defined by the inclusive indices 12011 /// llListReplaceList removes the sub-list defined by the inclusive indices
11869 /// start and end and inserts the src list in its place. The inclusive 12012 /// 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 12013 /// 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 12014 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -11922,16 +12065,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11922 // based upon end. Note that if end exceeds the upper 12065 // based upon end. Note that if end exceeds the upper
11923 // bound in this case, the entire destination list 12066 // bound in this case, the entire destination list
11924 // is removed. 12067 // is removed.
11925 else 12068 else if (start == 0)
11926 { 12069 {
11927 if (end + 1 < dest.Length) 12070 if (end + 1 < dest.Length)
11928 {
11929 return src + dest.GetSublist(end + 1, -1); 12071 return src + dest.GetSublist(end + 1, -1);
11930 }
11931 else 12072 else
11932 {
11933 return src; 12073 return src;
11934 } 12074 }
12075 else // Start < 0
12076 {
12077 if (end + 1 < dest.Length)
12078 return dest.GetSublist(end + 1, -1);
12079 else
12080 return new LSL_List();
11935 } 12081 }
11936 } 12082 }
11937 // Finally, if start > end, we strip away a prefix and 12083 // Finally, if start > end, we strip away a prefix and
@@ -11968,7 +12114,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 12114 // 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. 12115 // lets add estate owners and gods, too, and use the generic permission check.
11970 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 12116 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
11971 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; 12117 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia, false)) return;
11972 12118
11973 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? 12119 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)?
11974 byte loop = 0; 12120 byte loop = 0;
@@ -11982,17 +12128,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11982 int width = 0; 12128 int width = 0;
11983 int height = 0; 12129 int height = 0;
11984 12130
11985 ParcelMediaCommandEnum? commandToSend = null; 12131 uint commandToSend = 0;
11986 float time = 0.0f; // default is from start 12132 float time = 0.0f; // default is from start
11987 12133
11988 ScenePresence presence = null; 12134 ScenePresence presence = null;
11989 12135
11990 for (int i = 0; i < commandList.Data.Length; i++) 12136 for (int i = 0; i < commandList.Data.Length; i++)
11991 { 12137 {
11992 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 12138 uint command = (uint)(commandList.GetLSLIntegerItem(i));
11993 switch (command) 12139 switch (command)
11994 { 12140 {
11995 case ParcelMediaCommandEnum.Agent: 12141 case (uint)ParcelMediaCommandEnum.Agent:
11996 // we send only to one agent 12142 // we send only to one agent
11997 if ((i + 1) < commandList.Length) 12143 if ((i + 1) < commandList.Length)
11998 { 12144 {
@@ -12009,25 +12155,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12009 } 12155 }
12010 break; 12156 break;
12011 12157
12012 case ParcelMediaCommandEnum.Loop: 12158 case (uint)ParcelMediaCommandEnum.Loop:
12013 loop = 1; 12159 loop = 1;
12014 commandToSend = command; 12160 commandToSend = command;
12015 update = true; //need to send the media update packet to set looping 12161 update = true; //need to send the media update packet to set looping
12016 break; 12162 break;
12017 12163
12018 case ParcelMediaCommandEnum.Play: 12164 case (uint)ParcelMediaCommandEnum.Play:
12019 loop = 0; 12165 loop = 0;
12020 commandToSend = command; 12166 commandToSend = command;
12021 update = true; //need to send the media update packet to make sure it doesn't loop 12167 update = true; //need to send the media update packet to make sure it doesn't loop
12022 break; 12168 break;
12023 12169
12024 case ParcelMediaCommandEnum.Pause: 12170 case (uint)ParcelMediaCommandEnum.Pause:
12025 case ParcelMediaCommandEnum.Stop: 12171 case (uint)ParcelMediaCommandEnum.Stop:
12026 case ParcelMediaCommandEnum.Unload: 12172 case (uint)ParcelMediaCommandEnum.Unload:
12027 commandToSend = command; 12173 commandToSend = command;
12028 break; 12174 break;
12029 12175
12030 case ParcelMediaCommandEnum.Url: 12176 case (uint)ParcelMediaCommandEnum.Url:
12031 if ((i + 1) < commandList.Length) 12177 if ((i + 1) < commandList.Length)
12032 { 12178 {
12033 if (commandList.Data[i + 1] is LSL_String) 12179 if (commandList.Data[i + 1] is LSL_String)
@@ -12040,7 +12186,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12040 } 12186 }
12041 break; 12187 break;
12042 12188
12043 case ParcelMediaCommandEnum.Texture: 12189 case (uint)ParcelMediaCommandEnum.Texture:
12044 if ((i + 1) < commandList.Length) 12190 if ((i + 1) < commandList.Length)
12045 { 12191 {
12046 if (commandList.Data[i + 1] is LSL_String) 12192 if (commandList.Data[i + 1] is LSL_String)
@@ -12053,7 +12199,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12053 } 12199 }
12054 break; 12200 break;
12055 12201
12056 case ParcelMediaCommandEnum.Time: 12202 case (uint)ParcelMediaCommandEnum.Time:
12057 if ((i + 1) < commandList.Length) 12203 if ((i + 1) < commandList.Length)
12058 { 12204 {
12059 if (commandList.Data[i + 1] is LSL_Float) 12205 if (commandList.Data[i + 1] is LSL_Float)
@@ -12065,7 +12211,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12065 } 12211 }
12066 break; 12212 break;
12067 12213
12068 case ParcelMediaCommandEnum.AutoAlign: 12214 case (uint)ParcelMediaCommandEnum.AutoAlign:
12069 if ((i + 1) < commandList.Length) 12215 if ((i + 1) < commandList.Length)
12070 { 12216 {
12071 if (commandList.Data[i + 1] is LSL_Integer) 12217 if (commandList.Data[i + 1] is LSL_Integer)
@@ -12079,7 +12225,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12079 } 12225 }
12080 break; 12226 break;
12081 12227
12082 case ParcelMediaCommandEnum.Type: 12228 case (uint)ParcelMediaCommandEnum.Type:
12083 if ((i + 1) < commandList.Length) 12229 if ((i + 1) < commandList.Length)
12084 { 12230 {
12085 if (commandList.Data[i + 1] is LSL_String) 12231 if (commandList.Data[i + 1] is LSL_String)
@@ -12092,7 +12238,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12092 } 12238 }
12093 break; 12239 break;
12094 12240
12095 case ParcelMediaCommandEnum.Desc: 12241 case (uint)ParcelMediaCommandEnum.Desc:
12096 if ((i + 1) < commandList.Length) 12242 if ((i + 1) < commandList.Length)
12097 { 12243 {
12098 if (commandList.Data[i + 1] is LSL_String) 12244 if (commandList.Data[i + 1] is LSL_String)
@@ -12105,7 +12251,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12105 } 12251 }
12106 break; 12252 break;
12107 12253
12108 case ParcelMediaCommandEnum.Size: 12254 case (uint)ParcelMediaCommandEnum.Size:
12109 if ((i + 2) < commandList.Length) 12255 if ((i + 2) < commandList.Length)
12110 { 12256 {
12111 if (commandList.Data[i + 1] is LSL_Integer) 12257 if (commandList.Data[i + 1] is LSL_Integer)
@@ -12175,7 +12321,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12175 } 12321 }
12176 } 12322 }
12177 12323
12178 if (commandToSend != null) 12324 if (commandToSend != 0)
12179 { 12325 {
12180 // the commandList contained a start/stop/... command, too 12326 // the commandList contained a start/stop/... command, too
12181 if (presence == null) 12327 if (presence == null)
@@ -12212,7 +12358,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12212 12358
12213 if (aList.Data[i] != null) 12359 if (aList.Data[i] != null)
12214 { 12360 {
12215 switch ((ParcelMediaCommandEnum) aList.Data[i]) 12361 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
12216 { 12362 {
12217 case ParcelMediaCommandEnum.Url: 12363 case ParcelMediaCommandEnum.Url:
12218 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 12364 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -12269,15 +12415,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12269 12415
12270 if (quick_pay_buttons.Data.Length < 4) 12416 if (quick_pay_buttons.Data.Length < 4)
12271 { 12417 {
12272 Error("llSetPayPrice", "List must have at least 4 elements"); 12418 int x;
12273 return; 12419 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
12420 {
12421 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
12422 }
12274 } 12423 }
12275 m_host.ParentGroup.RootPart.PayPrice[0]=price; 12424 int[] nPrice = new int[5];
12276 12425 nPrice[0] = price;
12277 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 12426 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
12278 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 12427 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
12279 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 12428 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
12280 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 12429 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
12430 m_host.ParentGroup.RootPart.PayPrice = nPrice;
12281 m_host.ParentGroup.HasGroupChanged = true; 12431 m_host.ParentGroup.HasGroupChanged = true;
12282 } 12432 }
12283 12433
@@ -12294,7 +12444,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12294 return Vector3.Zero; 12444 return Vector3.Zero;
12295 } 12445 }
12296 12446
12297 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 12447// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
12448 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
12298 if (presence != null) 12449 if (presence != null)
12299 { 12450 {
12300 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 12451 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
@@ -12317,7 +12468,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12317 return Quaternion.Identity; 12468 return Quaternion.Identity;
12318 } 12469 }
12319 12470
12320 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 12471// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
12472 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
12321 if (presence != null) 12473 if (presence != null)
12322 { 12474 {
12323 return new LSL_Rotation(presence.CameraRotation); 12475 return new LSL_Rotation(presence.CameraRotation);
@@ -12370,8 +12522,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12370 { 12522 {
12371 m_host.AddScriptLPS(1); 12523 m_host.AddScriptLPS(1);
12372 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 12524 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
12373 if (detectedParams == null) return; // only works on the first detected avatar 12525 if (detectedParams == null)
12374 12526 {
12527 if (m_host.ParentGroup.IsAttachment == true)
12528 {
12529 detectedParams = new DetectParams();
12530 detectedParams.Key = m_host.OwnerID;
12531 }
12532 else
12533 {
12534 return;
12535 }
12536 }
12537
12375 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 12538 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
12376 if (avatar != null) 12539 if (avatar != null)
12377 { 12540 {
@@ -12386,7 +12549,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12386 m_host.AddScriptLPS(1); 12549 m_host.AddScriptLPS(1);
12387 UUID key; 12550 UUID key;
12388 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 12551 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
12389 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 12552 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false))
12390 { 12553 {
12391 int expires = 0; 12554 int expires = 0;
12392 if (hours != 0) 12555 if (hours != 0)
@@ -12427,7 +12590,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12427 m_host.AddScriptLPS(1); 12590 m_host.AddScriptLPS(1);
12428 UUID key; 12591 UUID key;
12429 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 12592 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
12430 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) 12593 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed, false))
12431 { 12594 {
12432 if (UUID.TryParse(avatar, out key)) 12595 if (UUID.TryParse(avatar, out key))
12433 { 12596 {
@@ -12454,7 +12617,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12454 m_host.AddScriptLPS(1); 12617 m_host.AddScriptLPS(1);
12455 UUID key; 12618 UUID key;
12456 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 12619 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
12457 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 12620 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false))
12458 { 12621 {
12459 if (UUID.TryParse(avatar, out key)) 12622 if (UUID.TryParse(avatar, out key))
12460 { 12623 {
@@ -12686,19 +12849,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12686 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 12849 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
12687 { 12850 {
12688 m_host.AddScriptLPS(1); 12851 m_host.AddScriptLPS(1);
12689 string ret = String.Empty; 12852
12690 string src1 = llBase64ToString(str1); 12853 if (str1 == String.Empty)
12691 string src2 = llBase64ToString(str2); 12854 return String.Empty;
12692 int c = 0; 12855 if (str2 == String.Empty)
12693 for (int i = 0; i < src1.Length; i++) 12856 return str1;
12857
12858 int len = str2.Length;
12859 if ((len % 4) != 0) // LL is EVIL!!!!
12694 { 12860 {
12695 ret += (char) (src1[i] ^ src2[c]); 12861 while (str2.EndsWith("="))
12862 str2 = str2.Substring(0, str2.Length - 1);
12696 12863
12697 c++; 12864 len = str2.Length;
12698 if (c >= src2.Length) 12865 int mod = len % 4;
12699 c = 0; 12866
12867 if (mod == 1)
12868 str2 = str2.Substring(0, str2.Length - 1);
12869 else if (mod == 2)
12870 str2 += "==";
12871 else if (mod == 3)
12872 str2 += "=";
12873 }
12874
12875 byte[] data1;
12876 byte[] data2;
12877 try
12878 {
12879 data1 = Convert.FromBase64String(str1);
12880 data2 = Convert.FromBase64String(str2);
12881 }
12882 catch (Exception)
12883 {
12884 return new LSL_String(String.Empty);
12885 }
12886
12887 byte[] d2 = new Byte[data1.Length];
12888 int pos = 0;
12889
12890 if (data1.Length <= data2.Length)
12891 {
12892 Array.Copy(data2, 0, d2, 0, data1.Length);
12893 }
12894 else
12895 {
12896 while (pos < data1.Length)
12897 {
12898 len = data1.Length - pos;
12899 if (len > data2.Length)
12900 len = data2.Length;
12901
12902 Array.Copy(data2, 0, d2, pos, len);
12903 pos += len;
12904 }
12700 } 12905 }
12701 return llStringToBase64(ret); 12906
12907 for (pos = 0 ; pos < data1.Length ; pos++ )
12908 data1[pos] ^= d2[pos];
12909
12910 return Convert.ToBase64String(data1);
12702 } 12911 }
12703 12912
12704 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 12913 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -12802,16 +13011,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12802 if (userAgent != null) 13011 if (userAgent != null)
12803 httpHeaders["User-Agent"] = userAgent; 13012 httpHeaders["User-Agent"] = userAgent;
12804 13013
13014 // See if the URL contains any header hacks
13015 string[] urlParts = url.Split(new char[] {'\n'});
13016 if (urlParts.Length > 1)
13017 {
13018 // Iterate the passed headers and parse them
13019 for (int i = 1 ; i < urlParts.Length ; i++ )
13020 {
13021 // The rest of those would be added to the body in SL.
13022 // Let's not do that.
13023 if (urlParts[i] == String.Empty)
13024 break;
13025
13026 // See if this could be a valid header
13027 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
13028 if (headerParts.Length != 2)
13029 continue;
13030
13031 string headerName = headerParts[0].Trim();
13032 string headerValue = headerParts[1].Trim();
13033
13034 // Filter out headers that could be used to abuse
13035 // another system or cloak the request
13036 if (headerName.ToLower() == "x-secondlife-shard" ||
13037 headerName.ToLower() == "x-secondlife-object-name" ||
13038 headerName.ToLower() == "x-secondlife-object-key" ||
13039 headerName.ToLower() == "x-secondlife-region" ||
13040 headerName.ToLower() == "x-secondlife-local-position" ||
13041 headerName.ToLower() == "x-secondlife-local-velocity" ||
13042 headerName.ToLower() == "x-secondlife-local-rotation" ||
13043 headerName.ToLower() == "x-secondlife-owner-name" ||
13044 headerName.ToLower() == "x-secondlife-owner-key" ||
13045 headerName.ToLower() == "connection" ||
13046 headerName.ToLower() == "content-length" ||
13047 headerName.ToLower() == "from" ||
13048 headerName.ToLower() == "host" ||
13049 headerName.ToLower() == "proxy-authorization" ||
13050 headerName.ToLower() == "referer" ||
13051 headerName.ToLower() == "trailer" ||
13052 headerName.ToLower() == "transfer-encoding" ||
13053 headerName.ToLower() == "via" ||
13054 headerName.ToLower() == "authorization")
13055 continue;
13056
13057 httpHeaders[headerName] = headerValue;
13058 }
13059
13060 // Finally, strip any protocol specifier from the URL
13061 url = urlParts[0].Trim();
13062 int idx = url.IndexOf(" HTTP/");
13063 if (idx != -1)
13064 url = url.Substring(0, idx);
13065 }
13066
12805 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 13067 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
12806 Regex r = new Regex(authregex); 13068 Regex r = new Regex(authregex);
12807 int[] gnums = r.GetGroupNumbers(); 13069 int[] gnums = r.GetGroupNumbers();
12808 Match m = r.Match(url); 13070 Match m = r.Match(url);
12809 if (m.Success) { 13071 if (m.Success)
12810 for (int i = 1; i < gnums.Length; i++) { 13072 {
13073 for (int i = 1; i < gnums.Length; i++)
13074 {
12811 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 13075 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
12812 //CaptureCollection cc = g.Captures; 13076 //CaptureCollection cc = g.Captures;
12813 } 13077 }
12814 if (m.Groups.Count == 5) { 13078 if (m.Groups.Count == 5)
13079 {
12815 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 13080 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(); 13081 url = m.Groups[1].ToString() + m.Groups[4].ToString();
12817 } 13082 }
@@ -13018,6 +13283,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13018 13283
13019 LSL_List ret = new LSL_List(); 13284 LSL_List ret = new LSL_List();
13020 UUID key = new UUID(); 13285 UUID key = new UUID();
13286
13287
13021 if (UUID.TryParse(id, out key)) 13288 if (UUID.TryParse(id, out key))
13022 { 13289 {
13023 ScenePresence av = World.GetScenePresence(key); 13290 ScenePresence av = World.GetScenePresence(key);
@@ -13035,13 +13302,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13035 ret.Add(new LSL_String("")); 13302 ret.Add(new LSL_String(""));
13036 break; 13303 break;
13037 case ScriptBaseClass.OBJECT_POS: 13304 case ScriptBaseClass.OBJECT_POS:
13038 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 13305 Vector3 avpos;
13306
13307 if (av.ParentID != 0 && av.ParentPart != null)
13308 {
13309 avpos = av.OffsetPosition;
13310
13311 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
13312 avpos -= sitOffset;
13313
13314 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
13315 }
13316 else
13317 avpos = av.AbsolutePosition;
13318
13319 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
13039 break; 13320 break;
13040 case ScriptBaseClass.OBJECT_ROT: 13321 case ScriptBaseClass.OBJECT_ROT:
13041 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 13322 Quaternion avrot = av.Rotation;
13323 if (av.ParentID != 0 && av.ParentPart != null)
13324 {
13325 avrot = av.ParentPart.GetWorldRotation() * avrot;
13326 }
13327 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
13042 break; 13328 break;
13043 case ScriptBaseClass.OBJECT_VELOCITY: 13329 case ScriptBaseClass.OBJECT_VELOCITY:
13044 ret.Add(new LSL_Vector(av.GetWorldVelocity())); 13330 Vector3 avvel = av.GetWorldVelocity();
13331 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
13045 break; 13332 break;
13046 case ScriptBaseClass.OBJECT_OWNER: 13333 case ScriptBaseClass.OBJECT_OWNER:
13047 ret.Add(new LSL_String(id)); 13334 ret.Add(new LSL_String(id));
@@ -13143,11 +13430,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13143 case ScriptBaseClass.OBJECT_NAME: 13430 case ScriptBaseClass.OBJECT_NAME:
13144 ret.Add(new LSL_String(obj.Name)); 13431 ret.Add(new LSL_String(obj.Name));
13145 break; 13432 break;
13146 case ScriptBaseClass.OBJECT_DESC: 13433 case ScriptBaseClass.OBJECT_DESC:
13147 ret.Add(new LSL_String(obj.Description)); 13434 ret.Add(new LSL_String(obj.Description));
13148 break; 13435 break;
13149 case ScriptBaseClass.OBJECT_POS: 13436 case ScriptBaseClass.OBJECT_POS:
13150 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 13437 Vector3 opos = obj.AbsolutePosition;
13438 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
13151 break; 13439 break;
13152 case ScriptBaseClass.OBJECT_ROT: 13440 case ScriptBaseClass.OBJECT_ROT:
13153 Quaternion rot = Quaternion.Identity; 13441 Quaternion rot = Quaternion.Identity;
@@ -13220,9 +13508,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13220 // The value returned in SL for normal prims is prim count 13508 // The value returned in SL for normal prims is prim count
13221 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 13509 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
13222 break; 13510 break;
13223 // The following 3 costs I have intentionaly coded to return zero. They are part of 13511
13224 // "Land Impact" calculations. These calculations are probably not applicable 13512 // 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: 13513 case ScriptBaseClass.OBJECT_SERVER_COST:
13227 // The linden calculation is here 13514 // The linden calculation is here
13228 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 13515 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -13230,16 +13517,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13230 ret.Add(new LSL_Float(0)); 13517 ret.Add(new LSL_Float(0));
13231 break; 13518 break;
13232 case ScriptBaseClass.OBJECT_STREAMING_COST: 13519 case ScriptBaseClass.OBJECT_STREAMING_COST:
13233 // The linden calculation is here 13520 // The value returned in SL for normal prims is prim count * 0.06
13234 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 13521 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; 13522 break;
13238 case ScriptBaseClass.OBJECT_PHYSICS_COST: 13523 case ScriptBaseClass.OBJECT_PHYSICS_COST:
13239 // The linden calculation is here 13524 // The value returned in SL for normal prims is prim count
13240 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 13525 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; 13526 break;
13244 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 13527 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
13245 ret.Add(new LSL_Float(0)); 13528 ret.Add(new LSL_Float(0));
@@ -13522,23 +13805,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13522 13805
13523 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 13806 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
13524 { 13807 {
13525 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 13808 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
13809
13810 LSL_List result = new LSL_List();
13526 13811
13527 if (obj != null && obj.OwnerID == m_host.OwnerID) 13812 if (obj != null && obj.OwnerID == m_host.OwnerID)
13528 return GetEntityParams(obj, rules); 13813 {
13814 LSL_List remaining = GetPrimParams(obj, rules, ref result);
13529 13815
13530 return new LSL_List(); 13816 while (remaining.Length > 2)
13817 {
13818 int linknumber = remaining.GetLSLIntegerItem(0);
13819 rules = remaining.GetSublist(1, -1);
13820 List<SceneObjectPart> parts = GetLinkParts(linknumber);
13821
13822 foreach (SceneObjectPart part in parts)
13823 remaining = GetPrimParams(part, rules, ref result);
13824 }
13825 }
13826
13827 return result;
13531 } 13828 }
13532 13829
13533 public void print(string str) 13830 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
13534 { 13831 {
13535 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 13832 List<SceneObjectPart> parts = GetLinkParts(link);
13536 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 13833 if (parts.Count < 1)
13537 if (ossl != null) 13834 return 0;
13538 { 13835
13539 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 13836 return GetNumberOfSides(parts[0]);
13540 m_log.Info("LSL print():" + str);
13541 }
13542 } 13837 }
13543 13838
13544 private string Name2Username(string name) 13839 private string Name2Username(string name)
@@ -13583,7 +13878,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13583 13878
13584 return rq.ToString(); 13879 return rq.ToString();
13585 } 13880 }
13586 13881/*
13882 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
13883 {
13884 m_SayShoutCount = 0;
13885 }
13886*/
13587 private struct Tri 13887 private struct Tri
13588 { 13888 {
13589 public Vector3 p1; 13889 public Vector3 p1;
@@ -13732,9 +14032,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13732 14032
13733 ContactResult result = new ContactResult (); 14033 ContactResult result = new ContactResult ();
13734 result.ConsumerID = group.LocalId; 14034 result.ConsumerID = group.LocalId;
13735 result.Depth = intersection.distance; 14035// result.Depth = intersection.distance;
13736 result.Normal = intersection.normal; 14036 result.Normal = intersection.normal;
13737 result.Pos = intersection.ipoint; 14037 result.Pos = intersection.ipoint;
14038 result.Depth = Vector3.Mag(rayStart - result.Pos);
13738 14039
13739 contacts.Add(result); 14040 contacts.Add(result);
13740 }); 14041 });
@@ -13867,6 +14168,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13867 14168
13868 return contacts[0]; 14169 return contacts[0];
13869 } 14170 }
14171/*
14172 // not done:
14173 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
14174 {
14175 ContactResult[] contacts = null;
14176 World.ForEachSOG(delegate(SceneObjectGroup group)
14177 {
14178 if (m_host.ParentGroup == group)
14179 return;
14180
14181 if (group.IsAttachment)
14182 return;
14183
14184 if(group.RootPart.PhysActor != null)
14185 return;
14186
14187 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
14188 });
14189 return contacts;
14190 }
14191*/
13870 14192
13871 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 14193 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
13872 { 14194 {
@@ -13994,18 +14316,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13994 } 14316 }
13995 } 14317 }
13996 14318
14319 // Double check this
13997 if (checkTerrain) 14320 if (checkTerrain)
13998 { 14321 {
13999 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 14322 bool skipGroundCheck = false;
14000 if (groundContact != null) 14323
14001 results.Add((ContactResult)groundContact); 14324 foreach (ContactResult c in results)
14325 {
14326 if (c.ConsumerID == 0) // Physics gave us a ground collision
14327 skipGroundCheck = true;
14328 }
14329
14330 if (!skipGroundCheck)
14331 {
14332 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
14333 if (groundContact != null)
14334 results.Add((ContactResult)groundContact);
14335 }
14002 } 14336 }
14003 14337
14004 results.Sort(delegate(ContactResult a, ContactResult b) 14338 results.Sort(delegate(ContactResult a, ContactResult b)
14005 { 14339 {
14006 return a.Depth.CompareTo(b.Depth); 14340 return a.Depth.CompareTo(b.Depth);
14007 }); 14341 });
14008 14342
14009 int values = 0; 14343 int values = 0;
14010 SceneObjectGroup thisgrp = m_host.ParentGroup; 14344 SceneObjectGroup thisgrp = m_host.ParentGroup;
14011 14345
@@ -14064,6 +14398,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14064 } 14398 }
14065 14399
14066 /// <summary> 14400 /// <summary>
14401 /// Helper to calculate bounding box of an avatar.
14402 /// </summary>
14403 private void BoundingBoxOfScenePresence(ScenePresence sp, out Vector3 lower, out Vector3 upper)
14404 {
14405 // Adjust from OS model
14406 // avatar height = visual height - 0.2, bounding box height = visual height
14407 // to SL model
14408 // avatar height = visual height, bounding box height = visual height + 0.2
14409 float height = sp.Appearance.AvatarHeight + m_avatarHeightCorrection;
14410
14411 // According to avatar bounding box in SL 2015-04-18:
14412 // standing = <-0.275,-0.35,-0.1-0.5*h> : <0.275,0.35,0.1+0.5*h>
14413 // groundsitting = <-0.3875,-0.5,-0.05-0.375*h> : <0.3875,0.5,0.5>
14414 // sitting = <-0.5875,-0.35,-0.35-0.375*h> : <0.1875,0.35,-0.25+0.25*h>
14415
14416 // When avatar is sitting
14417 if (sp.ParentPart != null)
14418 {
14419 lower = new Vector3(m_lABB1SitX0, m_lABB1SitY0, m_lABB1SitZ0 + m_lABB1SitZ1 * height);
14420 upper = new Vector3(m_lABB2SitX0, m_lABB2SitY0, m_lABB2SitZ0 + m_lABB2SitZ1 * height);
14421 }
14422 // When avatar is groundsitting
14423 else if (sp.Animator.Animations.ImplicitDefaultAnimation.AnimID == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
14424 {
14425 lower = new Vector3(m_lABB1GrsX0, m_lABB1GrsY0, m_lABB1GrsZ0 + m_lABB1GrsZ1 * height);
14426 upper = new Vector3(m_lABB2GrsX0, m_lABB2GrsY0, m_lABB2GrsZ0 + m_lABB2GrsZ1 * height);
14427 }
14428 // When avatar is standing or flying
14429 else
14430 {
14431 lower = new Vector3(m_lABB1StdX0, m_lABB1StdY0, m_lABB1StdZ0 + m_lABB1StdZ1 * height);
14432 upper = new Vector3(m_lABB2StdX0, m_lABB2StdY0, m_lABB2StdZ0 + m_lABB2StdZ1 * height);
14433 }
14434 }
14435
14436
14437 /// <summary>
14067 /// Implementation of llCastRay similar to SL 2015-04-21. 14438 /// Implementation of llCastRay similar to SL 2015-04-21.
14068 /// http://wiki.secondlife.com/wiki/LlCastRay 14439 /// http://wiki.secondlife.com/wiki/LlCastRay
14069 /// Uses pure geometry, bounding shapes, meshing and no physics 14440 /// Uses pure geometry, bounding shapes, meshing and no physics
@@ -14964,7 +15335,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14964 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 15335 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
14965 if (!isAccount) return 0; 15336 if (!isAccount) return 0;
14966 if (estate.HasAccess(id)) return 1; 15337 if (estate.HasAccess(id)) return 1;
14967 if (estate.IsBanned(id)) 15338 if (estate.IsBanned(id, World.GetUserFlags(id)))
14968 estate.RemoveBan(id); 15339 estate.RemoveBan(id);
14969 estate.AddEstateUser(id); 15340 estate.AddEstateUser(id);
14970 break; 15341 break;
@@ -14983,14 +15354,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14983 break; 15354 break;
14984 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 15355 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
14985 if (!isAccount) return 0; 15356 if (!isAccount) return 0;
14986 if (estate.IsBanned(id)) return 1; 15357 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
14987 EstateBan ban = new EstateBan(); 15358 EstateBan ban = new EstateBan();
14988 ban.EstateID = estate.EstateID; 15359 ban.EstateID = estate.EstateID;
14989 ban.BannedUserID = id; 15360 ban.BannedUserID = id;
14990 estate.AddBan(ban); 15361 estate.AddBan(ban);
14991 break; 15362 break;
14992 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 15363 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
14993 if (!isAccount || !estate.IsBanned(id)) return 0; 15364 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
14994 estate.RemoveBan(id); 15365 estate.RemoveBan(id);
14995 break; 15366 break;
14996 default: return 0; 15367 default: return 0;
@@ -15049,13 +15420,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
15049 public void llCollisionSprite(string impact_sprite) 15420 public void llCollisionSprite(string impact_sprite)
15050 { 15421 {
15051 m_host.AddScriptLPS(1); 15422 m_host.AddScriptLPS(1);
15052 NotImplemented("llCollisionSprite"); 15423 // Viewer 2.0 broke this and it's likely LL has no intention
15424 // of fixing it. Therefore, letting this be a NOP seems appropriate.
15053 } 15425 }
15054 15426
15055 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 15427 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
15056 { 15428 {
15057 m_host.AddScriptLPS(1); 15429 m_host.AddScriptLPS(1);
15058 NotImplemented("llGodLikeRezObject"); 15430
15431 if (!World.Permissions.IsGod(m_host.OwnerID))
15432 NotImplemented("llGodLikeRezObject");
15433
15434 AssetBase rezAsset = World.AssetService.Get(inventory);
15435 if (rezAsset == null)
15436 {
15437 llSay(0, "Asset not found");
15438 return;
15439 }
15440
15441 SceneObjectGroup group = null;
15442
15443 try
15444 {
15445 string xmlData = Utils.BytesToString(rezAsset.Data);
15446 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
15447 }
15448 catch
15449 {
15450 llSay(0, "Asset not found");
15451 return;
15452 }
15453
15454 if (group == null)
15455 {
15456 llSay(0, "Asset not found");
15457 return;
15458 }
15459
15460 group.RootPart.AttachPoint = group.RootPart.Shape.State;
15461 group.RootPart.AttachedPos = group.AbsolutePosition;
15462
15463 group.ResetIDs();
15464
15465 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
15466 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
15467 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
15468 group.ScheduleGroupForFullUpdate();
15469
15470 // objects rezzed with this method are die_at_edge by default.
15471 group.RootPart.SetDieAtEdge(true);
15472
15473 group.ResumeScripts();
15474
15475 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
15476 "object_rez", new Object[] {
15477 new LSL_String(
15478 group.RootPart.UUID.ToString()) },
15479 new DetectParams[0]));
15059 } 15480 }
15060 15481
15061 public LSL_String llTransferLindenDollars(string destination, int amount) 15482 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -15106,8 +15527,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
15106 return; 15527 return;
15107 } 15528 }
15108 15529
15530 string reason;
15109 bool result = money.ObjectGiveMoney( 15531 bool result = money.ObjectGiveMoney(
15110 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 15532 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn, out reason);
15111 15533
15112 if (result) 15534 if (result)
15113 { 15535 {
@@ -15115,7 +15537,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
15115 return; 15537 return;
15116 } 15538 }
15117 15539
15118 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS"; 15540 replydata = reason;
15119 } 15541 }
15120 finally 15542 finally
15121 { 15543 {
@@ -15132,6 +15554,964 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
15132 } 15554 }
15133 15555
15134 #endregion 15556 #endregion
15557
15558 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
15559 {
15560 SceneObjectGroup group = m_host.ParentGroup;
15561
15562 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
15563 return;
15564 if (group.IsAttachment)
15565 return;
15566
15567 if (frames.Data.Length > 0) // We are getting a new motion
15568 {
15569 if (group.RootPart.KeyframeMotion != null)
15570 group.RootPart.KeyframeMotion.Delete();
15571 group.RootPart.KeyframeMotion = null;
15572
15573 int idx = 0;
15574
15575 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
15576 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
15577
15578 while (idx < options.Data.Length)
15579 {
15580 int option = (int)options.GetLSLIntegerItem(idx++);
15581 int remain = options.Data.Length - idx;
15582
15583 switch (option)
15584 {
15585 case ScriptBaseClass.KFM_MODE:
15586 if (remain < 1)
15587 break;
15588 int modeval = (int)options.GetLSLIntegerItem(idx++);
15589 switch(modeval)
15590 {
15591 case ScriptBaseClass.KFM_FORWARD:
15592 mode = KeyframeMotion.PlayMode.Forward;
15593 break;
15594 case ScriptBaseClass.KFM_REVERSE:
15595 mode = KeyframeMotion.PlayMode.Reverse;
15596 break;
15597 case ScriptBaseClass.KFM_LOOP:
15598 mode = KeyframeMotion.PlayMode.Loop;
15599 break;
15600 case ScriptBaseClass.KFM_PING_PONG:
15601 mode = KeyframeMotion.PlayMode.PingPong;
15602 break;
15603 }
15604 break;
15605 case ScriptBaseClass.KFM_DATA:
15606 if (remain < 1)
15607 break;
15608 int dataval = (int)options.GetLSLIntegerItem(idx++);
15609 data = (KeyframeMotion.DataFormat)dataval;
15610 break;
15611 }
15612 }
15613
15614 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
15615
15616 idx = 0;
15617
15618 int elemLength = 2;
15619 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
15620 elemLength = 3;
15621
15622 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
15623 while (idx < frames.Data.Length)
15624 {
15625 int remain = frames.Data.Length - idx;
15626
15627 if (remain < elemLength)
15628 break;
15629
15630 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
15631 frame.Position = null;
15632 frame.Rotation = null;
15633
15634 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
15635 {
15636 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
15637 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
15638 }
15639 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
15640 {
15641 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
15642 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
15643 q.Normalize();
15644 frame.Rotation = q;
15645 }
15646
15647 float tempf = (float)frames.GetLSLFloatItem(idx++);
15648 frame.TimeMS = (int)(tempf * 1000.0f);
15649
15650 keyframes.Add(frame);
15651 }
15652
15653 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
15654 group.RootPart.KeyframeMotion.Start();
15655 }
15656 else
15657 {
15658 if (group.RootPart.KeyframeMotion == null)
15659 return;
15660
15661 if (options.Data.Length == 0)
15662 {
15663 group.RootPart.KeyframeMotion.Stop();
15664 return;
15665 }
15666
15667 int code = (int)options.GetLSLIntegerItem(0);
15668
15669 int idx = 0;
15670
15671 while (idx < options.Data.Length)
15672 {
15673 int option = (int)options.GetLSLIntegerItem(idx++);
15674 int remain = options.Data.Length - idx;
15675
15676 switch (option)
15677 {
15678 case ScriptBaseClass.KFM_COMMAND:
15679 int cmd = (int)options.GetLSLIntegerItem(idx++);
15680 switch (cmd)
15681 {
15682 case ScriptBaseClass.KFM_CMD_PLAY:
15683 group.RootPart.KeyframeMotion.Start();
15684 break;
15685 case ScriptBaseClass.KFM_CMD_STOP:
15686 group.RootPart.KeyframeMotion.Stop();
15687 break;
15688 case ScriptBaseClass.KFM_CMD_PAUSE:
15689 group.RootPart.KeyframeMotion.Pause();
15690 break;
15691 }
15692 break;
15693 }
15694 }
15695 }
15696 }
15697
15698 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
15699 {
15700 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
15701
15702 int idx = 0;
15703 int idxStart = 0;
15704
15705 bool positionChanged = false;
15706 Vector3 finalPos = Vector3.Zero;
15707
15708 try
15709 {
15710 while (idx < rules.Length)
15711 {
15712 ++rulesParsed;
15713 int code = rules.GetLSLIntegerItem(idx++);
15714
15715 int remain = rules.Length - idx;
15716 idxStart = idx;
15717
15718 switch (code)
15719 {
15720 case (int)ScriptBaseClass.PRIM_POSITION:
15721 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
15722 {
15723 if (remain < 1)
15724 return new LSL_List();
15725
15726 LSL_Vector v;
15727 v = rules.GetVector3Item(idx++);
15728
15729 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
15730
15731 v = v + 2 * sitOffset;
15732
15733 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
15734 av.SendAvatarDataToAllAgents();
15735
15736 }
15737 break;
15738
15739 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
15740 case (int)ScriptBaseClass.PRIM_ROTATION:
15741 {
15742 if (remain < 1)
15743 return new LSL_List();
15744
15745 LSL_Rotation r;
15746 r = rules.GetQuaternionItem(idx++);
15747
15748 av.Rotation = r * llGetRootRotation();
15749 av.SendAvatarDataToAllAgents();
15750 }
15751 break;
15752
15753 // parse rest doing nothing but number of parameters error check
15754 case (int)ScriptBaseClass.PRIM_SIZE:
15755 case (int)ScriptBaseClass.PRIM_MATERIAL:
15756 case (int)ScriptBaseClass.PRIM_PHANTOM:
15757 case (int)ScriptBaseClass.PRIM_PHYSICS:
15758 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
15759 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
15760 case (int)ScriptBaseClass.PRIM_NAME:
15761 case (int)ScriptBaseClass.PRIM_DESC:
15762 if (remain < 1)
15763 return new LSL_List();
15764 idx++;
15765 break;
15766
15767 case (int)ScriptBaseClass.PRIM_GLOW:
15768 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
15769 case (int)ScriptBaseClass.PRIM_TEXGEN:
15770 if (remain < 2)
15771 return new LSL_List();
15772 idx += 2;
15773 break;
15774
15775 case (int)ScriptBaseClass.PRIM_TYPE:
15776 if (remain < 3)
15777 return new LSL_List();
15778 code = (int)rules.GetLSLIntegerItem(idx++);
15779 remain = rules.Length - idx;
15780 switch (code)
15781 {
15782 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
15783 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
15784 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
15785 if (remain < 6)
15786 return new LSL_List();
15787 idx += 6;
15788 break;
15789
15790 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
15791 if (remain < 5)
15792 return new LSL_List();
15793 idx += 5;
15794 break;
15795
15796 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
15797 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
15798 case (int)ScriptBaseClass.PRIM_TYPE_RING:
15799 if (remain < 11)
15800 return new LSL_List();
15801 idx += 11;
15802 break;
15803
15804 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
15805 if (remain < 2)
15806 return new LSL_List();
15807 idx += 2;
15808 break;
15809 }
15810 break;
15811
15812 case (int)ScriptBaseClass.PRIM_COLOR:
15813 case (int)ScriptBaseClass.PRIM_TEXT:
15814 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
15815 case (int)ScriptBaseClass.PRIM_OMEGA:
15816 if (remain < 3)
15817 return new LSL_List();
15818 idx += 3;
15819 break;
15820
15821 case (int)ScriptBaseClass.PRIM_TEXTURE:
15822 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
15823 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
15824 if (remain < 5)
15825 return new LSL_List();
15826 idx += 5;
15827 break;
15828
15829 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
15830 if (remain < 7)
15831 return new LSL_List();
15832
15833 idx += 7;
15834 break;
15835
15836 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
15837 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
15838 return new LSL_List();
15839
15840 return rules.GetSublist(idx, -1);
15841 }
15842 }
15843 }
15844 catch (InvalidCastException e)
15845 {
15846 Error(originFunc,string.Format(
15847 " error running rule #{1}: arg #{2} ",
15848 rulesParsed, idx - idxStart) + e.Message);
15849 }
15850 finally
15851 {
15852 if (positionChanged)
15853 {
15854 av.OffsetPosition = finalPos;
15855// av.SendAvatarDataToAllAgents();
15856 av.SendTerseUpdateToAllClients();
15857 positionChanged = false;
15858 }
15859 }
15860 return new LSL_List();
15861 }
15862
15863 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
15864 {
15865 // avatars case
15866 // replies as SL wiki
15867
15868// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
15869 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
15870
15871 int idx = 0;
15872 while (idx < rules.Length)
15873 {
15874 int code = (int)rules.GetLSLIntegerItem(idx++);
15875 int remain = rules.Length - idx;
15876
15877 switch (code)
15878 {
15879 case (int)ScriptBaseClass.PRIM_MATERIAL:
15880 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
15881 break;
15882
15883 case (int)ScriptBaseClass.PRIM_PHYSICS:
15884 res.Add(new LSL_Integer(0));
15885 break;
15886
15887 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
15888 res.Add(new LSL_Integer(0));
15889 break;
15890
15891 case (int)ScriptBaseClass.PRIM_PHANTOM:
15892 res.Add(new LSL_Integer(0));
15893 break;
15894
15895 case (int)ScriptBaseClass.PRIM_POSITION:
15896
15897 Vector3 pos = avatar.OffsetPosition;
15898
15899 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
15900 pos -= sitOffset;
15901
15902 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
15903 break;
15904
15905 case (int)ScriptBaseClass.PRIM_SIZE:
15906 Vector3 s = avatar.Appearance.AvatarSize;
15907 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
15908
15909 break;
15910
15911 case (int)ScriptBaseClass.PRIM_ROTATION:
15912 LSL_Rotation rot = new LSL_Rotation(avatar.Rotation.X, avatar.Rotation.Y, avatar.Rotation.Z, avatar.Rotation.W) / llGetRootRotation();
15913
15914 res.Add(rot);
15915 break;
15916
15917 case (int)ScriptBaseClass.PRIM_TYPE:
15918 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
15919 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
15920 res.Add(new LSL_Vector(0f,1.0f,0f));
15921 res.Add(new LSL_Float(0.0f));
15922 res.Add(new LSL_Vector(0, 0, 0));
15923 res.Add(new LSL_Vector(1.0f,1.0f,0f));
15924 res.Add(new LSL_Vector(0, 0, 0));
15925 break;
15926
15927 case (int)ScriptBaseClass.PRIM_TEXTURE:
15928 if (remain < 1)
15929 return new LSL_List();
15930
15931 int face = (int)rules.GetLSLIntegerItem(idx++);
15932 if (face == ScriptBaseClass.ALL_SIDES)
15933 {
15934 for (face = 0; face < 21; face++)
15935 {
15936 res.Add(new LSL_String(""));
15937 res.Add(new LSL_Vector(0,0,0));
15938 res.Add(new LSL_Vector(0,0,0));
15939 res.Add(new LSL_Float(0.0));
15940 }
15941 }
15942 else
15943 {
15944 if (face >= 0 && face < 21)
15945 {
15946 res.Add(new LSL_String(""));
15947 res.Add(new LSL_Vector(0,0,0));
15948 res.Add(new LSL_Vector(0,0,0));
15949 res.Add(new LSL_Float(0.0));
15950 }
15951 }
15952 break;
15953
15954 case (int)ScriptBaseClass.PRIM_COLOR:
15955 if (remain < 1)
15956 return new LSL_List();
15957
15958 face = (int)rules.GetLSLIntegerItem(idx++);
15959
15960 if (face == ScriptBaseClass.ALL_SIDES)
15961 {
15962 for (face = 0; face < 21; face++)
15963 {
15964 res.Add(new LSL_Vector(0,0,0));
15965 res.Add(new LSL_Float(0));
15966 }
15967 }
15968 else
15969 {
15970 res.Add(new LSL_Vector(0,0,0));
15971 res.Add(new LSL_Float(0));
15972 }
15973 break;
15974
15975 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
15976 if (remain < 1)
15977 return new LSL_List();
15978 face = (int)rules.GetLSLIntegerItem(idx++);
15979
15980 if (face == ScriptBaseClass.ALL_SIDES)
15981 {
15982 for (face = 0; face < 21; face++)
15983 {
15984 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
15985 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
15986 }
15987 }
15988 else
15989 {
15990 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
15991 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
15992 }
15993 break;
15994
15995 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
15996 if (remain < 1)
15997 return new LSL_List();
15998 face = (int)rules.GetLSLIntegerItem(idx++);
15999
16000 if (face == ScriptBaseClass.ALL_SIDES)
16001 {
16002 for (face = 0; face < 21; face++)
16003 {
16004 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
16005 }
16006 }
16007 else
16008 {
16009 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
16010 }
16011 break;
16012
16013 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
16014 res.Add(new LSL_Integer(0));
16015 res.Add(new LSL_Integer(0));// softness
16016 res.Add(new LSL_Float(0.0f)); // gravity
16017 res.Add(new LSL_Float(0.0f)); // friction
16018 res.Add(new LSL_Float(0.0f)); // wind
16019 res.Add(new LSL_Float(0.0f)); // tension
16020 res.Add(new LSL_Vector(0f,0f,0f));
16021 break;
16022
16023 case (int)ScriptBaseClass.PRIM_TEXGEN:
16024 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
16025 if (remain < 1)
16026 return new LSL_List();
16027 face = (int)rules.GetLSLIntegerItem(idx++);
16028
16029 if (face == ScriptBaseClass.ALL_SIDES)
16030 {
16031 for (face = 0; face < 21; face++)
16032 {
16033 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
16034 }
16035 }
16036 else
16037 {
16038 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
16039 }
16040 break;
16041
16042 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
16043 res.Add(new LSL_Integer(0));
16044 res.Add(new LSL_Vector(0f,0f,0f));
16045 res.Add(new LSL_Float(0f)); // intensity
16046 res.Add(new LSL_Float(0f)); // radius
16047 res.Add(new LSL_Float(0f)); // falloff
16048 break;
16049
16050 case (int)ScriptBaseClass.PRIM_GLOW:
16051 if (remain < 1)
16052 return new LSL_List();
16053 face = (int)rules.GetLSLIntegerItem(idx++);
16054
16055 if (face == ScriptBaseClass.ALL_SIDES)
16056 {
16057 for (face = 0; face < 21; face++)
16058 {
16059 res.Add(new LSL_Float(0f));
16060 }
16061 }
16062 else
16063 {
16064 res.Add(new LSL_Float(0f));
16065 }
16066 break;
16067
16068 case (int)ScriptBaseClass.PRIM_TEXT:
16069 res.Add(new LSL_String(""));
16070 res.Add(new LSL_Vector(0f,0f,0f));
16071 res.Add(new LSL_Float(1.0f));
16072 break;
16073
16074 case (int)ScriptBaseClass.PRIM_NAME:
16075 res.Add(new LSL_String(avatar.Name));
16076 break;
16077
16078 case (int)ScriptBaseClass.PRIM_DESC:
16079 res.Add(new LSL_String(""));
16080 break;
16081
16082 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
16083 Quaternion lrot = avatar.Rotation;
16084
16085 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
16086 {
16087 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
16088 }
16089 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
16090 break;
16091
16092 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
16093 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
16094 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
16095 lpos -= lsitOffset;
16096
16097 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
16098 {
16099 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
16100 }
16101 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
16102 break;
16103
16104 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
16105 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
16106 return new LSL_List();
16107
16108 return rules.GetSublist(idx, -1);
16109 }
16110 }
16111
16112 return new LSL_List();
16113 }
16114
16115 public void llSetContentType(LSL_Key id, LSL_Integer content_type)
16116 {
16117 if (m_UrlModule != null)
16118 {
16119 string type = "text.plain";
16120 if (content_type == (int)ScriptBaseClass.CONTENT_TYPE_HTML)
16121 type = "text/html";
16122
16123 m_UrlModule.HttpContentType(new UUID(id),type);
16124 }
16125 }
16126
16127 public void llSetAnimationOverride(LSL_String animState, LSL_String anim)
16128 {
16129 string state = String.Empty;
16130
16131 foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL)
16132 {
16133 if (kvp.Value.ToLower() == ((string)animState).ToLower())
16134 {
16135 state = kvp.Key;
16136 break;
16137 }
16138 }
16139
16140 if (state == String.Empty)
16141 {
16142 llShout(ScriptBaseClass.DEBUG_CHANNEL, "Invalid animation state " + animState);
16143 return;
16144 }
16145
16146 if (m_item.PermsGranter == UUID.Zero)
16147 {
16148 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16149 return;
16150 }
16151
16152 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS) == 0)
16153 {
16154 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16155 return;
16156 }
16157
16158 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
16159
16160 if (presence == null)
16161 return;
16162
16163 UUID animID;
16164
16165 animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation);
16166
16167 if (animID == UUID.Zero)
16168 {
16169 String animupper = ((string)anim).ToUpperInvariant();
16170 DefaultAvatarAnimations.AnimsUUID.TryGetValue(animupper, out animID);
16171 }
16172
16173 if (animID == UUID.Zero)
16174 {
16175 llShout(ScriptBaseClass.DEBUG_CHANNEL, "Animation not found");
16176 return;
16177 }
16178
16179 presence.SetAnimationOverride(state, animID);
16180 }
16181
16182 public void llResetAnimationOverride(LSL_String animState)
16183 {
16184 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
16185 if (presence == null)
16186 return;
16187
16188 if (m_item.PermsGranter == UUID.Zero)
16189 {
16190 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16191 return;
16192 }
16193
16194 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS) == 0)
16195 {
16196 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16197 return;
16198 }
16199
16200 if (animState == "ALL")
16201 {
16202 presence.SetAnimationOverride("ALL", UUID.Zero);
16203 return;
16204 }
16205
16206 string state = String.Empty;
16207
16208 foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL)
16209 {
16210 if (kvp.Value.ToLower() == ((string)animState).ToLower())
16211 {
16212 state = kvp.Key;
16213 break;
16214 }
16215 }
16216
16217 if (state == String.Empty)
16218 {
16219 return;
16220 }
16221
16222 presence.SetAnimationOverride(state, UUID.Zero);
16223 }
16224
16225 public LSL_String llGetAnimationOverride(LSL_String animState)
16226 {
16227 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
16228 if (presence == null)
16229 return String.Empty;
16230
16231 if (m_item.PermsGranter == UUID.Zero)
16232 {
16233 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16234 return String.Empty;
16235 }
16236
16237 if ((m_item.PermsMask & (ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS | ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION)) == 0)
16238 {
16239 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16240 return String.Empty;
16241 }
16242
16243 string state = String.Empty;
16244
16245 foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL)
16246 {
16247 if (kvp.Value.ToLower() == ((string)animState).ToLower())
16248 {
16249 state = kvp.Key;
16250 break;
16251 }
16252 }
16253
16254 if (state == String.Empty)
16255 {
16256 return String.Empty;
16257 }
16258
16259 UUID animID = presence.GetAnimationOverride(state);
16260 if (animID == UUID.Zero)
16261 return animState;
16262
16263 foreach (KeyValuePair<string, UUID> kvp in DefaultAvatarAnimations.AnimsUUID)
16264 {
16265 if (kvp.Value == animID)
16266 return kvp.Key.ToLower();
16267 }
16268
16269 foreach (TaskInventoryItem item in m_host.Inventory.GetInventoryItems())
16270 {
16271 if (item.AssetID == animID)
16272 return item.Name;
16273 }
16274
16275 return String.Empty;
16276 }
16277
16278 public LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers)
16279 {
16280 OSD o = OSDParser.DeserializeJson(json);
16281 OSD specVal = JsonGetSpecific(o, specifiers, 0);
16282
16283 return specVal.AsString();
16284 }
16285
16286 public LSL_List llJson2List(LSL_String json)
16287 {
16288 try
16289 {
16290 OSD o = OSDParser.DeserializeJson(json);
16291 return (LSL_List)ParseJsonNode(o);
16292 }
16293 catch (Exception)
16294 {
16295 return new LSL_List(ScriptBaseClass.JSON_INVALID);
16296 }
16297 }
16298
16299 private object ParseJsonNode(OSD node)
16300 {
16301 if (node.Type == OSDType.Integer)
16302 return new LSL_Integer(node.AsInteger());
16303 if (node.Type == OSDType.Boolean)
16304 return new LSL_Integer(node.AsBoolean() ? 1 : 0);
16305 if (node.Type == OSDType.Real)
16306 return new LSL_Float(node.AsReal());
16307 if (node.Type == OSDType.UUID || node.Type == OSDType.String)
16308 return new LSL_String(node.AsString());
16309 if (node.Type == OSDType.Array)
16310 {
16311 LSL_List resp = new LSL_List();
16312 OSDArray ar = node as OSDArray;
16313 foreach (OSD o in ar)
16314 resp.Add(ParseJsonNode(o));
16315 return resp;
16316 }
16317 if (node.Type == OSDType.Map)
16318 {
16319 LSL_List resp = new LSL_List();
16320 OSDMap ar = node as OSDMap;
16321 foreach (KeyValuePair<string, OSD> o in ar)
16322 {
16323 resp.Add(new LSL_String(o.Key));
16324 resp.Add(ParseJsonNode(o.Value));
16325 }
16326 return resp;
16327 }
16328 throw new Exception(ScriptBaseClass.JSON_INVALID);
16329 }
16330
16331 public LSL_String llList2Json(LSL_String type, LSL_List values)
16332 {
16333 try
16334 {
16335 if (type == ScriptBaseClass.JSON_ARRAY)
16336 {
16337 OSDArray array = new OSDArray();
16338 foreach (object o in values.Data)
16339 {
16340 array.Add(ListToJson(o));
16341 }
16342 return OSDParser.SerializeJsonString(array);
16343 }
16344 else if (type == ScriptBaseClass.JSON_OBJECT)
16345 {
16346 OSDMap map = new OSDMap();
16347 for (int i = 0; i < values.Data.Length; i += 2)
16348 {
16349 if (!(values.Data[i] is LSL_String))
16350 return ScriptBaseClass.JSON_INVALID;
16351 map.Add(((LSL_String)values.Data[i]).m_string, ListToJson(values.Data[i + 1]));
16352 }
16353 return OSDParser.SerializeJsonString(map);
16354 }
16355 return ScriptBaseClass.JSON_INVALID;
16356 }
16357 catch (Exception ex)
16358 {
16359 return ex.Message;
16360 }
16361 }
16362
16363 private OSD ListToJson(object o)
16364 {
16365 if (o is LSL_Float)
16366 return OSD.FromReal(((LSL_Float)o).value);
16367 if (o is LSL_Integer)
16368 {
16369 int i = ((LSL_Integer)o).value;
16370 if (i == 0)
16371 return OSD.FromBoolean(false);
16372 else if (i == 1)
16373 return OSD.FromBoolean(true);
16374 return OSD.FromInteger(i);
16375 }
16376 if (o is LSL_Rotation)
16377 return OSD.FromString(((LSL_Rotation)o).ToString());
16378 if (o is LSL_Vector)
16379 return OSD.FromString(((LSL_Vector)o).ToString());
16380 if (o is LSL_String)
16381 {
16382 string str = ((LSL_String)o).m_string;
16383 if (str == ScriptBaseClass.JSON_NULL)
16384 return new OSD();
16385 return OSD.FromString(str);
16386 }
16387 throw new Exception(ScriptBaseClass.JSON_INVALID);
16388 }
16389
16390 private OSD JsonGetSpecific(OSD o, LSL_List specifiers, int i)
16391 {
16392 object spec = specifiers.Data[i];
16393 OSD nextVal = null;
16394 if (o is OSDArray)
16395 {
16396 if (spec is LSL_Integer)
16397 nextVal = ((OSDArray)o)[((LSL_Integer)spec).value];
16398 }
16399 if (o is OSDMap)
16400 {
16401 if (spec is LSL_String)
16402 nextVal = ((OSDMap)o)[((LSL_String)spec).m_string];
16403 }
16404 if (nextVal != null)
16405 {
16406 if (specifiers.Data.Length - 1 > i)
16407 return JsonGetSpecific(nextVal, specifiers, i + 1);
16408 }
16409 return nextVal;
16410 }
16411
16412 public LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value)
16413 {
16414 try
16415 {
16416 OSD o = OSDParser.DeserializeJson(json);
16417 JsonSetSpecific(o, specifiers, 0, value);
16418 return OSDParser.SerializeJsonString(o);
16419 }
16420 catch (Exception)
16421 {
16422 }
16423 return ScriptBaseClass.JSON_INVALID;
16424 }
16425
16426 private void JsonSetSpecific(OSD o, LSL_List specifiers, int i, LSL_String val)
16427 {
16428 object spec = specifiers.Data[i];
16429 // 20131224 not used object specNext = i+1 == specifiers.Data.Length ? null : specifiers.Data[i+1];
16430 OSD nextVal = null;
16431 if (o is OSDArray)
16432 {
16433 OSDArray array = ((OSDArray)o);
16434 if (spec is LSL_Integer)
16435 {
16436 int v = ((LSL_Integer)spec).value;
16437 if (v >= array.Count)
16438 array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val));
16439 else
16440 nextVal = ((OSDArray)o)[v];
16441 }
16442 else if (spec is LSL_String && ((LSL_String)spec) == ScriptBaseClass.JSON_APPEND)
16443 array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val));
16444 }
16445 if (o is OSDMap)
16446 {
16447 if (spec is LSL_String)
16448 {
16449 OSDMap map = ((OSDMap)o);
16450 if (map.ContainsKey(((LSL_String)spec).m_string))
16451 nextVal = map[((LSL_String)spec).m_string];
16452 else
16453 map.Add(((LSL_String)spec).m_string, JsonBuildRestOfSpec(specifiers, i + 1, val));
16454 }
16455 }
16456 if (nextVal != null)
16457 {
16458 if (specifiers.Data.Length - 1 > i)
16459 {
16460 JsonSetSpecific(nextVal, specifiers, i + 1, val);
16461 return;
16462 }
16463 }
16464 }
16465
16466 private OSD JsonBuildRestOfSpec(LSL_List specifiers, int i, LSL_String val)
16467 {
16468 object spec = i >= specifiers.Data.Length ? null : specifiers.Data[i];
16469 // 20131224 not used object specNext = i+1 >= specifiers.Data.Length ? null : specifiers.Data[i+1];
16470
16471 if (spec == null)
16472 return OSD.FromString(val);
16473
16474 if (spec is LSL_Integer ||
16475 (spec is LSL_String && ((LSL_String)spec) == ScriptBaseClass.JSON_APPEND))
16476 {
16477 OSDArray array = new OSDArray();
16478 array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val));
16479 return array;
16480 }
16481 else if (spec is LSL_String)
16482 {
16483 OSDMap map = new OSDMap();
16484 map.Add((LSL_String)spec, JsonBuildRestOfSpec(specifiers, i + 1, val));
16485 return map;
16486 }
16487 return new OSD();
16488 }
16489
16490 public LSL_String llJsonValueType(LSL_String json, LSL_List specifiers)
16491 {
16492 OSD o = OSDParser.DeserializeJson(json);
16493 OSD specVal = JsonGetSpecific(o, specifiers, 0);
16494 if (specVal == null)
16495 return ScriptBaseClass.JSON_INVALID;
16496 switch (specVal.Type)
16497 {
16498 case OSDType.Array:
16499 return ScriptBaseClass.JSON_ARRAY;
16500 case OSDType.Boolean:
16501 return specVal.AsBoolean() ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE;
16502 case OSDType.Integer:
16503 case OSDType.Real:
16504 return ScriptBaseClass.JSON_NUMBER;
16505 case OSDType.Map:
16506 return ScriptBaseClass.JSON_OBJECT;
16507 case OSDType.String:
16508 case OSDType.UUID:
16509 return ScriptBaseClass.JSON_STRING;
16510 case OSDType.Unknown:
16511 return ScriptBaseClass.JSON_NULL;
16512 }
16513 return ScriptBaseClass.JSON_INVALID;
16514 }
15135 } 16515 }
15136 16516
15137 public class NotecardCache 16517 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..a87ee73 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -140,6 +140,7 @@ 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 bool m_debuggerSafe = false;
143 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 144 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
144 145
145 protected IUrlModule m_UrlModule = null; 146 protected IUrlModule m_UrlModule = null;
@@ -150,6 +151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
150 m_ScriptEngine = scriptEngine; 151 m_ScriptEngine = scriptEngine;
151 m_host = host; 152 m_host = host;
152 m_item = item; 153 m_item = item;
154 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
153 155
154 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 156 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
155 157
@@ -216,7 +218,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
216 218
217 internal void OSSLError(string msg) 219 internal void OSSLError(string msg)
218 { 220 {
219 throw new ScriptException("OSSL Runtime Error: " + msg); 221 if (m_debuggerSafe)
222 {
223 OSSLShoutError(msg);
224 }
225 else
226 {
227 throw new ScriptException("OSSL Runtime Error: " + msg);
228 }
220 } 229 }
221 230
222 /// <summary> 231 /// <summary>
@@ -820,7 +829,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
820 private void TeleportAgent(string agent, int regionX, int regionY, 829 private void TeleportAgent(string agent, int regionX, int regionY,
821 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions) 830 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions)
822 { 831 {
823 // ulong regionHandle = Util.UIntsToLong(((uint)regionX * (uint)Constants.RegionSize), ((uint)regionY * (uint)Constants.RegionSize));
824 ulong regionHandle = Util.RegionLocToHandle((uint)regionX, (uint)regionY); 832 ulong regionHandle = Util.RegionLocToHandle((uint)regionX, (uint)regionY);
825 833
826 m_host.AddScriptLPS(1); 834 m_host.AddScriptLPS(1);
@@ -993,18 +1001,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
993 if (target != null) 1001 if (target != null)
994 { 1002 {
995 UUID animID=UUID.Zero; 1003 UUID animID=UUID.Zero;
996 lock (m_host.TaskInventory) 1004 m_host.TaskInventory.LockItemsForRead(true);
1005 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
997 { 1006 {
998 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 1007 if (inv.Value.Name == animation)
999 { 1008 {
1000 if (inv.Value.Name == animation) 1009 if (inv.Value.Type == (int)AssetType.Animation)
1001 { 1010 animID = inv.Value.AssetID;
1002 if (inv.Value.Type == (int)AssetType.Animation) 1011 continue;
1003 animID = inv.Value.AssetID;
1004 continue;
1005 }
1006 } 1012 }
1007 } 1013 }
1014 m_host.TaskInventory.LockItemsForRead(false);
1008 if (animID == UUID.Zero) 1015 if (animID == UUID.Zero)
1009 target.Animator.AddAnimation(animation, m_host.UUID); 1016 target.Animator.AddAnimation(animation, m_host.UUID);
1010 else 1017 else
@@ -1046,6 +1053,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1046 animID = UUID.Zero; 1053 animID = UUID.Zero;
1047 } 1054 }
1048 1055
1056
1049 if (animID == UUID.Zero) 1057 if (animID == UUID.Zero)
1050 target.Animator.RemoveAnimation(animation); 1058 target.Animator.RemoveAnimation(animation);
1051 else 1059 else
@@ -1487,7 +1495,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1487 return; 1495 return;
1488 } 1496 }
1489 1497
1490 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, startLandObject, GroupPowers.LandOptions)) 1498 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, startLandObject, GroupPowers.LandOptions, false))
1491 { 1499 {
1492 OSSLShoutError("You do not have permission to modify the parcel"); 1500 OSSLShoutError("You do not have permission to modify the parcel");
1493 return; 1501 return;
@@ -1722,7 +1730,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1722 } 1730 }
1723 } 1731 }
1724 1732
1725 public Object osParseJSONNew(string JSON) 1733 private Object osParseJSONNew(string JSON)
1726 { 1734 {
1727 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew"); 1735 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew");
1728 1736
@@ -1934,15 +1942,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1934 { 1942 {
1935 UUID assetID = UUID.Zero; 1943 UUID assetID = UUID.Zero;
1936 1944
1937 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1945 bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID);
1946
1947 if (!notecardNameIsUUID)
1938 { 1948 {
1939 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1949 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1940 {
1941 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1942 {
1943 assetID = item.AssetID;
1944 }
1945 }
1946 } 1950 }
1947 1951
1948 if (assetID == UUID.Zero) 1952 if (assetID == UUID.Zero)
@@ -1953,13 +1957,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1953 AssetBase a = World.AssetService.Get(assetID.ToString()); 1957 AssetBase a = World.AssetService.Get(assetID.ToString());
1954 1958
1955 if (a == null) 1959 if (a == null)
1956 return UUID.Zero; 1960 {
1961 // Whoops, it's still possible here that the notecard name was properly
1962 // formatted like a UUID but isn't an asset UUID so lets look it up by name after all
1963 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1964 if (assetID == UUID.Zero)
1965 return UUID.Zero;
1966
1967 if (!NotecardCache.IsCached(assetID))
1968 {
1969 a = World.AssetService.Get(assetID.ToString());
1970
1971 if (a == null)
1972 {
1973 return UUID.Zero;
1974 }
1975 }
1976 }
1957 1977
1958 NotecardCache.Cache(assetID, a.Data); 1978 NotecardCache.Cache(assetID, a.Data);
1959 }; 1979 };
1960 1980
1961 return assetID; 1981 return assetID;
1962 } 1982 }
1983 protected UUID SearchTaskInventoryForAssetId(string name)
1984 {
1985 UUID assetId = UUID.Zero;
1986 m_host.TaskInventory.LockItemsForRead(true);
1987 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1988 {
1989 if (item.Type == 7 && item.Name == name)
1990 {
1991 assetId = item.AssetID;
1992 }
1993 }
1994 m_host.TaskInventory.LockItemsForRead(false);
1995 return assetId;
1996 }
1963 1997
1964 /// <summary> 1998 /// <summary>
1965 /// Directly get an entire notecard at once. 1999 /// Directly get an entire notecard at once.
@@ -2544,7 +2578,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2544 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2578 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2545 m_host.AddScriptLPS(1); 2579 m_host.AddScriptLPS(1);
2546 2580
2547 return NpcCreate(firstname, lastname, position, notecard, false, false); 2581 return NpcCreate(firstname, lastname, position, notecard, true, false);
2548 } 2582 }
2549 2583
2550 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2584 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2555,24 +2589,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2555 return NpcCreate( 2589 return NpcCreate(
2556 firstname, lastname, position, notecard, 2590 firstname, lastname, position, notecard,
2557 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2591 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2558 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2592 false);
2593// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2559 } 2594 }
2560 2595
2561 private LSL_Key NpcCreate( 2596 private LSL_Key NpcCreate(
2562 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2597 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2563 { 2598 {
2599 if (!owned)
2600 OSSLError("Unowned NPCs are unsupported");
2601
2602 string groupTitle = String.Empty;
2603
2604 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2605 return new LSL_Key(UUID.Zero.ToString());
2606
2607 if (firstname != String.Empty || lastname != String.Empty)
2608 {
2609 if (firstname != "Shown outfit:")
2610 groupTitle = "- NPC -";
2611 }
2612
2564 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2613 INPCModule module = World.RequestModuleInterface<INPCModule>();
2565 if (module != null) 2614 if (module != null)
2566 { 2615 {
2567 AvatarAppearance appearance = null; 2616 AvatarAppearance appearance = null;
2568 2617
2569 UUID id; 2618// UUID id;
2570 if (UUID.TryParse(notecard, out id)) 2619// if (UUID.TryParse(notecard, out id))
2571 { 2620// {
2572 ScenePresence clonePresence = World.GetScenePresence(id); 2621// ScenePresence clonePresence = World.GetScenePresence(id);
2573 if (clonePresence != null) 2622// if (clonePresence != null)
2574 appearance = clonePresence.Appearance; 2623// appearance = clonePresence.Appearance;
2575 } 2624// }
2576 2625
2577 if (appearance == null) 2626 if (appearance == null)
2578 { 2627 {
@@ -2580,9 +2629,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2580 2629
2581 if (appearanceSerialized != null) 2630 if (appearanceSerialized != null)
2582 { 2631 {
2583 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2632 try
2584 appearance = new AvatarAppearance(); 2633 {
2585 appearance.Unpack(appearanceOsd); 2634 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2635 appearance = new AvatarAppearance();
2636 appearance.Unpack(appearanceOsd);
2637 }
2638 catch
2639 {
2640 return UUID.Zero.ToString();
2641 }
2586 } 2642 }
2587 else 2643 else
2588 { 2644 {
@@ -2601,6 +2657,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2601 World, 2657 World,
2602 appearance); 2658 appearance);
2603 2659
2660 ScenePresence sp;
2661 if (World.TryGetScenePresence(x, out sp))
2662 {
2663 sp.Grouptitle = groupTitle;
2664 sp.SendAvatarDataToAllAgents();
2665 }
2604 return new LSL_Key(x.ToString()); 2666 return new LSL_Key(x.ToString());
2605 } 2667 }
2606 2668
@@ -2898,16 +2960,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2898 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2960 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2899 m_host.AddScriptLPS(1); 2961 m_host.AddScriptLPS(1);
2900 2962
2901 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2963 ManualResetEvent ev = new ManualResetEvent(false);
2902 if (module != null)
2903 {
2904 UUID npcId = new UUID(npc.m_string);
2905 2964
2906 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2965 Util.FireAndForget(delegate(object x) {
2907 return; 2966 try
2967 {
2968 INPCModule module = World.RequestModuleInterface<INPCModule>();
2969 if (module != null)
2970 {
2971 UUID npcId = new UUID(npc.m_string);
2908 2972
2909 module.DeleteNPC(npcId, World); 2973 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2910 } 2974 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2975 {
2976 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2977 return;
2978 }
2979
2980 module.DeleteNPC(npcId, World);
2981 }
2982 }
2983 finally
2984 {
2985 ev.Set();
2986 }
2987 });
2988 ev.WaitOne();
2911 } 2989 }
2912 2990
2913 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2991 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3185,7 +3263,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3185 { 3263 {
3186 Scene scene = m_ScriptEngine.World; 3264 Scene scene = m_ScriptEngine.World;
3187 GridRegion region = scene.GridService.GetRegionByUUID(UUID.Zero, World.RegionInfo.RegionID); 3265 GridRegion region = scene.GridService.GetRegionByUUID(UUID.Zero, World.RegionInfo.RegionID);
3188 return new LSL_Vector((float)region.RegionSizeX, (float)region.RegionSizeX, Constants.RegionHeight); 3266 return new LSL_Vector(region.RegionSizeX, region.RegionSizeY, Constants.RegionHeight);
3189 } 3267 }
3190 } 3268 }
3191 3269
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..ddd7630 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);
@@ -261,7 +261,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
261 string osGetSimulatorVersion(); 261 string osGetSimulatorVersion();
262 LSL_Integer osCheckODE(); 262 LSL_Integer osCheckODE();
263 string osGetPhysicsEngineType(); 263 string osGetPhysicsEngineType();
264 Object osParseJSONNew(string JSON);
265 Hashtable osParseJSON(string JSON); 264 Hashtable osParseJSON(string JSON);
266 265
267 void osMessageObject(key objectUUID,string message); 266 void osMessageObject(key objectUUID,string message);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 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..2745637 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)
@@ -1558,11 +1555,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1558 m_LSL_Functions.llSetForceAndTorque(force, torque, local); 1555 m_LSL_Functions.llSetForceAndTorque(force, torque, local);
1559 } 1556 }
1560 1557
1561 public void llSetVelocity(LSL_Vector force, int local)
1562 {
1563 m_LSL_Functions.llSetVelocity(force, local);
1564 }
1565
1566 public void llSetAngularVelocity(LSL_Vector force, int local) 1558 public void llSetAngularVelocity(LSL_Vector force, int local)
1567 { 1559 {
1568 m_LSL_Functions.llSetAngularVelocity(force, local); 1560 m_LSL_Functions.llSetAngularVelocity(force, local);
@@ -1643,6 +1635,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1643 m_LSL_Functions.llSetPos(pos); 1635 m_LSL_Functions.llSetPos(pos);
1644 } 1636 }
1645 1637
1638 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1639 {
1640 return m_LSL_Functions.llSetRegionPos(pos);
1641 }
1642
1646 public void llSetPrimitiveParams(LSL_List rules) 1643 public void llSetPrimitiveParams(LSL_List rules)
1647 { 1644 {
1648 m_LSL_Functions.llSetPrimitiveParams(rules); 1645 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1658,11 +1655,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1658 m_LSL_Functions.llSetPrimURL(url); 1655 m_LSL_Functions.llSetPrimURL(url);
1659 } 1656 }
1660 1657
1661 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1662 {
1663 return m_LSL_Functions.llSetRegionPos(pos);
1664 }
1665
1666 public void llSetRemoteScriptAccessPin(int pin) 1658 public void llSetRemoteScriptAccessPin(int pin)
1667 { 1659 {
1668 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1660 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -2008,9 +2000,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
2008 return m_LSL_Functions.llClearLinkMedia(link, face); 2000 return m_LSL_Functions.llClearLinkMedia(link, face);
2009 } 2001 }
2010 2002
2011 public void print(string str) 2003 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
2004 {
2005 return m_LSL_Functions.llGetLinkNumberOfSides(link);
2006 }
2007
2008 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
2009 {
2010 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2011 }
2012
2013 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
2014 {
2015 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
2016 }
2017
2018 public LSL_List llGetPhysicsMaterial()
2019 {
2020 return m_LSL_Functions.llGetPhysicsMaterial();
2021 }
2022
2023 public void llSetAnimationOverride(LSL_String animState, LSL_String anim)
2024 {
2025 m_LSL_Functions.llSetAnimationOverride(animState, anim);
2026 }
2027
2028 public void llResetAnimationOverride(LSL_String anim_state)
2029 {
2030 m_LSL_Functions.llResetAnimationOverride(anim_state);
2031 }
2032
2033 public LSL_String llGetAnimationOverride(LSL_String anim_state)
2034 {
2035 return m_LSL_Functions.llGetAnimationOverride(anim_state);
2036 }
2037
2038 public LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers)
2039 {
2040 return m_LSL_Functions.llJsonGetValue(json, specifiers);
2041 }
2042
2043 public LSL_List llJson2List(LSL_String json)
2044 {
2045 return m_LSL_Functions.llJson2List(json);
2046 }
2047
2048 public LSL_String llList2Json(LSL_String type, LSL_List values)
2049 {
2050 return m_LSL_Functions.llList2Json(type, values);
2051 }
2052
2053 public LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value)
2054 {
2055 return m_LSL_Functions.llJsonSetValue(json, specifiers, value);
2056 }
2057
2058 public LSL_String llJsonValueType(LSL_String json, LSL_List specifiers)
2012 { 2059 {
2013 m_LSL_Functions.print(str); 2060 return m_LSL_Functions.llJsonValueType(json, specifiers);
2014 } 2061 }
2015 } 2062 }
2016} 2063}
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..6e8a96d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -440,11 +440,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
440 return m_OSSL_Functions.osParseJSON(JSON); 440 return m_OSSL_Functions.osParseJSON(JSON);
441 } 441 }
442 442
443 public Object osParseJSONNew(string JSON)
444 {
445 return m_OSSL_Functions.osParseJSONNew(JSON);
446 }
447
448 public void osMessageObject(key objectUUID,string message) 443 public void osMessageObject(key objectUUID,string message)
449 { 444 {
450 m_OSSL_Functions.osMessageObject(objectUUID,message); 445 m_OSSL_Functions.osMessageObject(objectUUID,message);
@@ -752,6 +747,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
752 Position.y = 0; 747 Position.y = 0;
753 if (Position.z < 0) 748 if (Position.z < 0)
754 Position.z = 0; 749 Position.z = 0;
750 if (Position.z > Constants.RegionHeight)
751 Position.z = Constants.RegionHeight;
755 prim.OSSL.llSetPos(Position); 752 prim.OSSL.llSetPos(Position);
756 } 753 }
757 754
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..2633f30 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Reflection; 34using System.Reflection;
34using System.Runtime.Remoting; 35using System.Runtime.Remoting;
35using System.Runtime.Remoting.Lifetime; 36using System.Runtime.Remoting.Lifetime;
@@ -186,13 +187,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
186 187
187 public UUID ItemID { get; private set; } 188 public UUID ItemID { get; private set; }
188 189
189 public UUID ObjectID { get { return Part.UUID; } } 190 public UUID ObjectID { get; private set; }
190 191
191 public uint LocalID { get { return Part.LocalId; } } 192 public uint LocalID { get; private set; }
192 193
193 public UUID RootObjectID { get { return Part.ParentGroup.UUID; } } 194 public UUID RootObjectID { get; private set; }
194 195
195 public uint RootLocalID { get { return Part.ParentGroup.LocalId; } } 196 public uint RootLocalID { get; private set; }
196 197
197 public UUID AssetID { get; private set; } 198 public UUID AssetID { get; private set; }
198 199
@@ -251,13 +252,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
251 ItemID = ScriptTask.ItemID; 252 ItemID = ScriptTask.ItemID;
252 AssetID = ScriptTask.AssetID; 253 AssetID = ScriptTask.AssetID;
253 } 254 }
255 LocalID = part.LocalId;
254 256
255 PrimName = part.ParentGroup.Name; 257 PrimName = part.ParentGroup.Name;
256 StartParam = startParam; 258 StartParam = startParam;
257 m_MaxScriptQueue = maxScriptQueue; 259 m_MaxScriptQueue = maxScriptQueue;
258 m_postOnRez = postOnRez; 260 m_postOnRez = postOnRez;
259 m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; 261 m_AttachedAvatar = part.ParentGroup.AttachedAvatar;
260 m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; 262 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID;
261 263
262 m_SaveState = StatePersistedHere; 264 m_SaveState = StatePersistedHere;
263 265
@@ -456,27 +458,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
456 PostEvent(new EventParams("attach", 458 PostEvent(new EventParams("attach",
457 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); 459 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0]));
458 } 460 }
461
459 } 462 }
460 } 463 }
461 464
462 private void ReleaseControls() 465 private void ReleaseControls()
463 { 466 {
464 int permsMask; 467 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
465 UUID permsGranter; 468
466 lock (Part.TaskInventory) 469 if (part != null)
467 { 470 {
468 if (!Part.TaskInventory.ContainsKey(ItemID)) 471 int permsMask;
472 UUID permsGranter;
473 part.TaskInventory.LockItemsForRead(true);
474 if (!part.TaskInventory.ContainsKey(ItemID))
475 {
476 part.TaskInventory.LockItemsForRead(false);
469 return; 477 return;
478 }
479 permsGranter = part.TaskInventory[ItemID].PermsGranter;
480 permsMask = part.TaskInventory[ItemID].PermsMask;
481 part.TaskInventory.LockItemsForRead(false);
470 482
471 permsGranter = Part.TaskInventory[ItemID].PermsGranter; 483 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
472 permsMask = Part.TaskInventory[ItemID].PermsMask; 484 {
473 } 485 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
474 486 if (presence != null)
475 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 487 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
476 { 488 }
477 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
478 if (presence != null)
479 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
480 } 489 }
481 } 490 }
482 491
@@ -639,6 +648,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
639 return true; 648 return true;
640 } 649 }
641 650
651 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
642 public void SetState(string state) 652 public void SetState(string state)
643 { 653 {
644 if (state == State) 654 if (state == State)
@@ -764,6 +774,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
764 /// <returns></returns> 774 /// <returns></returns>
765 public object EventProcessor() 775 public object EventProcessor()
766 { 776 {
777 EventParams data = null;
767 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 778 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
768 if (!Running) 779 if (!Running)
769 return 0; 780 return 0;
@@ -850,7 +861,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
850 Part.ParentGroup.UUID, 861 Part.ParentGroup.UUID,
851 Part.AbsolutePosition, 862 Part.AbsolutePosition,
852 Part.ParentGroup.Scene.Name); 863 Part.ParentGroup.Scene.Name);
853
854 AsyncCommandManager.StateChange(Engine, 864 AsyncCommandManager.StateChange(Engine,
855 LocalID, ItemID); 865 LocalID, ItemID);
856 // we are effectively in the new state now, so we can resume queueing 866 // we are effectively in the new state now, so we can resume queueing
@@ -867,6 +877,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
867 // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", 877 // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
868 // PrimName, ScriptName, data.EventName, State); 878 // PrimName, ScriptName, data.EventName, State);
869 879
880
870 try 881 try
871 { 882 {
872 m_CurrentEvent = data.EventName; 883 m_CurrentEvent = data.EventName;
@@ -931,15 +942,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
931 catch (Exception) 942 catch (Exception)
932 { 943 {
933 } 944 }
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 } 945 }
944 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) 946 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
945 { 947 {
@@ -1012,15 +1014,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1012 ReleaseControls(); 1014 ReleaseControls();
1013 1015
1014 Stop(timeout); 1016 Stop(timeout);
1015 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 1017 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
1016 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 1018 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
1019 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
1020 part.CollisionSound = UUID.Zero;
1017 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 1021 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
1018 EventQueue.Clear(); 1022 EventQueue.Clear();
1019 m_Script.ResetVars(); 1023 m_Script.ResetVars();
1020 StartParam = 0; 1024 StartParam = 0;
1021 State = "default"; 1025 State = "default";
1022 1026
1023 Part.SetScriptEvents(ItemID, 1027 part.SetScriptEvents(ItemID,
1024 (int)m_Script.GetStateEventFlags(State)); 1028 (int)m_Script.GetStateEventFlags(State));
1025 if (running) 1029 if (running)
1026 Start(); 1030 Start();
@@ -1031,6 +1035,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1031 new Object[0], new DetectParams[0])); 1035 new Object[0], new DetectParams[0]));
1032 } 1036 }
1033 1037
1038 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
1034 public void ApiResetScript() 1039 public void ApiResetScript()
1035 { 1040 {
1036 // bool running = Running; 1041 // bool running = Running;
@@ -1039,8 +1044,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1039 ReleaseControls(); 1044 ReleaseControls();
1040 1045
1041 m_Script.ResetVars(); 1046 m_Script.ResetVars();
1042 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 1047 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
1043 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 1048 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
1049 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
1050 part.CollisionSound = UUID.Zero;
1044 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 1051 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
1045 1052
1046 EventQueue.Clear(); 1053 EventQueue.Clear();
@@ -1049,7 +1056,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1049 StartParam = 0; 1056 StartParam = 0;
1050 State = "default"; 1057 State = "default";
1051 1058
1052 Part.SetScriptEvents(ItemID, 1059 part.SetScriptEvents(ItemID,
1053 (int)m_Script.GetStateEventFlags(State)); 1060 (int)m_Script.GetStateEventFlags(State));
1054 1061
1055 if (m_CurrentEvent != "state_entry" || oldState != "default") 1062 if (m_CurrentEvent != "state_entry" || oldState != "default")
@@ -1063,10 +1070,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1063 1070
1064 public Dictionary<string, object> GetVars() 1071 public Dictionary<string, object> GetVars()
1065 { 1072 {
1066 if (m_Script != null) 1073 return m_Script.GetVars();
1067 return m_Script.GetVars();
1068 else
1069 return new Dictionary<string, object>();
1070 } 1074 }
1071 1075
1072 public void SetVars(Dictionary<string, object> vars) 1076 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 0ca5ff3..5fce15c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -102,19 +102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
102 102
103 public override string ToString() 103 public override string ToString()
104 { 104 {
105 string s=String.Format(Culture.FormatProvider,"<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 105 string s = String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
106 return s; 106 return s;
107 } 107 }
108 108
109 public static explicit operator LSLString(Vector3 vec) 109 public static explicit operator LSLString(Vector3 vec)
110 { 110 {
111 string s=String.Format(Culture.FormatProvider,"<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 111 string s = String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
112 return new LSLString(s); 112 return new LSLString(s);
113 } 113 }
114 114
115 public static explicit operator string(Vector3 vec) 115 public static explicit operator string(Vector3 vec)
116 { 116 {
117 string s=String.Format(Culture.FormatProvider,"<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 117 string s = String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
118 return s; 118 return s;
119 } 119 }
120 120
@@ -414,19 +414,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
414 414
415 public override string ToString() 415 public override string ToString()
416 { 416 {
417 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 417 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; 418 return st;
419 } 419 }
420 420
421 public static explicit operator string(Quaternion r) 421 public static explicit operator string(Quaternion r)
422 { 422 {
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); 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);
424 return s; 424 return s;
425 } 425 }
426 426
427 public static explicit operator LSLString(Quaternion r) 427 public static explicit operator LSLString(Quaternion r)
428 { 428 {
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); 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);
430 return new LSLString(s); 430 return new LSLString(s);
431 } 431 }
432 432
@@ -537,7 +537,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
537 else if (o is LSL_Types.LSLFloat) 537 else if (o is LSL_Types.LSLFloat)
538 size += 8; 538 size += 8;
539 else if (o is LSL_Types.LSLString) 539 else if (o is LSL_Types.LSLString)
540 size += ((LSL_Types.LSLString)o).m_string.Length; 540 size += ((LSL_Types.LSLString)o).m_string == null ? 0 : ((LSL_Types.LSLString)o).m_string.Length;
541 else if (o is LSL_Types.key) 541 else if (o is LSL_Types.key)
542 size += ((LSL_Types.key)o).value.Length; 542 size += ((LSL_Types.key)o).value.Length;
543 else if (o is LSL_Types.Vector3) 543 else if (o is LSL_Types.Vector3)
@@ -546,6 +546,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
546 size += 64; 546 size += 64;
547 else if (o is int) 547 else if (o is int)
548 size += 4; 548 size += 4;
549 else if (o is uint)
550 size += 4;
549 else if (o is string) 551 else if (o is string)
550 size += ((string)o).Length; 552 size += ((string)o).Length;
551 else if (o is float) 553 else if (o is float)
@@ -739,24 +741,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
739 741
740 public static bool operator ==(list a, list b) 742 public static bool operator ==(list a, list b)
741 { 743 {
742 int la = -1; 744 int la = a.Length;
743 int lb = -1; 745 int lb = b.Length;
744 try { la = a.Length; }
745 catch (NullReferenceException) { }
746 try { lb = b.Length; }
747 catch (NullReferenceException) { }
748 746
749 return la == lb; 747 return la == lb;
750 } 748 }
751 749
752 public static bool operator !=(list a, list b) 750 public static bool operator !=(list a, list b)
753 { 751 {
754 int la = -1; 752 int la = a.Length;
755 int lb = -1; 753 int lb = b.Length;
756 try { la = a.Length; }
757 catch (NullReferenceException) { }
758 try {lb = b.Length;}
759 catch (NullReferenceException) { }
760 754
761 return la != lb; 755 return la != lb;
762 } 756 }
@@ -990,7 +984,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
990 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 984 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
991 } 985 }
992 986
993 if (ascending == 0) 987 if (ascending != 1)
994 { 988 {
995 ret = 0 - ret; 989 ret = 0 - ret;
996 } 990 }
@@ -1023,6 +1017,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
1023 stride = 1; 1017 stride = 1;
1024 } 1018 }
1025 1019
1020 if ((Data.Length % stride) != 0)
1021 return new list(ret);
1022
1026 // we can optimize here in the case where stride == 1 and the list 1023 // we can optimize here in the case where stride == 1 and the list
1027 // consists of homogeneous types 1024 // consists of homogeneous types
1028 1025
@@ -1042,7 +1039,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1042 if (homogeneous) 1039 if (homogeneous)
1043 { 1040 {
1044 Array.Sort(ret, new HomogeneousComparer()); 1041 Array.Sort(ret, new HomogeneousComparer());
1045 if (ascending == 0) 1042 if (ascending != 1)
1046 { 1043 {
1047 Array.Reverse(ret); 1044 Array.Reverse(ret);
1048 } 1045 }
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