aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api/Implementation
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs117
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3497
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs157
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs22
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
7 files changed, 2732 insertions, 1131 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 998f40b..1e19032 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)
@@ -364,6 +365,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
364 } 365 }
365 } 366 }
366 367
368 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
369 {
370 // Remove a specific script
371
372 // Remove dataserver events
373 m_Dataserver[engine].RemoveEvents(localID, itemID);
374
375 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
376 if (comms != null)
377 comms.DeleteListener(itemID);
378
379 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
380 if (xmlrpc != null)
381 {
382 xmlrpc.DeleteChannels(itemID);
383 xmlrpc.CancelSRDRequests(itemID);
384 }
385
386 // Remove Sensors
387 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
388
389 }
390
367 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 391 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
368 { 392 {
369 List<Object> data = new List<Object>(); 393 List<Object> data = new List<Object>();
@@ -439,4 +463,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
439 } 463 }
440 } 464 }
441 } 465 }
442} \ No newline at end of file 466}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..fce8ff8
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,117 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Threading;
30using System.Reflection;
31using System.Collections;
32using System.Collections.Generic;
33using System.Runtime.Remoting.Lifetime;
34using OpenMetaverse;
35using Nini.Config;
36using OpenSim;
37using OpenSim.Framework;
38using OpenSim.Region.CoreModules.World.LightShare;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.ScriptEngine.Shared;
42using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
43using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
44using OpenSim.Region.ScriptEngine.Interfaces;
45using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
46using OpenSim.Services.Interfaces;
47
48using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
49using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
50using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
51using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
52using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
53using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
54using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
55
56namespace OpenSim.Region.ScriptEngine.Shared.Api
57{
58 [Serializable]
59 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
60 {
61 internal IScriptEngine m_ScriptEngine;
62 internal SceneObjectPart m_host;
63 internal TaskInventoryItem m_item;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_item = item;
71
72 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
73 m_CMFunctionsEnabled = true;
74 }
75
76 public override Object InitializeLifetimeService()
77 {
78 ILease lease = (ILease)base.InitializeLifetimeService();
79
80 if (lease.CurrentState == LeaseState.Initial)
81 {
82 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
83 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
84 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
85 }
86 return lease;
87 }
88
89 public Scene World
90 {
91 get { return m_ScriptEngine.World; }
92 }
93
94 public string cmDetectedCountry(int number)
95 {
96 m_host.AddScriptLPS(1);
97 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
98 if (detectedParams == null)
99 return String.Empty;
100 return detectedParams.Country;
101 }
102
103 public string cmGetAgentCountry(LSL_Key key)
104 {
105 if (!World.Permissions.IsGod(m_host.OwnerID))
106 return String.Empty;
107
108 UUID uuid;
109
110 if (!UUID.TryParse(key, out uuid))
111 return String.Empty;
112
113 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
114 return account.UserCountry;
115 }
116 }
117}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index c0b8373..d5f14bf 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,14 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Framework.Scenes.Scripting; 51using OpenSim.Region.Framework.Scenes.Scripting;
49using OpenSim.Region.Physics.Manager; 52using OpenSim.Region.Physics.Manager;
@@ -67,6 +70,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
67using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 70using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
68using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 71using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
69using System.Reflection; 72using System.Reflection;
73using Timer = System.Timers.Timer;
70using System.Linq; 74using System.Linq;
71using PermissionMask = OpenSim.Framework.PermissionMask; 75using PermissionMask = OpenSim.Framework.PermissionMask;
72 76
@@ -115,11 +119,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
115 protected int m_notecardLineReadCharsMax = 255; 119 protected int m_notecardLineReadCharsMax = 255;
116 protected int m_scriptConsoleChannel = 0; 120 protected int m_scriptConsoleChannel = 0;
117 protected bool m_scriptConsoleChannelEnabled = false; 121 protected bool m_scriptConsoleChannelEnabled = false;
122 protected bool m_debuggerSafe = false;
118 protected IUrlModule m_UrlModule = null; 123 protected IUrlModule m_UrlModule = null;
119 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 124 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
120 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 125 new Dictionary<UUID, UserInfoCacheEntry>();
126 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
121 protected ISoundModule m_SoundModule = null; 127 protected ISoundModule m_SoundModule = null;
122 128
129// protected Timer m_ShoutSayTimer;
130 protected int m_SayShoutCount = 0;
131 DateTime m_lastSayShoutCheck;
132
133 private Dictionary<string, string> MovementAnimationsForLSL =
134 new Dictionary<string, string> {
135 {"FLY", "Flying"},
136 {"FLYSLOW", "FlyingSlow"},
137 {"HOVER_UP", "Hovering Up"},
138 {"HOVER_DOWN", "Hovering Down"},
139 {"HOVER", "Hovering"},
140 {"LAND", "Landing"},
141 {"FALLDOWN", "Falling Down"},
142 {"PREJUMP", "PreJumping"},
143 {"JUMP", "Jumping"},
144 {"STANDUP", "Standing Up"},
145 {"SOFT_LAND", "Soft Landing"},
146 {"STAND", "Standing"},
147 {"CROUCHWALK", "CrouchWalking"},
148 {"RUN", "Running"},
149 {"WALK", "Walking"},
150 {"CROUCH", "Crouching"},
151 {"TURNLEFT", "Turning Left"},
152 {"TURNRIGHT", "Turning Right"}
153 };
123 //An array of HTTP/1.1 headers that are not allowed to be used 154 //An array of HTTP/1.1 headers that are not allowed to be used
124 //as custom headers by llHTTPRequest. 155 //as custom headers by llHTTPRequest.
125 private string[] HttpStandardHeaders = 156 private string[] HttpStandardHeaders =
@@ -140,9 +171,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
140 public void Initialize( 171 public void Initialize(
141 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) 172 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
142 { 173 {
174 m_lastSayShoutCheck = DateTime.UtcNow;
175
143 m_ScriptEngine = scriptEngine; 176 m_ScriptEngine = scriptEngine;
144 m_host = host; 177 m_host = host;
145 m_item = item; 178 m_item = item;
179 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
146 m_coopSleepHandle = coopSleepHandle; 180 m_coopSleepHandle = coopSleepHandle;
147 181
148 LoadConfig(); 182 LoadConfig();
@@ -231,6 +265,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
231 get { return m_ScriptEngine.World; } 265 get { return m_ScriptEngine.World; }
232 } 266 }
233 267
268 [DebuggerNonUserCode]
234 public void state(string newState) 269 public void state(string newState)
235 { 270 {
236 m_ScriptEngine.SetState(m_item.ItemID, newState); 271 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -240,6 +275,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
240 /// Reset the named script. The script must be present 275 /// Reset the named script. The script must be present
241 /// in the same prim. 276 /// in the same prim.
242 /// </summary> 277 /// </summary>
278 [DebuggerNonUserCode]
243 public void llResetScript() 279 public void llResetScript()
244 { 280 {
245 m_host.AddScriptLPS(1); 281 m_host.AddScriptLPS(1);
@@ -302,6 +338,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
302 } 338 }
303 } 339 }
304 340
341 public List<ScenePresence> GetLinkAvatars(int linkType)
342 {
343 List<ScenePresence> ret = new List<ScenePresence>();
344 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
345 return ret;
346
347 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
348
349 switch (linkType)
350 {
351 case ScriptBaseClass.LINK_SET:
352 return avs;
353
354 case ScriptBaseClass.LINK_ROOT:
355 return ret;
356
357 case ScriptBaseClass.LINK_ALL_OTHERS:
358 return avs;
359
360 case ScriptBaseClass.LINK_ALL_CHILDREN:
361 return avs;
362
363 case ScriptBaseClass.LINK_THIS:
364 return ret;
365
366 default:
367 if (linkType < 0)
368 return ret;
369
370 int partCount = m_host.ParentGroup.GetPartCount();
371
372 if (linkType <= partCount)
373 {
374 return ret;
375 }
376 else
377 {
378 linkType = linkType - partCount;
379 if (linkType > avs.Count)
380 {
381 return ret;
382 }
383 else
384 {
385 ret.Add(avs[linkType-1]);
386 return ret;
387 }
388 }
389 }
390 }
391
305 /// <summary> 392 /// <summary>
306 /// Get a given link entity from a linkset (linked objects and any sitting avatars). 393 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
307 /// </summary> 394 /// </summary>
@@ -384,6 +471,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
384 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 471 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
385 { 472 {
386 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 473 List<SceneObjectPart> ret = new List<SceneObjectPart>();
474 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
475 return ret;
387 ret.Add(part); 476 ret.Add(part);
388 477
389 switch (linkType) 478 switch (linkType)
@@ -537,31 +626,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
537 626
538 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 627 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
539 628
540 /// <summary> 629 // Utility function for llRot2Euler
541 /// Convert an LSL rotation to a Euler vector. 630
542 /// </summary> 631 // normalize an angle between -PI and PI (-180 to +180 degrees)
543 /// <remarks> 632 protected double NormalizeAngle(double angle)
544 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
545 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
546 /// </remarks>
547 /// <param name="r"></param>
548 /// <returns></returns>
549 public LSL_Vector llRot2Euler(LSL_Rotation r)
550 { 633 {
551 m_host.AddScriptLPS(1); 634 if (angle > -Math.PI && angle < Math.PI)
635 return angle;
552 636
553 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 637 int numPis = (int)(Math.PI / angle);
554 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 638 double remainder = angle - Math.PI * numPis;
555 if (m == 0.0) return new LSL_Vector(); 639 if (numPis % 2 == 1)
556 double x = Math.Atan2(-v.y, v.z); 640 return Math.PI - angle;
557 double sin = v.x / m; 641 return remainder;
558 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 642 }
559 double y = Math.Asin(sin);
560 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
561 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)));
562 double z = Math.Atan2(v.y, v.x);
563 643
564 return new LSL_Vector(x, y, z); 644 public LSL_Vector llRot2Euler(LSL_Rotation q1)
645 {
646 m_host.AddScriptLPS(1);
647 LSL_Vector eul = new LSL_Vector();
648
649 double sqw = q1.s*q1.s;
650 double sqx = q1.x*q1.x;
651 double sqy = q1.z*q1.z;
652 double sqz = q1.y*q1.y;
653 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
654 double test = q1.x*q1.z + q1.y*q1.s;
655 if (test > 0.4999*unit) { // singularity at north pole
656 eul.z = 2 * Math.Atan2(q1.x,q1.s);
657 eul.y = Math.PI/2;
658 eul.x = 0;
659 return eul;
660 }
661 if (test < -0.4999*unit) { // singularity at south pole
662 eul.z = -2 * Math.Atan2(q1.x,q1.s);
663 eul.y = -Math.PI/2;
664 eul.x = 0;
665 return eul;
666 }
667 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
668 eul.y = Math.Asin(2*test/unit);
669 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
670 return eul;
565 } 671 }
566 672
567 /* From wiki: 673 /* From wiki:
@@ -614,18 +720,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
614 m_host.AddScriptLPS(1); 720 m_host.AddScriptLPS(1);
615 721
616 double x,y,z,s; 722 double x,y,z,s;
617 723 v.x *= 0.5;
618 double c1 = Math.Cos(v.x * 0.5); 724 v.y *= 0.5;
619 double c2 = Math.Cos(v.y * 0.5); 725 v.z *= 0.5;
620 double c3 = Math.Cos(v.z * 0.5); 726 double c1 = Math.Cos(v.x);
621 double s1 = Math.Sin(v.x * 0.5); 727 double c2 = Math.Cos(v.y);
622 double s2 = Math.Sin(v.y * 0.5); 728 double c1c2 = c1 * c2;
623 double s3 = Math.Sin(v.z * 0.5); 729 double s1 = Math.Sin(v.x);
624 730 double s2 = Math.Sin(v.y);
625 x = s1 * c2 * c3 + c1 * s2 * s3; 731 double s1s2 = s1 * s2;
626 y = c1 * s2 * c3 - s1 * c2 * s3; 732 double c1s2 = c1 * s2;
627 z = s1 * s2 * c3 + c1 * c2 * s3; 733 double s1c2 = s1 * c2;
628 s = c1 * c2 * c3 - s1 * s2 * s3; 734 double c3 = Math.Cos(v.z);
735 double s3 = Math.Sin(v.z);
736
737 x = s1c2 * c3 + c1s2 * s3;
738 y = c1s2 * c3 - s1c2 * s3;
739 z = s1s2 * c3 + c1c2 * s3;
740 s = c1c2 * c3 - s1s2 * s3;
629 741
630 return new LSL_Rotation(x, y, z, s); 742 return new LSL_Rotation(x, y, z, s);
631 } 743 }
@@ -763,77 +875,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
763 { 875 {
764 //A and B should both be normalized 876 //A and B should both be normalized
765 m_host.AddScriptLPS(1); 877 m_host.AddScriptLPS(1);
766 LSL_Rotation rotBetween; 878 /* This method is more accurate than the SL one, and thus causes problems
767 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 879 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
768 // continue calculation. 880
769 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 881 double dotProduct = LSL_Vector.Dot(a, b);
770 { 882 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
771 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 883 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
772 } 884 double angle = Math.Acos(dotProduct / magProduct);
773 else 885 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
774 { 886 double s = Math.Sin(angle / 2);
775 a = LSL_Vector.Norm(a); 887
776 b = LSL_Vector.Norm(b); 888 double x = axis.x * s;
777 double dotProduct = LSL_Vector.Dot(a, b); 889 double y = axis.y * s;
778 // There are two degenerate cases possible. These are for vectors 180 or 890 double z = axis.z * s;
779 // 0 degrees apart. These have to be detected and handled individually. 891 double w = Math.Cos(angle / 2);
780 // 892
781 // Check for vectors 180 degrees apart. 893 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
782 // A dot product of -1 would mean the angle between vectors is 180 degrees. 894 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
783 if (dotProduct < -0.9999999f) 895
784 { 896 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
785 // First assume X axis is orthogonal to the vectors. 897 */
786 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 898
787 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 899 // This method mimics the 180 errors found in SL
788 // Check for near zero vector. A very small non-zero number here will create 900 // See www.euclideanspace.com... angleBetween
789 // a rotation in an undesired direction. 901 LSL_Vector vec_a = a;
790 if (LSL_Vector.Mag(orthoVector) > 0.0001) 902 LSL_Vector vec_b = b;
791 { 903
792 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 904 // Eliminate zero length
793 } 905 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
794 // If the magnitude of the vector was near zero, then assume the X axis is not 906 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
795 // orthogonal and use the Z axis instead. 907 if (vec_a_mag < 0.00001 ||
796 else 908 vec_b_mag < 0.00001)
797 { 909 {
798 // Set 180 z rotation. 910 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
799 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f); 911 }
800 } 912
801 } 913 // Normalize
802 // Check for parallel vectors. 914 vec_a = llVecNorm(vec_a);
803 // A dot product of 1 would mean the angle between vectors is 0 degrees. 915 vec_b = llVecNorm(vec_b);
804 else if (dotProduct > 0.9999999f) 916
805 { 917 // Calculate axis and rotation angle
806 // Set zero rotation. 918 LSL_Vector axis = vec_a % vec_b;
807 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 919 LSL_Float cos_theta = vec_a * vec_b;
808 } 920
809 else 921 // Check if parallel
810 { 922 if (cos_theta > 0.99999)
811 // All special checks have been performed so get the axis of rotation. 923 {
812 LSL_Vector crossProduct = LSL_Vector.Cross(a, b); 924 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
813 // Quarternion s value is the length of the unit vector + dot product. 925 }
814 double qs = 1.0 + dotProduct; 926
815 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs); 927 // Check if anti-parallel
816 // Normalize the rotation. 928 else if (cos_theta < -0.99999)
817 double mag = LSL_Rotation.Mag(rotBetween); 929 {
818 // We shouldn't have to worry about a divide by zero here. The qs value will be 930 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
819 // non-zero because we already know if we're here, then the dotProduct is not -1 so 931 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
820 // qs will not be zero. Also, we've already handled the input vectors being zero so the 932 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
821 // crossProduct vector should also not be zero. 933 }
822 rotBetween.x = rotBetween.x / mag; 934 else // other rotation
823 rotBetween.y = rotBetween.y / mag; 935 {
824 rotBetween.z = rotBetween.z / mag; 936 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
825 rotBetween.s = rotBetween.s / mag; 937 axis = llVecNorm(axis);
826 // Check for undefined values and set zero rotation if any found. This code might not actually be required 938 double x, y, z, s, t;
827 // any longer since zero vectors are checked for at the top. 939 s = Math.Cos(theta);
828 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s)) 940 t = Math.Sin(theta);
829 { 941 x = axis.x * t;
830 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 942 y = axis.y * t;
831 } 943 z = axis.z * t;
832 } 944 return new LSL_Rotation(x,y,z,s);
833 } 945 }
834 return rotBetween; 946 }
835 } 947
836
837 public void llWhisper(int channelID, string text) 948 public void llWhisper(int channelID, string text)
838 { 949 {
839 m_host.AddScriptLPS(1); 950 m_host.AddScriptLPS(1);
@@ -849,10 +960,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
849 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 960 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
850 } 961 }
851 962
963 private void CheckSayShoutTime()
964 {
965 DateTime now = DateTime.UtcNow;
966 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
967 {
968 m_lastSayShoutCheck = now;
969 m_SayShoutCount = 0;
970 }
971 else
972 m_SayShoutCount++;
973 }
974
852 public void llSay(int channelID, string text) 975 public void llSay(int channelID, string text)
853 { 976 {
854 m_host.AddScriptLPS(1); 977 m_host.AddScriptLPS(1);
855 978
979 if (channelID == 0)
980// m_SayShoutCount++;
981 CheckSayShoutTime();
982
983 if (m_SayShoutCount >= 11)
984 ScriptSleep(2000);
985
856 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 986 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
857 { 987 {
858 Console.WriteLine(text); 988 Console.WriteLine(text);
@@ -875,6 +1005,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
875 { 1005 {
876 m_host.AddScriptLPS(1); 1006 m_host.AddScriptLPS(1);
877 1007
1008 if (channelID == 0)
1009// m_SayShoutCount++;
1010 CheckSayShoutTime();
1011
1012 if (m_SayShoutCount >= 11)
1013 ScriptSleep(2000);
1014
878 if (text.Length > 1023) 1015 if (text.Length > 1023)
879 text = text.Substring(0, 1023); 1016 text = text.Substring(0, 1023);
880 1017
@@ -906,22 +1043,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
906 1043
907 public void llRegionSayTo(string target, int channel, string msg) 1044 public void llRegionSayTo(string target, int channel, string msg)
908 { 1045 {
1046 string error = String.Empty;
1047
909 if (msg.Length > 1023) 1048 if (msg.Length > 1023)
910 msg = msg.Substring(0, 1023); 1049 msg = msg.Substring(0, 1023);
911 1050
912 m_host.AddScriptLPS(1); 1051 m_host.AddScriptLPS(1);
913 1052
914 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
915 {
916 return;
917 }
918
919 UUID TargetID; 1053 UUID TargetID;
920 UUID.TryParse(target, out TargetID); 1054 UUID.TryParse(target, out TargetID);
921 1055
922 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1056 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
923 if (wComm != null) 1057 if (wComm != null)
924 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1058 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1059 LSLError(error);
925 } 1060 }
926 1061
927 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1062 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1177,10 +1312,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 return detectedParams.TouchUV; 1312 return detectedParams.TouchUV;
1178 } 1313 }
1179 1314
1315 [DebuggerNonUserCode]
1180 public virtual void llDie() 1316 public virtual void llDie()
1181 { 1317 {
1182 m_host.AddScriptLPS(1); 1318 m_host.AddScriptLPS(1);
1183 throw new SelfDeleteException(); 1319 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1184 } 1320 }
1185 1321
1186 public LSL_Float llGround(LSL_Vector offset) 1322 public LSL_Float llGround(LSL_Vector offset)
@@ -1251,6 +1387,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1251 1387
1252 public void llSetStatus(int status, int value) 1388 public void llSetStatus(int status, int value)
1253 { 1389 {
1390 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1391 return;
1254 m_host.AddScriptLPS(1); 1392 m_host.AddScriptLPS(1);
1255 1393
1256 int statusrotationaxis = 0; 1394 int statusrotationaxis = 0;
@@ -1274,6 +1412,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1274 if (!allow) 1412 if (!allow)
1275 return; 1413 return;
1276 1414
1415 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1416 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1417 return;
1418
1277 m_host.ScriptSetPhysicsStatus(true); 1419 m_host.ScriptSetPhysicsStatus(true);
1278 } 1420 }
1279 else 1421 else
@@ -1474,12 +1616,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1474 { 1616 {
1475 m_host.AddScriptLPS(1); 1617 m_host.AddScriptLPS(1);
1476 1618
1619 SetColor(m_host, color, face);
1620 }
1621
1622 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1623 {
1624 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1625 return;
1626
1627 Primitive.TextureEntry tex = part.Shape.Textures;
1628 Color4 texcolor;
1629 if (face >= 0 && face < GetNumberOfSides(part))
1630 {
1631 texcolor = tex.CreateFace((uint)face).RGBA;
1632 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1633 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1634 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1635 tex.FaceTextures[face].RGBA = texcolor;
1636 part.UpdateTextureEntry(tex.GetBytes());
1637 return;
1638 }
1639 else if (face == ScriptBaseClass.ALL_SIDES)
1640 {
1641 for (uint i = 0; i < GetNumberOfSides(part); i++)
1642 {
1643 if (tex.FaceTextures[i] != null)
1644 {
1645 texcolor = tex.FaceTextures[i].RGBA;
1646 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1647 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1648 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1649 tex.FaceTextures[i].RGBA = texcolor;
1650 }
1651 texcolor = tex.DefaultTexture.RGBA;
1652 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1653 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1654 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1655 tex.DefaultTexture.RGBA = texcolor;
1656 }
1657 part.UpdateTextureEntry(tex.GetBytes());
1658 return;
1659 }
1660
1477 if (face == ScriptBaseClass.ALL_SIDES) 1661 if (face == ScriptBaseClass.ALL_SIDES)
1478 face = SceneObjectPart.ALL_SIDES; 1662 face = SceneObjectPart.ALL_SIDES;
1479 1663
1480 m_host.SetFaceColorAlpha(face, color, null); 1664 m_host.SetFaceColorAlpha(face, color, null);
1481 } 1665 }
1482 1666
1667 /*
1483 public void llSetContentType(LSL_Key id, LSL_Integer type) 1668 public void llSetContentType(LSL_Key id, LSL_Integer type)
1484 { 1669 {
1485 m_host.AddScriptLPS(1); 1670 m_host.AddScriptLPS(1);
@@ -1546,9 +1731,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1546 break; 1731 break;
1547 } 1732 }
1548 } 1733 }
1734 */
1549 1735
1550 public void SetTexGen(SceneObjectPart part, int face,int style) 1736 public void SetTexGen(SceneObjectPart part, int face,int style)
1551 { 1737 {
1738 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1739 return;
1740
1552 Primitive.TextureEntry tex = part.Shape.Textures; 1741 Primitive.TextureEntry tex = part.Shape.Textures;
1553 MappingType textype; 1742 MappingType textype;
1554 textype = MappingType.Default; 1743 textype = MappingType.Default;
@@ -1579,6 +1768,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1579 1768
1580 public void SetGlow(SceneObjectPart part, int face, float glow) 1769 public void SetGlow(SceneObjectPart part, int face, float glow)
1581 { 1770 {
1771 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1772 return;
1773
1582 Primitive.TextureEntry tex = part.Shape.Textures; 1774 Primitive.TextureEntry tex = part.Shape.Textures;
1583 if (face >= 0 && face < GetNumberOfSides(part)) 1775 if (face >= 0 && face < GetNumberOfSides(part))
1584 { 1776 {
@@ -1604,6 +1796,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1604 1796
1605 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1797 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1606 { 1798 {
1799 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1800 return;
1607 1801
1608 Shininess sval = new Shininess(); 1802 Shininess sval = new Shininess();
1609 1803
@@ -1654,6 +1848,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1654 1848
1655 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1849 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1656 { 1850 {
1851 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1852 return;
1853
1657 Primitive.TextureEntry tex = part.Shape.Textures; 1854 Primitive.TextureEntry tex = part.Shape.Textures;
1658 if (face >= 0 && face < GetNumberOfSides(part)) 1855 if (face >= 0 && face < GetNumberOfSides(part))
1659 { 1856 {
@@ -1714,13 +1911,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1714 m_host.AddScriptLPS(1); 1911 m_host.AddScriptLPS(1);
1715 1912
1716 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1913 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1717 1914 if (parts.Count > 0)
1718 foreach (SceneObjectPart part in parts) 1915 {
1719 SetAlpha(part, alpha, face); 1916 try
1917 {
1918 foreach (SceneObjectPart part in parts)
1919 SetAlpha(part, alpha, face);
1920 }
1921 finally
1922 {
1923 }
1924 }
1720 } 1925 }
1721 1926
1722 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1927 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1723 { 1928 {
1929 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1930 return;
1931
1724 Primitive.TextureEntry tex = part.Shape.Textures; 1932 Primitive.TextureEntry tex = part.Shape.Textures;
1725 Color4 texcolor; 1933 Color4 texcolor;
1726 if (face >= 0 && face < GetNumberOfSides(part)) 1934 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1773,7 +1981,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1773 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1981 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1774 float wind, float tension, LSL_Vector Force) 1982 float wind, float tension, LSL_Vector Force)
1775 { 1983 {
1776 if (part == null) 1984 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1777 return; 1985 return;
1778 1986
1779 if (flexi) 1987 if (flexi)
@@ -1814,7 +2022,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1814 /// <param name="falloff"></param> 2022 /// <param name="falloff"></param>
1815 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 2023 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1816 { 2024 {
1817 if (part == null) 2025 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1818 return; 2026 return;
1819 2027
1820 if (light) 2028 if (light)
@@ -1847,11 +2055,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1847 Primitive.TextureEntry tex = part.Shape.Textures; 2055 Primitive.TextureEntry tex = part.Shape.Textures;
1848 Color4 texcolor; 2056 Color4 texcolor;
1849 LSL_Vector rgb = new LSL_Vector(); 2057 LSL_Vector rgb = new LSL_Vector();
2058 int nsides = GetNumberOfSides(part);
2059
1850 if (face == ScriptBaseClass.ALL_SIDES) 2060 if (face == ScriptBaseClass.ALL_SIDES)
1851 { 2061 {
1852 int i; 2062 int i;
1853 2063 for (i = 0; i < nsides; i++)
1854 for (i = 0 ; i < GetNumberOfSides(part); i++)
1855 { 2064 {
1856 texcolor = tex.GetFace((uint)i).RGBA; 2065 texcolor = tex.GetFace((uint)i).RGBA;
1857 rgb.x += texcolor.R; 2066 rgb.x += texcolor.R;
@@ -1859,14 +2068,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1859 rgb.z += texcolor.B; 2068 rgb.z += texcolor.B;
1860 } 2069 }
1861 2070
1862 rgb.x /= (float)GetNumberOfSides(part); 2071 float invnsides = 1.0f / (float)nsides;
1863 rgb.y /= (float)GetNumberOfSides(part); 2072
1864 rgb.z /= (float)GetNumberOfSides(part); 2073 rgb.x *= invnsides;
2074 rgb.y *= invnsides;
2075 rgb.z *= invnsides;
1865 2076
1866 return rgb; 2077 return rgb;
1867 } 2078 }
1868 2079 if (face >= 0 && face < nsides)
1869 if (face >= 0 && face < GetNumberOfSides(part))
1870 { 2080 {
1871 texcolor = tex.GetFace((uint)face).RGBA; 2081 texcolor = tex.GetFace((uint)face).RGBA;
1872 rgb.x = texcolor.R; 2082 rgb.x = texcolor.R;
@@ -1893,15 +2103,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1893 m_host.AddScriptLPS(1); 2103 m_host.AddScriptLPS(1);
1894 2104
1895 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2105 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1896 2106 if (parts.Count > 0)
1897 foreach (SceneObjectPart part in parts) 2107 {
1898 SetTexture(part, texture, face); 2108 try
1899 2109 {
2110 foreach (SceneObjectPart part in parts)
2111 SetTexture(part, texture, face);
2112 }
2113 finally
2114 {
2115 }
2116 }
1900 ScriptSleep(200); 2117 ScriptSleep(200);
1901 } 2118 }
1902 2119
1903 protected void SetTexture(SceneObjectPart part, string texture, int face) 2120 protected void SetTexture(SceneObjectPart part, string texture, int face)
1904 { 2121 {
2122 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2123 return;
2124
1905 UUID textureID = new UUID(); 2125 UUID textureID = new UUID();
1906 2126
1907 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 2127 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
@@ -1946,6 +2166,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1946 2166
1947 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2167 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1948 { 2168 {
2169 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2170 return;
2171
1949 Primitive.TextureEntry tex = part.Shape.Textures; 2172 Primitive.TextureEntry tex = part.Shape.Textures;
1950 if (face >= 0 && face < GetNumberOfSides(part)) 2173 if (face >= 0 && face < GetNumberOfSides(part))
1951 { 2174 {
@@ -1982,6 +2205,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1982 2205
1983 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2206 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1984 { 2207 {
2208 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2209 return;
2210
1985 Primitive.TextureEntry tex = part.Shape.Textures; 2211 Primitive.TextureEntry tex = part.Shape.Textures;
1986 if (face >= 0 && face < GetNumberOfSides(part)) 2212 if (face >= 0 && face < GetNumberOfSides(part))
1987 { 2213 {
@@ -2018,6 +2244,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2018 2244
2019 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2245 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
2020 { 2246 {
2247 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2248 return;
2249
2021 Primitive.TextureEntry tex = part.Shape.Textures; 2250 Primitive.TextureEntry tex = part.Shape.Textures;
2022 if (face >= 0 && face < GetNumberOfSides(part)) 2251 if (face >= 0 && face < GetNumberOfSides(part))
2023 { 2252 {
@@ -2159,7 +2388,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2159 return end; 2388 return end;
2160 } 2389 }
2161 2390
2162 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2391 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2163 { 2392 {
2164 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2393 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2165 return fromPos; 2394 return fromPos;
@@ -2175,9 +2404,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2175 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2404 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2176 targetPos.z = ground; 2405 targetPos.z = ground;
2177 } 2406 }
2178 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2407 if (adjust)
2408 return SetPosAdjust(fromPos, targetPos);
2179 2409
2180 return real_vec; 2410 return targetPos;
2181 } 2411 }
2182 2412
2183 /// <summary> 2413 /// <summary>
@@ -2188,27 +2418,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2188 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2418 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2189 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2419 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2190 { 2420 {
2191 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2421 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2422 return;
2423
2192 LSL_Vector currentPos = GetPartLocalPos(part); 2424 LSL_Vector currentPos = GetPartLocalPos(part);
2425 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2193 2426
2194 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2195 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2196 2427
2197 if (part.ParentGroup.RootPart == part) 2428 if (part.ParentGroup.RootPart == part)
2198 { 2429 {
2199 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2200 targetPos.z = ground;
2201 SceneObjectGroup parent = part.ParentGroup; 2430 SceneObjectGroup parent = part.ParentGroup;
2202 parent.UpdateGroupPosition(!adjust ? targetPos : 2431 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2203 SetPosAdjust(currentPos, targetPos)); 2432 return;
2433 Util.FireAndForget(delegate(object x) {
2434 parent.UpdateGroupPosition((Vector3)toPos);
2435 });
2204 } 2436 }
2205 else 2437 else
2206 { 2438 {
2207 part.OffsetPosition = !adjust ? targetPos : 2439 part.OffsetPosition = (Vector3)toPos;
2208 SetPosAdjust(currentPos, targetPos); 2440// SceneObjectGroup parent = part.ParentGroup;
2209 SceneObjectGroup parent = part.ParentGroup; 2441// parent.HasGroupChanged = true;
2210 parent.HasGroupChanged = true; 2442// parent.ScheduleGroupForTerseUpdate();
2211 parent.ScheduleGroupForTerseUpdate(); 2443 part.ScheduleTerseUpdate();
2212 } 2444 }
2213 } 2445 }
2214 2446
@@ -2237,13 +2469,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2237 else 2469 else
2238 { 2470 {
2239 if (part.ParentGroup.IsAttachment) 2471 if (part.ParentGroup.IsAttachment)
2240 {
2241 pos = part.AttachedPos; 2472 pos = part.AttachedPos;
2242 }
2243 else 2473 else
2244 {
2245 pos = part.AbsolutePosition; 2474 pos = part.AbsolutePosition;
2246 }
2247 } 2475 }
2248 2476
2249// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2477// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2255,8 +2483,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2255 { 2483 {
2256 m_host.AddScriptLPS(1); 2484 m_host.AddScriptLPS(1);
2257 2485
2486
2487 // 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
2488 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2489 // 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.
2490 // RootPart != null should shortcircuit
2491
2258 // try to let this work as in SL... 2492 // try to let this work as in SL...
2259 if (m_host.ParentID == 0) 2493 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2260 { 2494 {
2261 // special case: If we are root, rotate complete SOG to new rotation 2495 // special case: If we are root, rotate complete SOG to new rotation
2262 SetRot(m_host, rot); 2496 SetRot(m_host, rot);
@@ -2283,25 +2517,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2283 2517
2284 protected void SetRot(SceneObjectPart part, Quaternion rot) 2518 protected void SetRot(SceneObjectPart part, Quaternion rot)
2285 { 2519 {
2286 part.UpdateRotation(rot); 2520 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2287 // Update rotation does not move the object in the physics scene if it's a linkset. 2521 return;
2288 2522
2289//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2523 bool isroot = (part == part.ParentGroup.RootPart);
2290// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2524 bool isphys;
2291 2525
2292 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2293 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2294 // It's perfectly okay when the object is not an active physical body though.
2295 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2296 // but only if the object is not physial and active. This is important for rotating doors.
2297 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2298 // scene
2299 PhysicsActor pa = part.PhysActor; 2526 PhysicsActor pa = part.PhysActor;
2300 2527
2301 if (pa != null && !pa.IsPhysical) 2528 // keep using physactor ideia of isphysical
2529 // it should be SOP ideia of that
2530 // not much of a issue with ubitODE
2531 if (pa != null && pa.IsPhysical)
2532 isphys = true;
2533 else
2534 isphys = false;
2535
2536 // SL doesn't let scripts rotate root of physical linksets
2537 if (isroot && isphys)
2538 return;
2539
2540 part.UpdateRotation(rot);
2541
2542 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2543 // so do a nasty update of parts positions if is a root part rotation
2544 if (isroot && pa != null) // with if above implies non physical root part
2302 { 2545 {
2303 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2546 part.ParentGroup.ResetChildPrimPhysicsPositions();
2304 } 2547 }
2548 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2549 {
2550 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2551 if (sittingavas.Count > 0)
2552 {
2553 foreach (ScenePresence av in sittingavas)
2554 {
2555 if (isroot || part.LocalId == av.ParentID)
2556 av.SendTerseUpdateToAllClients();
2557 }
2558 }
2559 }
2305 } 2560 }
2306 2561
2307 /// <summary> 2562 /// <summary>
@@ -2318,6 +2573,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2318 2573
2319 m_host.AddScriptLPS(1); 2574 m_host.AddScriptLPS(1);
2320 Quaternion q = m_host.GetWorldRotation(); 2575 Quaternion q = m_host.GetWorldRotation();
2576
2577 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2578 {
2579 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2580 if (avatar != null)
2581 {
2582 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2583 q = avatar.CameraRotation * q; // Mouselook
2584 else
2585 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2586 }
2587 }
2588
2321 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2589 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2322 } 2590 }
2323 2591
@@ -2345,14 +2613,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2345 return new LSL_Rotation(q); 2613 return new LSL_Rotation(q);
2346 } 2614 }
2347 2615
2348 return new LSL_Rotation(part.GetWorldRotation()); 2616 q = part.GetWorldRotation();
2617 if (part.ParentGroup.AttachmentPoint != 0)
2618 {
2619 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2620 if (avatar != null)
2621 {
2622 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2623 q = avatar.CameraRotation * q; // Mouselook
2624 else
2625 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2626 }
2627 }
2628
2629 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2349 } 2630 }
2350 2631
2351 public LSL_Rotation llGetLocalRot() 2632 public LSL_Rotation llGetLocalRot()
2352 { 2633 {
2353 m_host.AddScriptLPS(1); 2634 return GetPartLocalRot(m_host);
2635 }
2354 2636
2355 return new LSL_Rotation(m_host.RotationOffset); 2637 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2638 {
2639 m_host.AddScriptLPS(1);
2640 Quaternion rot = part.RotationOffset;
2641 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2356 } 2642 }
2357 2643
2358 public void llSetForce(LSL_Vector force, int local) 2644 public void llSetForce(LSL_Vector force, int local)
@@ -2432,16 +2718,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2432 m_host.ApplyImpulse(v, local != 0); 2718 m_host.ApplyImpulse(v, local != 0);
2433 } 2719 }
2434 2720
2721
2435 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2722 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2436 { 2723 {
2437 m_host.AddScriptLPS(1); 2724 m_host.AddScriptLPS(1);
2438 m_host.ApplyAngularImpulse(force, local != 0); 2725 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2439 } 2726 }
2440 2727
2441 public void llSetTorque(LSL_Vector torque, int local) 2728 public void llSetTorque(LSL_Vector torque, int local)
2442 { 2729 {
2443 m_host.AddScriptLPS(1); 2730 m_host.AddScriptLPS(1);
2444 m_host.SetAngularImpulse(torque, local != 0); 2731 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2445 } 2732 }
2446 2733
2447 public LSL_Vector llGetTorque() 2734 public LSL_Vector llGetTorque()
@@ -2458,20 +2745,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2458 llSetTorque(torque, local); 2745 llSetTorque(torque, local);
2459 } 2746 }
2460 2747
2748 public void llSetVelocity(LSL_Vector vel, int local)
2749 {
2750 m_host.AddScriptLPS(1);
2751 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2752 }
2753
2461 public LSL_Vector llGetVel() 2754 public LSL_Vector llGetVel()
2462 { 2755 {
2463 m_host.AddScriptLPS(1); 2756 m_host.AddScriptLPS(1);
2464 2757
2465 Vector3 vel; 2758 Vector3 vel = Vector3.Zero;
2466 2759
2467 if (m_host.ParentGroup.IsAttachment) 2760 if (m_host.ParentGroup.IsAttachment)
2468 { 2761 {
2469 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2762 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2470 vel = avatar.Velocity; 2763 if (avatar != null)
2764 vel = avatar.Velocity;
2471 } 2765 }
2472 else 2766 else
2473 { 2767 {
2474 vel = m_host.Velocity; 2768 vel = m_host.ParentGroup.RootPart.Velocity;
2475 } 2769 }
2476 2770
2477 return new LSL_Vector(vel); 2771 return new LSL_Vector(vel);
@@ -2484,11 +2778,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2484 return new LSL_Vector(m_host.Acceleration); 2778 return new LSL_Vector(m_host.Acceleration);
2485 } 2779 }
2486 2780
2487 public LSL_Vector llGetOmega() 2781 public void llSetAngularVelocity(LSL_Vector avel, int local)
2488 { 2782 {
2489 m_host.AddScriptLPS(1); 2783 m_host.AddScriptLPS(1);
2784 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2785 }
2490 2786
2491 return new LSL_Vector(m_host.AngularVelocity); 2787 public LSL_Vector llGetOmega()
2788 {
2789 m_host.AddScriptLPS(1);
2790 Vector3 avel = m_host.AngularVelocity;
2791 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2492 } 2792 }
2493 2793
2494 public LSL_Float llGetTimeOfDay() 2794 public LSL_Float llGetTimeOfDay()
@@ -2849,7 +3149,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2849 return src.ToLower(); 3149 return src.ToLower();
2850 } 3150 }
2851 3151
2852 public void llGiveMoney(string destination, int amount) 3152 public LSL_Integer llGiveMoney(string destination, int amount)
2853 { 3153 {
2854 Util.FireAndForget(x => 3154 Util.FireAndForget(x =>
2855 { 3155 {
@@ -2881,8 +3181,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2881 } 3181 }
2882 3182
2883 money.ObjectGiveMoney( 3183 money.ObjectGiveMoney(
2884 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3184 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2885 }); 3185 });
3186
3187 return 0;
2886 } 3188 }
2887 3189
2888 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3190 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -2961,13 +3263,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2961 new_group.RootPart.UUID.ToString()) }, 3263 new_group.RootPart.UUID.ToString()) },
2962 new DetectParams[0])); 3264 new DetectParams[0]));
2963 3265
2964 float groupmass = new_group.GetMass(); 3266 // do recoil
3267 SceneObjectGroup hostgrp = m_host.ParentGroup;
3268 if (hostgrp == null)
3269 return;
3270
3271 if (hostgrp.IsAttachment) // don't recoil avatars
3272 return;
2965 3273
2966 PhysicsActor pa = new_group.RootPart.PhysActor; 3274 PhysicsActor pa = new_group.RootPart.PhysActor;
2967 3275
2968 //Recoil. 3276 //Recoil.
2969 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3277 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2970 { 3278 {
3279 float groupmass = new_group.GetMass();
2971 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3280 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2972 if (recoil != Vector3.Zero) 3281 if (recoil != Vector3.Zero)
2973 { 3282 {
@@ -2975,6 +3284,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2975 } 3284 }
2976 } 3285 }
2977 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3286 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3287 return;
3288
2978 }); 3289 });
2979 3290
2980 //ScriptSleep((int)((groupmass * velmag) / 10)); 3291 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2989,35 +3300,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2989 public void llLookAt(LSL_Vector target, double strength, double damping) 3300 public void llLookAt(LSL_Vector target, double strength, double damping)
2990 { 3301 {
2991 m_host.AddScriptLPS(1); 3302 m_host.AddScriptLPS(1);
2992 // Determine where we are looking from
2993 LSL_Vector from = llGetPos();
2994
2995 // Work out the normalised vector from the source to the target
2996 LSL_Vector delta = llVecNorm(target - from);
2997 LSL_Vector angle = new LSL_Vector(0,0,0);
2998 3303
2999 // Calculate the yaw 3304 // Get the normalized vector to the target
3000 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3305 LSL_Vector d1 = llVecNorm(target - llGetPos());
3001 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO;
3002 3306
3003 // Calculate pitch 3307 // Get the bearing (yaw)
3004 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3308 LSL_Vector a1 = new LSL_Vector(0,0,0);
3309 a1.z = llAtan2(d1.y, d1.x);
3005 3310
3006 // we need to convert from a vector describing 3311 // Get the elevation (pitch)
3007 // the angles of rotation in radians into rotation value 3312 LSL_Vector a2 = new LSL_Vector(0,0,0);
3008 LSL_Rotation rot = llEuler2Rot(angle); 3313 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
3009 3314
3010 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3315 LSL_Rotation r1 = llEuler2Rot(a1);
3011 // set the rotation of the object, copy that behavior 3316 LSL_Rotation r2 = llEuler2Rot(a2);
3012 PhysicsActor pa = m_host.PhysActor; 3317 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
3013 3318
3014 if (strength == 0 || pa == null || !pa.IsPhysical) 3319 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
3015 { 3320 {
3016 llSetRot(rot); 3321 // Do nothing if either value is 0 (this has been checked in SL)
3322 if (strength <= 0.0 || damping <= 0.0)
3323 return;
3324
3325 llSetRot(r3 * r2 * r1);
3017 } 3326 }
3018 else 3327 else
3019 { 3328 {
3020 m_host.StartLookAt(rot, (float)strength, (float)damping); 3329 if (strength == 0)
3330 {
3331 llSetRot(r3 * r2 * r1);
3332 return;
3333 }
3334
3335 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
3021 } 3336 }
3022 } 3337 }
3023 3338
@@ -3064,17 +3379,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3064 } 3379 }
3065 else 3380 else
3066 { 3381 {
3067 if (m_host.IsRoot) 3382 // new SL always returns object mass
3068 { 3383// if (m_host.IsRoot)
3384// {
3069 return m_host.ParentGroup.GetMass(); 3385 return m_host.ParentGroup.GetMass();
3070 } 3386// }
3071 else 3387// else
3072 { 3388// {
3073 return m_host.GetMass(); 3389// return m_host.GetMass();
3074 } 3390// }
3075 } 3391 }
3076 } 3392 }
3077 3393
3394
3395 public LSL_Float llGetMassMKS()
3396 {
3397 return 100f * llGetMass();
3398 }
3399
3078 public void llCollisionFilter(string name, string id, int accept) 3400 public void llCollisionFilter(string name, string id, int accept)
3079 { 3401 {
3080 m_host.AddScriptLPS(1); 3402 m_host.AddScriptLPS(1);
@@ -3122,8 +3444,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3122 { 3444 {
3123 // Unregister controls from Presence 3445 // Unregister controls from Presence
3124 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3446 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3125 // Remove Take Control permission.
3126 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3127 } 3447 }
3128 } 3448 }
3129 } 3449 }
@@ -3151,7 +3471,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3151 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3471 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3152 3472
3153 if (attachmentsModule != null) 3473 if (attachmentsModule != null)
3154 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true); 3474 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3155 else 3475 else
3156 return false; 3476 return false;
3157 } 3477 }
@@ -3181,9 +3501,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3181 { 3501 {
3182 m_host.AddScriptLPS(1); 3502 m_host.AddScriptLPS(1);
3183 3503
3184// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3185// return;
3186
3187 if (m_item.PermsGranter != m_host.OwnerID) 3504 if (m_item.PermsGranter != m_host.OwnerID)
3188 return; 3505 return;
3189 3506
@@ -3226,6 +3543,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3226 3543
3227 public void llInstantMessage(string user, string message) 3544 public void llInstantMessage(string user, string message)
3228 { 3545 {
3546 UUID result;
3547 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3548 {
3549 ShoutError("An invalid key was passed to llInstantMessage");
3550 ScriptSleep(2000);
3551 return;
3552 }
3553
3554
3229 m_host.AddScriptLPS(1); 3555 m_host.AddScriptLPS(1);
3230 3556
3231 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3557 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3240,14 +3566,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3240 UUID friendTransactionID = UUID.Random(); 3566 UUID friendTransactionID = UUID.Random();
3241 3567
3242 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3568 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3243 3569
3244 GridInstantMessage msg = new GridInstantMessage(); 3570 GridInstantMessage msg = new GridInstantMessage();
3245 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3571 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3246 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3572 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3247 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3573 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3248// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3574// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3249// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3575// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3250 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3576// DateTime dt = DateTime.UtcNow;
3577//
3578// // Ticks from UtcNow, but make it look like local. Evil, huh?
3579// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3580//
3581// try
3582// {
3583// // Convert that to the PST timezone
3584// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3585// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3586// }
3587// catch
3588// {
3589// // No logging here, as it could be VERY spammy
3590// }
3591//
3592// // And make it look local again to fool the unix time util
3593// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3594
3595 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3596
3251 //if (client != null) 3597 //if (client != null)
3252 //{ 3598 //{
3253 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3599 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3261,10 +3607,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3261 msg.message = message.Substring(0, 1024); 3607 msg.message = message.Substring(0, 1024);
3262 else 3608 else
3263 msg.message = message; 3609 msg.message = message;
3264 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3610 msg.dialog = (byte)19; // MessageFromObject
3265 msg.fromGroup = false;// fromGroup; 3611 msg.fromGroup = false;// fromGroup;
3266 msg.offline = (byte)0; //offline; 3612 msg.offline = (byte)0; //offline;
3267 msg.ParentEstateID = 0; //ParentEstateID; 3613 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3268 msg.Position = new Vector3(m_host.AbsolutePosition); 3614 msg.Position = new Vector3(m_host.AbsolutePosition);
3269 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3615 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3270 3616
@@ -3296,7 +3642,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3296 } 3642 }
3297 3643
3298 emailModule.SendEmail(m_host.UUID, address, subject, message); 3644 emailModule.SendEmail(m_host.UUID, address, subject, message);
3299 llSleep(EMAIL_PAUSE_TIME); 3645 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3300 } 3646 }
3301 3647
3302 public void llGetNextEmail(string address, string subject) 3648 public void llGetNextEmail(string address, string subject)
@@ -3542,7 +3888,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3542 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3888 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3543 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3889 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3544 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3890 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3891 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3545 ScriptBaseClass.PERMISSION_ATTACH; 3892 ScriptBaseClass.PERMISSION_ATTACH;
3893
3546 } 3894 }
3547 else 3895 else
3548 { 3896 {
@@ -3559,15 +3907,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3559 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3907 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3560 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3908 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3561 } 3909 }
3910 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3911 {
3912 implicitPerms = perm;
3913 }
3562 } 3914 }
3563 3915
3564 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3916 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3565 { 3917 {
3566 lock (m_host.TaskInventory) 3918 m_host.TaskInventory.LockItemsForWrite(true);
3567 { 3919 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3568 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3920 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3569 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3921 m_host.TaskInventory.LockItemsForWrite(false);
3570 }
3571 3922
3572 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3923 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3573 "run_time_permissions", new Object[] { 3924 "run_time_permissions", new Object[] {
@@ -3610,11 +3961,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3610 3961
3611 if (!m_waitingForScriptAnswer) 3962 if (!m_waitingForScriptAnswer)
3612 { 3963 {
3613 lock (m_host.TaskInventory) 3964 m_host.TaskInventory.LockItemsForWrite(true);
3614 { 3965 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3615 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3966 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3616 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3967 m_host.TaskInventory.LockItemsForWrite(false);
3617 }
3618 3968
3619 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3969 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3620 m_waitingForScriptAnswer=true; 3970 m_waitingForScriptAnswer=true;
@@ -3643,14 +3993,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3643 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3993 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3644 llReleaseControls(); 3994 llReleaseControls();
3645 3995
3646 lock (m_host.TaskInventory) 3996 m_host.TaskInventory.LockItemsForWrite(true);
3647 { 3997 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3648 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3998 m_host.TaskInventory.LockItemsForWrite(false);
3649 } 3999
3650 4000 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3651 m_ScriptEngine.PostScriptEvent( 4001 "run_time_permissions", new Object[] {
3652 m_item.ItemID, 4002 new LSL_Integer(answer) },
3653 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 4003 new DetectParams[0]));
3654 } 4004 }
3655 4005
3656 public LSL_String llGetPermissionsKey() 4006 public LSL_String llGetPermissionsKey()
@@ -3689,14 +4039,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3689 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 4039 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3690 { 4040 {
3691 List<SceneObjectPart> parts = GetLinkParts(linknumber); 4041 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3692 4042 if (parts.Count > 0)
3693 foreach (SceneObjectPart part in parts) 4043 {
3694 part.SetFaceColorAlpha(face, color, null); 4044 try
4045 {
4046 foreach (SceneObjectPart part in parts)
4047 part.SetFaceColorAlpha(face, color, null);
4048 }
4049 finally
4050 {
4051 }
4052 }
3695 } 4053 }
3696 4054
3697 public void llCreateLink(string target, int parent) 4055 public void llCreateLink(string target, int parent)
3698 { 4056 {
3699 m_host.AddScriptLPS(1); 4057 m_host.AddScriptLPS(1);
4058
3700 UUID targetID; 4059 UUID targetID;
3701 4060
3702 if (!UUID.TryParse(target, out targetID)) 4061 if (!UUID.TryParse(target, out targetID))
@@ -3802,10 +4161,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3802 // Restructuring Multiple Prims. 4161 // Restructuring Multiple Prims.
3803 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4162 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3804 parts.Remove(parentPrim.RootPart); 4163 parts.Remove(parentPrim.RootPart);
3805 foreach (SceneObjectPart part in parts) 4164 if (parts.Count > 0)
3806 { 4165 {
3807 parentPrim.DelinkFromGroup(part.LocalId, true); 4166 try
4167 {
4168 foreach (SceneObjectPart part in parts)
4169 {
4170 parentPrim.DelinkFromGroup(part.LocalId, true);
4171 }
4172 }
4173 finally
4174 {
4175 }
3808 } 4176 }
4177
3809 parentPrim.HasGroupChanged = true; 4178 parentPrim.HasGroupChanged = true;
3810 parentPrim.ScheduleGroupForFullUpdate(); 4179 parentPrim.ScheduleGroupForFullUpdate();
3811 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4180 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3814,12 +4183,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3814 { 4183 {
3815 SceneObjectPart newRoot = parts[0]; 4184 SceneObjectPart newRoot = parts[0];
3816 parts.Remove(newRoot); 4185 parts.Remove(newRoot);
3817 foreach (SceneObjectPart part in parts) 4186
4187 try
3818 { 4188 {
3819 // Required for linking 4189 foreach (SceneObjectPart part in parts)
3820 part.ClearUpdateSchedule(); 4190 {
3821 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4191 part.ClearUpdateSchedule();
4192 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4193 }
3822 } 4194 }
4195 finally
4196 {
4197 }
4198
4199
3823 newRoot.ParentGroup.HasGroupChanged = true; 4200 newRoot.ParentGroup.HasGroupChanged = true;
3824 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4201 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3825 } 4202 }
@@ -3839,6 +4216,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3839 public void llBreakAllLinks() 4216 public void llBreakAllLinks()
3840 { 4217 {
3841 m_host.AddScriptLPS(1); 4218 m_host.AddScriptLPS(1);
4219
4220 TaskInventoryItem item = m_item;
4221
4222 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4223 && !m_automaticLinkPermission)
4224 {
4225 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4226 return;
4227 }
4228
3842 SceneObjectGroup parentPrim = m_host.ParentGroup; 4229 SceneObjectGroup parentPrim = m_host.ParentGroup;
3843 if (parentPrim.AttachmentPoint != 0) 4230 if (parentPrim.AttachmentPoint != 0)
3844 return; // Fail silently if attached 4231 return; // Fail silently if attached
@@ -3858,13 +4245,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3858 public LSL_String llGetLinkKey(int linknum) 4245 public LSL_String llGetLinkKey(int linknum)
3859 { 4246 {
3860 m_host.AddScriptLPS(1); 4247 m_host.AddScriptLPS(1);
4248 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
4249 if (part != null)
4250 {
4251 return part.UUID.ToString();
4252 }
4253 else
4254 {
4255 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4256 {
4257 linknum -= (m_host.ParentGroup.PrimCount) + 1;
3861 4258
3862 ISceneEntity entity = GetLinkEntity(linknum); 4259 if (linknum < 0)
4260 return UUID.Zero.ToString();
3863 4261
3864 if (entity != null) 4262 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
3865 return entity.UUID.ToString(); 4263 if (avatars.Count > linknum)
3866 else 4264 {
3867 return ScriptBaseClass.NULL_KEY; 4265 return avatars[linknum].UUID.ToString();
4266 }
4267 }
4268 return UUID.Zero.ToString();
4269 }
3868 } 4270 }
3869 4271
3870 /// <summary> 4272 /// <summary>
@@ -3923,17 +4325,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3923 m_host.AddScriptLPS(1); 4325 m_host.AddScriptLPS(1);
3924 int count = 0; 4326 int count = 0;
3925 4327
3926 lock (m_host.TaskInventory) 4328 m_host.TaskInventory.LockItemsForRead(true);
4329 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3927 { 4330 {
3928 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4331 if (inv.Value.Type == type || type == -1)
3929 { 4332 {
3930 if (inv.Value.Type == type || type == -1) 4333 count = count + 1;
3931 {
3932 count = count + 1;
3933 }
3934 } 4334 }
3935 } 4335 }
3936 4336
4337 m_host.TaskInventory.LockItemsForRead(false);
3937 return count; 4338 return count;
3938 } 4339 }
3939 4340
@@ -3942,16 +4343,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3942 m_host.AddScriptLPS(1); 4343 m_host.AddScriptLPS(1);
3943 ArrayList keys = new ArrayList(); 4344 ArrayList keys = new ArrayList();
3944 4345
3945 lock (m_host.TaskInventory) 4346 m_host.TaskInventory.LockItemsForRead(true);
4347 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3946 { 4348 {
3947 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4349 if (inv.Value.Type == type || type == -1)
3948 { 4350 {
3949 if (inv.Value.Type == type || type == -1) 4351 keys.Add(inv.Value.Name);
3950 {
3951 keys.Add(inv.Value.Name);
3952 }
3953 } 4352 }
3954 } 4353 }
4354 m_host.TaskInventory.LockItemsForRead(false);
3955 4355
3956 if (keys.Count == 0) 4356 if (keys.Count == 0)
3957 { 4357 {
@@ -3989,7 +4389,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3989 if (item == null) 4389 if (item == null)
3990 { 4390 {
3991 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4391 llSay(0, String.Format("Could not find object '{0}'", inventory));
3992 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4392 return;
4393// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3993 } 4394 }
3994 4395
3995 UUID objId = item.ItemID; 4396 UUID objId = item.ItemID;
@@ -4017,33 +4418,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4017 return; 4418 return;
4018 } 4419 }
4019 } 4420 }
4421
4020 // destination is an avatar 4422 // destination is an avatar
4021 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4423 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4022 4424
4023 if (agentItem == null) 4425 if (agentItem == null)
4024 return; 4426 return;
4025 4427
4026 if (m_TransferModule != null) 4428 byte[] bucket = new byte[1];
4027 { 4429 bucket[0] = (byte)item.Type;
4028 byte[] bucket = new byte[1]; 4430 //byte[] objBytes = agentItem.ID.GetBytes();
4029 bucket[0] = (byte)item.Type; 4431 //Array.Copy(objBytes, 0, bucket, 1, 16);
4030 4432
4031 GridInstantMessage msg = new GridInstantMessage(World, 4433 GridInstantMessage msg = new GridInstantMessage(World,
4032 m_host.OwnerID, m_host.Name, destId, 4434 m_host.OwnerID, m_host.Name, destId,
4033 (byte)InstantMessageDialog.TaskInventoryOffered, 4435 (byte)InstantMessageDialog.TaskInventoryOffered,
4034 false, item.Name+". "+m_host.Name+" is located at "+ 4436 false, item.Name+". "+m_host.Name+" is located at "+
4035 World.RegionInfo.RegionName+" "+ 4437 World.RegionInfo.RegionName+" "+
4036 m_host.AbsolutePosition.ToString(), 4438 m_host.AbsolutePosition.ToString(),
4037 agentItem.ID, true, m_host.AbsolutePosition, 4439 agentItem.ID, true, m_host.AbsolutePosition,
4038 bucket, true); 4440 bucket, true);
4039 4441
4040 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4442 ScenePresence sp;
4041 }
4042 4443
4444 if (World.TryGetScenePresence(destId, out sp))
4445 {
4446 sp.ControllingClient.SendInstantMessage(msg);
4447 }
4448 else
4449 {
4450 if (m_TransferModule != null)
4451 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4452 }
4453
4454 //This delay should only occur when giving inventory to avatars.
4043 ScriptSleep(3000); 4455 ScriptSleep(3000);
4044 } 4456 }
4045 } 4457 }
4046 4458
4459 [DebuggerNonUserCode]
4047 public void llRemoveInventory(string name) 4460 public void llRemoveInventory(string name)
4048 { 4461 {
4049 m_host.AddScriptLPS(1); 4462 m_host.AddScriptLPS(1);
@@ -4098,109 +4511,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4098 { 4511 {
4099 m_host.AddScriptLPS(1); 4512 m_host.AddScriptLPS(1);
4100 4513
4101 UUID uuid = (UUID)id; 4514 UUID uuid;
4102 PresenceInfo pinfo = null; 4515 if (UUID.TryParse(id, out uuid))
4103 UserAccount account;
4104
4105 UserInfoCacheEntry ce;
4106 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4107 { 4516 {
4108 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4517 PresenceInfo pinfo = null;
4109 if (account == null) 4518 UserAccount account;
4519
4520 UserInfoCacheEntry ce;
4521 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4110 { 4522 {
4111 m_userInfoCache[uuid] = null; // Cache negative 4523 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4112 return UUID.Zero.ToString(); 4524 if (account == null)
4113 } 4525 {
4526 m_userInfoCache[uuid] = null; // Cache negative
4527 return UUID.Zero.ToString();
4528 }
4114 4529
4115 4530
4116 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4531 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4117 if (pinfos != null && pinfos.Length > 0) 4532 if (pinfos != null && pinfos.Length > 0)
4118 {
4119 foreach (PresenceInfo p in pinfos)
4120 { 4533 {
4121 if (p.RegionID != UUID.Zero) 4534 foreach (PresenceInfo p in pinfos)
4122 { 4535 {
4123 pinfo = p; 4536 if (p.RegionID != UUID.Zero)
4537 {
4538 pinfo = p;
4539 }
4124 } 4540 }
4125 } 4541 }
4126 }
4127 4542
4128 ce = new UserInfoCacheEntry(); 4543 ce = new UserInfoCacheEntry();
4129 ce.time = Util.EnvironmentTickCount(); 4544 ce.time = Util.EnvironmentTickCount();
4130 ce.account = account; 4545 ce.account = account;
4131 ce.pinfo = pinfo; 4546 ce.pinfo = pinfo;
4132 } 4547 m_userInfoCache[uuid] = ce;
4133 else 4548 }
4134 { 4549 else
4135 if (ce == null) 4550 {
4136 return UUID.Zero.ToString(); 4551 if (ce == null)
4552 return UUID.Zero.ToString();
4137 4553
4138 account = ce.account; 4554 account = ce.account;
4139 pinfo = ce.pinfo; 4555 pinfo = ce.pinfo;
4140 } 4556 }
4141 4557
4142 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4558 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4143 {
4144 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4145 if (pinfos != null && pinfos.Length > 0)
4146 { 4559 {
4147 foreach (PresenceInfo p in pinfos) 4560 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4561 if (pinfos != null && pinfos.Length > 0)
4148 { 4562 {
4149 if (p.RegionID != UUID.Zero) 4563 foreach (PresenceInfo p in pinfos)
4150 { 4564 {
4151 pinfo = p; 4565 if (p.RegionID != UUID.Zero)
4566 {
4567 pinfo = p;
4568 }
4152 } 4569 }
4153 } 4570 }
4154 } 4571 else
4155 else 4572 pinfo = null;
4156 pinfo = null;
4157 4573
4158 ce.time = Util.EnvironmentTickCount(); 4574 ce.time = Util.EnvironmentTickCount();
4159 ce.pinfo = pinfo; 4575 ce.pinfo = pinfo;
4160 } 4576 }
4161 4577
4162 string reply = String.Empty; 4578 string reply = String.Empty;
4163 4579
4164 switch (data) 4580 switch (data)
4165 { 4581 {
4166 case 1: // DATA_ONLINE (0|1) 4582 case 1: // DATA_ONLINE (0|1)
4167 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4583 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4168 reply = "1"; 4584 reply = "1";
4169 else 4585 else
4170 reply = "0"; 4586 reply = "0";
4171 break; 4587 break;
4172 case 2: // DATA_NAME (First Last) 4588 case 2: // DATA_NAME (First Last)
4173 reply = account.FirstName + " " + account.LastName; 4589 reply = account.FirstName + " " + account.LastName;
4174 break; 4590 break;
4175 case 3: // DATA_BORN (YYYY-MM-DD) 4591 case 3: // DATA_BORN (YYYY-MM-DD)
4176 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4592 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4177 born = born.AddSeconds(account.Created); 4593 born = born.AddSeconds(account.Created);
4178 reply = born.ToString("yyyy-MM-dd"); 4594 reply = born.ToString("yyyy-MM-dd");
4179 break; 4595 break;
4180 case 4: // DATA_RATING (0,0,0,0,0,0) 4596 case 4: // DATA_RATING (0,0,0,0,0,0)
4181 reply = "0,0,0,0,0,0"; 4597 reply = "0,0,0,0,0,0";
4182 break; 4598 break;
4183 case 7: // DATA_USERLEVEL (integer) 4599 case 8: // DATA_PAYINFO (0|1|2|3)
4184 reply = account.UserLevel.ToString(); 4600 reply = "0";
4185 break; 4601 break;
4186 case 8: // DATA_PAYINFO (0|1|2|3) 4602 default:
4187 reply = "0"; 4603 return UUID.Zero.ToString(); // Raise no event
4188 break; 4604 }
4189 default:
4190 return UUID.Zero.ToString(); // Raise no event
4191 }
4192 4605
4193 UUID rq = UUID.Random(); 4606 UUID rq = UUID.Random();
4194 4607
4195 UUID tid = AsyncCommands. 4608 UUID tid = AsyncCommands.
4196 DataserverPlugin.RegisterRequest(m_host.LocalId, 4609 DataserverPlugin.RegisterRequest(m_host.LocalId,
4197 m_item.ItemID, rq.ToString()); 4610 m_item.ItemID, rq.ToString());
4198 4611
4199 AsyncCommands. 4612 AsyncCommands.
4200 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4613 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4201 4614
4202 ScriptSleep(100); 4615 ScriptSleep(100);
4203 return tid.ToString(); 4616 return tid.ToString();
4617 }
4618 else
4619 {
4620 ShoutError("Invalid UUID passed to llRequestAgentData.");
4621 }
4622 return "";
4204 } 4623 }
4205 4624
4206 public LSL_String llRequestInventoryData(string name) 4625 public LSL_String llRequestInventoryData(string name)
@@ -4257,12 +4676,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4257 if (UUID.TryParse(agent, out agentId)) 4676 if (UUID.TryParse(agent, out agentId))
4258 { 4677 {
4259 ScenePresence presence = World.GetScenePresence(agentId); 4678 ScenePresence presence = World.GetScenePresence(agentId);
4260 if (presence != null) 4679 if (presence != null && presence.PresenceType != PresenceType.Npc)
4261 { 4680 {
4681 // agent must not be a god
4682 if (presence.UserLevel >= 200) return;
4683
4262 // agent must be over the owners land 4684 // agent must be over the owners land
4263 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4685 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4264 { 4686 {
4265 World.TeleportClientHome(agentId, presence.ControllingClient); 4687 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4688 {
4689 // They can't be teleported home for some reason
4690 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4691 if (regionInfo != null)
4692 {
4693 World.RequestTeleportLocation(
4694 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4695 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4696 }
4697 }
4266 } 4698 }
4267 } 4699 }
4268 } 4700 }
@@ -4280,20 +4712,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4280 ScenePresence presence = World.GetScenePresence(agentId); 4712 ScenePresence presence = World.GetScenePresence(agentId);
4281 if (presence != null && presence.PresenceType != PresenceType.Npc) 4713 if (presence != null && presence.PresenceType != PresenceType.Npc)
4282 { 4714 {
4283 // agent must not be a god
4284 if (presence.GodLevel >= 200) return;
4285
4286 if (destination == String.Empty) 4715 if (destination == String.Empty)
4287 destination = World.RegionInfo.RegionName; 4716 destination = World.RegionInfo.RegionName;
4288 4717
4289 // agent must be over the owners land 4718 if (m_item.PermsGranter == agentId)
4290 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4719 {
4720 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4721 {
4722 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4723 }
4724 }
4725
4726 // agent must be wearing the object
4727 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4291 { 4728 {
4292 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4729 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4293 } 4730 }
4294 else // or must be wearing the prim 4731 else
4295 { 4732 {
4296 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4733 // agent must not be a god
4734 if (presence.GodLevel >= 200) return;
4735
4736 // agent must be over the owners land
4737 ILandObject agentLand = World.LandChannel.GetLandObject(presence.AbsolutePosition);
4738 ILandObject objectLand = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
4739 if (m_host.OwnerID == objectLand.LandData.OwnerID && m_host.OwnerID == agentLand.LandData.OwnerID)
4297 { 4740 {
4298 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4741 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4299 } 4742 }
@@ -4307,24 +4750,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4307 m_host.AddScriptLPS(1); 4750 m_host.AddScriptLPS(1);
4308 UUID agentId = new UUID(); 4751 UUID agentId = new UUID();
4309 4752
4310 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y); 4753 ulong regionHandle = Utils.UIntsToLong((uint)(global_coords.x / 256) * 256, (uint)(global_coords.y / 256) * 256);
4311 4754
4312 if (UUID.TryParse(agent, out agentId)) 4755 if (UUID.TryParse(agent, out agentId))
4313 { 4756 {
4757 // This function is owner only!
4758 if (m_host.OwnerID != agentId)
4759 return;
4760
4314 ScenePresence presence = World.GetScenePresence(agentId); 4761 ScenePresence presence = World.GetScenePresence(agentId);
4762
4763 // Can't TP sitting avatars
4764 if (presence.ParentID != 0) // Sitting
4765 return;
4766
4315 if (presence != null && presence.PresenceType != PresenceType.Npc) 4767 if (presence != null && presence.PresenceType != PresenceType.Npc)
4316 { 4768 {
4317 // agent must not be a god 4769 if (m_item.PermsGranter == agentId)
4318 if (presence.GodLevel >= 200) return;
4319
4320 // agent must be over the owners land
4321 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4322 {
4323 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4324 }
4325 else // or must be wearing the prim
4326 { 4770 {
4327 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4771 // If attached using llAttachToAvatarTemp, cowardly refuse
4772 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.ParentGroup.FromItemID == UUID.Zero)
4773 return;
4774
4775 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4328 { 4776 {
4329 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4777 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4330 } 4778 }
@@ -4368,7 +4816,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4368 UUID av = new UUID(); 4816 UUID av = new UUID();
4369 if (!UUID.TryParse(agent,out av)) 4817 if (!UUID.TryParse(agent,out av))
4370 { 4818 {
4371 LSLError("First parameter to llDialog needs to be a key");
4372 return; 4819 return;
4373 } 4820 }
4374 4821
@@ -4401,9 +4848,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4401 { 4848 {
4402 m_host.AddScriptLPS(1); 4849 m_host.AddScriptLPS(1);
4403 4850
4851 if(impact_sound == "")
4852 {
4853 m_host.CollisionSoundVolume = (float)impact_volume;
4854 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4855 m_host.CollisionSoundType = 0;
4856 return;
4857 }
4404 // TODO: Parameter check logic required. 4858 // TODO: Parameter check logic required.
4405 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 4859 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4406 m_host.CollisionSoundVolume = (float)impact_volume; 4860 m_host.CollisionSoundVolume = (float)impact_volume;
4861 m_host.CollisionSoundType = 1;
4407 } 4862 }
4408 4863
4409 public LSL_String llGetAnimation(string id) 4864 public LSL_String llGetAnimation(string id)
@@ -4417,14 +4872,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4417 4872
4418 if (m_host.RegionHandle == presence.RegionHandle) 4873 if (m_host.RegionHandle == presence.RegionHandle)
4419 { 4874 {
4420 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4421
4422 if (presence != null) 4875 if (presence != null)
4423 { 4876 {
4424 AnimationSet currentAnims = presence.Animator.Animations; 4877 if (presence.SitGround)
4425 string currentAnimationState = String.Empty; 4878 return "Sitting on Ground";
4426 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4879 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4427 return currentAnimationState; 4880 return "Sitting";
4881
4882 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4883 string lslMovementAnimation;
4884
4885 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4886 return lslMovementAnimation;
4428 } 4887 }
4429 } 4888 }
4430 4889
@@ -4572,7 +5031,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4572 { 5031 {
4573 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 5032 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4574 float distance_term = distance * distance * distance; // Script Energy 5033 float distance_term = distance * distance * distance; // Script Energy
4575 float pusher_mass = m_host.GetMass(); 5034 // use total object mass and not part
5035 float pusher_mass = m_host.ParentGroup.GetMass();
4576 5036
4577 float PUSH_ATTENUATION_DISTANCE = 17f; 5037 float PUSH_ATTENUATION_DISTANCE = 17f;
4578 float PUSH_ATTENUATION_SCALE = 5f; 5038 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4809,6 +5269,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4809 { 5269 {
4810 return item.AssetID.ToString(); 5270 return item.AssetID.ToString();
4811 } 5271 }
5272 m_host.TaskInventory.LockItemsForRead(false);
4812 5273
4813 return UUID.Zero.ToString(); 5274 return UUID.Zero.ToString();
4814 } 5275 }
@@ -4961,14 +5422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4961 { 5422 {
4962 m_host.AddScriptLPS(1); 5423 m_host.AddScriptLPS(1);
4963 5424
4964 if (src == null) 5425 return src.Length;
4965 {
4966 return 0;
4967 }
4968 else
4969 {
4970 return src.Length;
4971 }
4972 } 5426 }
4973 5427
4974 public LSL_Integer llList2Integer(LSL_List src, int index) 5428 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5039,7 +5493,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5039 else if (src.Data[index] is LSL_Float) 5493 else if (src.Data[index] is LSL_Float)
5040 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5494 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5041 else if (src.Data[index] is LSL_String) 5495 else if (src.Data[index] is LSL_String)
5042 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5496 {
5497 string str = ((LSL_String) src.Data[index]).m_string;
5498 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5499 if (m != Match.Empty)
5500 {
5501 str = m.Value;
5502 double d = 0.0;
5503 if (!Double.TryParse(str, out d))
5504 return 0.0;
5505
5506 return d;
5507 }
5508 return 0.0;
5509 }
5043 return Convert.ToDouble(src.Data[index]); 5510 return Convert.ToDouble(src.Data[index]);
5044 } 5511 }
5045 catch (FormatException) 5512 catch (FormatException)
@@ -5081,7 +5548,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5081 // for completion and should LSL_Key ever be implemented 5548 // for completion and should LSL_Key ever be implemented
5082 // as it's own struct 5549 // as it's own struct
5083 else if (!(src.Data[index] is LSL_String || 5550 else if (!(src.Data[index] is LSL_String ||
5084 src.Data[index] is LSL_Key)) 5551 src.Data[index] is LSL_Key ||
5552 src.Data[index] is String))
5085 { 5553 {
5086 return ""; 5554 return "";
5087 } 5555 }
@@ -5339,7 +5807,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5339 } 5807 }
5340 } 5808 }
5341 } 5809 }
5342 else { 5810 else
5811 {
5343 object[] array = new object[src.Length]; 5812 object[] array = new object[src.Length];
5344 Array.Copy(src.Data, 0, array, 0, src.Length); 5813 Array.Copy(src.Data, 0, array, 0, src.Length);
5345 result = new LSL_List(array); 5814 result = new LSL_List(array);
@@ -5446,7 +5915,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5446 public LSL_Integer llGetRegionAgentCount() 5915 public LSL_Integer llGetRegionAgentCount()
5447 { 5916 {
5448 m_host.AddScriptLPS(1); 5917 m_host.AddScriptLPS(1);
5449 return new LSL_Integer(World.GetRootAgentCount()); 5918
5919 int count = 0;
5920 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5921 count++;
5922 });
5923
5924 return new LSL_Integer(count);
5450 } 5925 }
5451 5926
5452 public LSL_Vector llGetRegionCorner() 5927 public LSL_Vector llGetRegionCorner()
@@ -5687,6 +6162,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5687 flags |= ScriptBaseClass.AGENT_AWAY; 6162 flags |= ScriptBaseClass.AGENT_AWAY;
5688 } 6163 }
5689 6164
6165 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6166 UUID[] anims = agent.Animator.GetAnimationArray();
6167 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6168 {
6169 flags |= ScriptBaseClass.AGENT_BUSY;
6170 }
6171
5690 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6172 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5691 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6173 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5692 { 6174 {
@@ -5734,6 +6216,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5734 flags |= ScriptBaseClass.AGENT_SITTING; 6216 flags |= ScriptBaseClass.AGENT_SITTING;
5735 } 6217 }
5736 6218
6219 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6220 {
6221 flags |= ScriptBaseClass.AGENT_MALE;
6222 }
6223
5737 return flags; 6224 return flags;
5738 } 6225 }
5739 6226
@@ -5879,9 +6366,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5879 6366
5880 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6367 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5881 6368
5882 foreach (SceneObjectPart part in parts) 6369 try
6370 {
6371 foreach (SceneObjectPart part in parts)
6372 {
6373 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6374 }
6375 }
6376 finally
5883 { 6377 {
5884 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5885 } 6378 }
5886 } 6379 }
5887 6380
@@ -5935,13 +6428,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5935 6428
5936 if (m_host.OwnerID == land.LandData.OwnerID) 6429 if (m_host.OwnerID == land.LandData.OwnerID)
5937 { 6430 {
5938 World.TeleportClientHome(agentID, presence.ControllingClient); 6431 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6432 presence.TeleportWithMomentum(p, null);
6433 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5939 } 6434 }
5940 } 6435 }
5941 } 6436 }
5942 ScriptSleep(5000); 6437 ScriptSleep(5000);
5943 } 6438 }
5944 6439
6440 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6441 {
6442 return ParseString2List(str, separators, in_spacers, false);
6443 }
6444
5945 public LSL_Integer llOverMyLand(string id) 6445 public LSL_Integer llOverMyLand(string id)
5946 { 6446 {
5947 m_host.AddScriptLPS(1); 6447 m_host.AddScriptLPS(1);
@@ -5994,26 +6494,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5994 } 6494 }
5995 else 6495 else
5996 { 6496 {
5997 agentSize = GetAgentSize(avatar); 6497// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6498 Vector3 s = avatar.Appearance.AvatarSize;
6499 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5998 } 6500 }
5999
6000 return agentSize; 6501 return agentSize;
6001 } 6502 }
6002 6503
6003 public LSL_Integer llSameGroup(string agent) 6504 public LSL_Integer llSameGroup(string id)
6004 { 6505 {
6005 m_host.AddScriptLPS(1); 6506 m_host.AddScriptLPS(1);
6006 UUID agentId = new UUID(); 6507 UUID uuid = new UUID();
6007 if (!UUID.TryParse(agent, out agentId)) 6508 if (!UUID.TryParse(id, out uuid))
6008 return new LSL_Integer(0);
6009 ScenePresence presence = World.GetScenePresence(agentId);
6010 if (presence == null || presence.IsChildAgent) // Return flase for child agents
6011 return new LSL_Integer(0); 6509 return new LSL_Integer(0);
6012 IClientAPI client = presence.ControllingClient; 6510
6013 if (m_host.GroupID == client.ActiveGroupId) 6511 // Check if it's a group key
6512 if (uuid == m_host.ParentGroup.RootPart.GroupID)
6014 return new LSL_Integer(1); 6513 return new LSL_Integer(1);
6015 else 6514
6515 // We got passed a UUID.Zero
6516 if (uuid == UUID.Zero)
6517 return new LSL_Integer(0);
6518
6519 // Handle the case where id names an avatar
6520 ScenePresence presence = World.GetScenePresence(uuid);
6521 if (presence != null)
6522 {
6523 if (presence.IsChildAgent)
6524 return new LSL_Integer(0);
6525
6526 IClientAPI client = presence.ControllingClient;
6527 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6528 return new LSL_Integer(1);
6529
6016 return new LSL_Integer(0); 6530 return new LSL_Integer(0);
6531 }
6532
6533 // Handle object case
6534 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6535 if (part != null)
6536 {
6537 // This will handle both deed and non-deed and also the no
6538 // group case
6539 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6540 return new LSL_Integer(1);
6541
6542 return new LSL_Integer(0);
6543 }
6544
6545 return new LSL_Integer(0);
6017 } 6546 }
6018 6547
6019 public void llUnSit(string id) 6548 public void llUnSit(string id)
@@ -6572,6 +7101,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6572 7101
6573 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7102 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6574 { 7103 {
7104 // LSL quaternions can normalize to 0, normal Quaternions can't.
7105 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7106 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7107
6575 part.SitTargetPosition = offset; 7108 part.SitTargetPosition = offset;
6576 part.SitTargetOrientation = rot; 7109 part.SitTargetOrientation = rot;
6577 part.ParentGroup.HasGroupChanged = true; 7110 part.ParentGroup.HasGroupChanged = true;
@@ -6758,30 +7291,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6758 UUID av = new UUID(); 7291 UUID av = new UUID();
6759 if (!UUID.TryParse(avatar,out av)) 7292 if (!UUID.TryParse(avatar,out av))
6760 { 7293 {
6761 LSLError("First parameter to llDialog needs to be a key"); 7294 //LSLError("First parameter to llDialog needs to be a key");
6762 return; 7295 return;
6763 } 7296 }
6764 if (buttons.Length < 1) 7297 if (buttons.Length < 1)
6765 { 7298 {
6766 LSLError("No less than 1 button can be shown"); 7299 buttons.Add("OK");
6767 return;
6768 } 7300 }
6769 if (buttons.Length > 12) 7301 if (buttons.Length > 12)
6770 { 7302 {
6771 LSLError("No more than 12 buttons can be shown"); 7303 ShoutError("button list too long, must be 12 or fewer entries");
6772 return;
6773 } 7304 }
6774 string[] buts = new string[buttons.Length]; 7305 int length = buttons.Length;
6775 for (int i = 0; i < buttons.Length; i++) 7306 if (length > 12)
7307 length = 12;
7308
7309 string[] buts = new string[length];
7310 for (int i = 0; i < length; i++)
6776 { 7311 {
6777 if (buttons.Data[i].ToString() == String.Empty) 7312 if (buttons.Data[i].ToString() == String.Empty)
6778 { 7313 {
6779 LSLError("button label cannot be blank"); 7314 ShoutError("button label cannot be blank");
6780 return; 7315 return;
6781 } 7316 }
6782 if (buttons.Data[i].ToString().Length > 24) 7317 if (buttons.Data[i].ToString().Length > 24)
6783 { 7318 {
6784 LSLError("button label cannot be longer than 24 characters"); 7319 ShoutError("button label cannot be longer than 24 characters");
6785 return; 7320 return;
6786 } 7321 }
6787 buts[i] = buttons.Data[i].ToString(); 7322 buts[i] = buttons.Data[i].ToString();
@@ -6848,9 +7383,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6848 return; 7383 return;
6849 } 7384 }
6850 7385
6851 // the rest of the permission checks are done in RezScript, so check the pin there as well 7386 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6852 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7387 if (dest != null)
7388 {
7389 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7390 {
7391 // the rest of the permission checks are done in RezScript, so check the pin there as well
7392 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6853 7393
7394 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7395 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7396 }
7397 }
6854 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7398 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6855 ScriptSleep(3000); 7399 ScriptSleep(3000);
6856 } 7400 }
@@ -6924,19 +7468,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6924 public LSL_String llMD5String(string src, int nonce) 7468 public LSL_String llMD5String(string src, int nonce)
6925 { 7469 {
6926 m_host.AddScriptLPS(1); 7470 m_host.AddScriptLPS(1);
6927 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7471 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6928 } 7472 }
6929 7473
6930 public LSL_String llSHA1String(string src) 7474 public LSL_String llSHA1String(string src)
6931 { 7475 {
6932 m_host.AddScriptLPS(1); 7476 m_host.AddScriptLPS(1);
6933 return Util.SHA1Hash(src).ToLower(); 7477 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6934 } 7478 }
6935 7479
6936 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7480 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6937 { 7481 {
6938 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7482 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6939 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7483 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7484 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7485 return shapeBlock;
6940 7486
6941 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7487 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6942 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7488 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -7041,6 +7587,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7041 // Prim type box, cylinder and prism. 7587 // Prim type box, cylinder and prism.
7042 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) 7588 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)
7043 { 7589 {
7590 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7591 return;
7592
7044 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7593 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7045 ObjectShapePacket.ObjectDataBlock shapeBlock; 7594 ObjectShapePacket.ObjectDataBlock shapeBlock;
7046 7595
@@ -7094,6 +7643,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7094 // Prim type sphere. 7643 // Prim type sphere.
7095 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7644 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7096 { 7645 {
7646 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7647 return;
7648
7097 ObjectShapePacket.ObjectDataBlock shapeBlock; 7649 ObjectShapePacket.ObjectDataBlock shapeBlock;
7098 7650
7099 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7651 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7135,6 +7687,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7135 // Prim type torus, tube and ring. 7687 // Prim type torus, tube and ring.
7136 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) 7688 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)
7137 { 7689 {
7690 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7691 return;
7692
7138 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7693 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7139 ObjectShapePacket.ObjectDataBlock shapeBlock; 7694 ObjectShapePacket.ObjectDataBlock shapeBlock;
7140 7695
@@ -7270,6 +7825,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7270 // Prim type sculpt. 7825 // Prim type sculpt.
7271 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7826 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7272 { 7827 {
7828 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7829 return;
7830
7273 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7831 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7274 UUID sculptId; 7832 UUID sculptId;
7275 7833
@@ -7292,7 +7850,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7292 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7850 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7293 { 7851 {
7294 // default 7852 // default
7295 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7853 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7296 } 7854 }
7297 7855
7298 part.Shape.SetSculptProperties((byte)type, sculptId); 7856 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7309,15 +7867,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7309 ScriptSleep(200); 7867 ScriptSleep(200);
7310 } 7868 }
7311 7869
7312 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7313 {
7314 m_host.AddScriptLPS(1);
7315
7316 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7317
7318 ScriptSleep(200);
7319 }
7320
7321 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7870 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7322 { 7871 {
7323 m_host.AddScriptLPS(1); 7872 m_host.AddScriptLPS(1);
@@ -7325,169 +7874,135 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7325 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7874 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7326 } 7875 }
7327 7876
7328 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7877 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7329 { 7878 {
7330 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7879 List<object> parts = new List<object>();
7880 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7881 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7882 foreach (SceneObjectPart p in prims)
7883 parts.Add(p);
7884 foreach (ScenePresence p in avatars)
7885 parts.Add(p);
7331 7886
7332 LSL_List remaining = null; 7887 LSL_List remaining = null;
7333 uint rulesParsed = 0; 7888 uint rulesParsed = 0;
7334 7889
7335 foreach (SceneObjectPart part in parts) 7890 if (parts.Count > 0)
7336 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7337
7338 while (remaining != null && remaining.Length > 2)
7339 {
7340 linknumber = remaining.GetLSLIntegerItem(0);
7341 rules = remaining.GetSublist(1, -1);
7342 parts = GetLinkParts(linknumber);
7343
7344 foreach (SceneObjectPart part in parts)
7345 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7346 }
7347 }
7348
7349 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
7350 {
7351 SceneObjectGroup group = m_host.ParentGroup;
7352
7353 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
7354 return;
7355 if (group.IsAttachment)
7356 return;
7357
7358 if (frames.Data.Length > 0) // We are getting a new motion
7359 { 7891 {
7360 if (group.RootPart.KeyframeMotion != null) 7892 foreach (object part in parts)
7361 group.RootPart.KeyframeMotion.Delete();
7362 group.RootPart.KeyframeMotion = null;
7363
7364 int idx = 0;
7365
7366 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
7367 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
7368
7369 while (idx < options.Data.Length)
7370 { 7893 {
7371 int option = (int)options.GetLSLIntegerItem(idx++); 7894 if (part is SceneObjectPart)
7372 int remain = options.Data.Length - idx; 7895 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7896 else
7897 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7898 }
7373 7899
7374 switch (option) 7900 while ((object)remaining != null && remaining.Length > 2)
7901 {
7902 linknumber = remaining.GetLSLIntegerItem(0);
7903 rules = remaining.GetSublist(1, -1);
7904 parts.Clear();
7905 prims = GetLinkParts(linknumber);
7906 avatars = GetLinkAvatars(linknumber);
7907 foreach (SceneObjectPart p in prims)
7908 parts.Add(p);
7909 foreach (ScenePresence p in avatars)
7910 parts.Add(p);
7911
7912 remaining = null;
7913 foreach (object part in parts)
7375 { 7914 {
7376 case ScriptBaseClass.KFM_MODE: 7915 if (part is SceneObjectPart)
7377 if (remain < 1) 7916 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7378 break; 7917 else
7379 int modeval = (int)options.GetLSLIntegerItem(idx++); 7918 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7380 switch(modeval)
7381 {
7382 case ScriptBaseClass.KFM_FORWARD:
7383 mode = KeyframeMotion.PlayMode.Forward;
7384 break;
7385 case ScriptBaseClass.KFM_REVERSE:
7386 mode = KeyframeMotion.PlayMode.Reverse;
7387 break;
7388 case ScriptBaseClass.KFM_LOOP:
7389 mode = KeyframeMotion.PlayMode.Loop;
7390 break;
7391 case ScriptBaseClass.KFM_PING_PONG:
7392 mode = KeyframeMotion.PlayMode.PingPong;
7393 break;
7394 }
7395 break;
7396 case ScriptBaseClass.KFM_DATA:
7397 if (remain < 1)
7398 break;
7399 int dataval = (int)options.GetLSLIntegerItem(idx++);
7400 data = (KeyframeMotion.DataFormat)dataval;
7401 break;
7402 } 7919 }
7403 } 7920 }
7921 }
7922 }
7404 7923
7405 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data); 7924 public LSL_List llGetPhysicsMaterial()
7925 {
7926 LSL_List result = new LSL_List();
7406 7927
7407 idx = 0; 7928 result.Add(new LSL_Float(m_host.GravityModifier));
7929 result.Add(new LSL_Float(m_host.Restitution));
7930 result.Add(new LSL_Float(m_host.Friction));
7931 result.Add(new LSL_Float(m_host.Density));
7408 7932
7409 int elemLength = 2; 7933 return result;
7410 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation)) 7934 }
7411 elemLength = 3;
7412 7935
7413 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>(); 7936 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7414 while (idx < frames.Data.Length) 7937 float material_density, float material_friction,
7415 { 7938 float material_restitution, float material_gravity_modifier)
7416 int remain = frames.Data.Length - idx; 7939 {
7940 ExtraPhysicsData physdata = new ExtraPhysicsData();
7941 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7942 physdata.Density = part.Density;
7943 physdata.Friction = part.Friction;
7944 physdata.Bounce = part.Restitution;
7945 physdata.GravitationModifier = part.GravityModifier;
7417 7946
7418 if (remain < elemLength) 7947 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7419 break; 7948 physdata.Density = material_density;
7949 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7950 physdata.Friction = material_friction;
7951 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7952 physdata.Bounce = material_restitution;
7953 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7954 physdata.GravitationModifier = material_gravity_modifier;
7420 7955
7421 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe(); 7956 part.UpdateExtraPhysics(physdata);
7422 frame.Position = null; 7957 }
7423 frame.Rotation = null;
7424 7958
7425 if ((data & KeyframeMotion.DataFormat.Translation) != 0) 7959 public void llSetPhysicsMaterial(int material_bits,
7426 { 7960 float material_gravity_modifier, float material_restitution,
7427 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++); 7961 float material_friction, float material_density)
7428 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z); 7962 {
7429 } 7963 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7430 if ((data & KeyframeMotion.DataFormat.Rotation) != 0) 7964 }
7431 {
7432 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
7433 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
7434 q.Normalize();
7435 frame.Rotation = q;
7436 }
7437 7965
7438 float tempf = (float)frames.GetLSLFloatItem(idx++); 7966 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7439 frame.TimeMS = (int)(tempf * 1000.0f); 7967 {
7968 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7969 llSetLinkPrimitiveParamsFast(linknumber, rules);
7970 ScriptSleep(200);
7971 }
7440 7972
7441 keyframes.Add(frame); 7973 // vector up using libomv (c&p from sop )
7442 } 7974 // vector up rotated by r
7975 private Vector3 Zrot(Quaternion r)
7976 {
7977 double x, y, z, m;
7443 7978
7444 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray()); 7979 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7445 group.RootPart.KeyframeMotion.Start(); 7980 if (Math.Abs(1.0 - m) > 0.000001)
7446 }
7447 else
7448 { 7981 {
7449 if (group.RootPart.KeyframeMotion == null) 7982 m = 1.0 / Math.Sqrt(m);
7450 return; 7983 r.X *= (float)m;
7451 7984 r.Y *= (float)m;
7452 if (options.Data.Length == 0) 7985 r.Z *= (float)m;
7453 { 7986 r.W *= (float)m;
7454 group.RootPart.KeyframeMotion.Stop(); 7987 }
7455 return;
7456 }
7457
7458 int idx = 0;
7459 7988
7460 while (idx < options.Data.Length) 7989 x = 2 * (r.X * r.Z + r.Y * r.W);
7461 { 7990 y = 2 * (-r.X * r.W + r.Y * r.Z);
7462 int option = (int)options.GetLSLIntegerItem(idx++); 7991 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7463 7992
7464 switch (option) 7993 return new Vector3((float)x, (float)y, (float)z);
7465 {
7466 case ScriptBaseClass.KFM_COMMAND:
7467 int cmd = (int)options.GetLSLIntegerItem(idx++);
7468 switch (cmd)
7469 {
7470 case ScriptBaseClass.KFM_CMD_PLAY:
7471 group.RootPart.KeyframeMotion.Start();
7472 break;
7473 case ScriptBaseClass.KFM_CMD_STOP:
7474 group.RootPart.KeyframeMotion.Stop();
7475 break;
7476 case ScriptBaseClass.KFM_CMD_PAUSE:
7477 group.RootPart.KeyframeMotion.Pause();
7478 break;
7479 }
7480 break;
7481 }
7482 }
7483 }
7484 } 7994 }
7485 7995
7486 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7996 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7487 { 7997 {
7998 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7999 return null;
8000
7488 int idx = 0; 8001 int idx = 0;
7489 int idxStart = 0; 8002 int idxStart = 0;
7490 8003
8004 SceneObjectGroup parentgrp = part.ParentGroup;
8005
7491 bool positionChanged = false; 8006 bool positionChanged = false;
7492 LSL_Vector currentPosition = GetPartLocalPos(part); 8007 LSL_Vector currentPosition = GetPartLocalPos(part);
7493 8008
@@ -7512,8 +8027,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7512 return null; 8027 return null;
7513 8028
7514 v=rules.GetVector3Item(idx++); 8029 v=rules.GetVector3Item(idx++);
8030 if (part.IsRoot && !part.ParentGroup.IsAttachment)
8031 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
8032 else
8033 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7515 positionChanged = true; 8034 positionChanged = true;
7516 currentPosition = GetSetPosTarget(part, v, currentPosition);
7517 8035
7518 break; 8036 break;
7519 case (int)ScriptBaseClass.PRIM_SIZE: 8037 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7530,7 +8048,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7530 8048
7531 LSL_Rotation q = rules.GetQuaternionItem(idx++); 8049 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7532 // try to let this work as in SL... 8050 // try to let this work as in SL...
7533 if (part.ParentID == 0) 8051 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7534 { 8052 {
7535 // special case: If we are root, rotate complete SOG to new rotation 8053 // special case: If we are root, rotate complete SOG to new rotation
7536 SetRot(part, q); 8054 SetRot(part, q);
@@ -7824,6 +8342,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7824 8342
7825 break; 8343 break;
7826 8344
8345 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8346 if (remain < 5)
8347 return null;
8348
8349 int material_bits = rules.GetLSLIntegerItem(idx++);
8350 float material_density = (float)rules.GetLSLFloatItem(idx++);
8351 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8352 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8353 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8354
8355 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8356
8357 break;
8358
7827 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8359 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7828 if (remain < 1) 8360 if (remain < 1)
7829 return null; 8361 return null;
@@ -7903,14 +8435,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7903 if (part.ParentGroup.RootPart == part) 8435 if (part.ParentGroup.RootPart == part)
7904 { 8436 {
7905 SceneObjectGroup parent = part.ParentGroup; 8437 SceneObjectGroup parent = part.ParentGroup;
7906 parent.UpdateGroupPosition(currentPosition); 8438 Util.FireAndForget(delegate(object x) {
8439 parent.UpdateGroupPosition(currentPosition);
8440 });
7907 } 8441 }
7908 else 8442 else
7909 { 8443 {
7910 part.OffsetPosition = currentPosition; 8444 part.OffsetPosition = currentPosition;
7911 SceneObjectGroup parent = part.ParentGroup; 8445// SceneObjectGroup parent = part.ParentGroup;
7912 parent.HasGroupChanged = true; 8446// parent.HasGroupChanged = true;
7913 parent.ScheduleGroupForTerseUpdate(); 8447// parent.ScheduleGroupForTerseUpdate();
8448 part.ScheduleTerseUpdate();
7914 } 8449 }
7915 } 8450 }
7916 } 8451 }
@@ -7948,10 +8483,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7948 8483
7949 public LSL_String llXorBase64Strings(string str1, string str2) 8484 public LSL_String llXorBase64Strings(string str1, string str2)
7950 { 8485 {
7951 m_host.AddScriptLPS(1); 8486 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7952 Deprecated("llXorBase64Strings"); 8487
7953 ScriptSleep(300); 8488 ScriptSleep(300);
7954 return String.Empty; 8489 m_host.AddScriptLPS(1);
8490
8491 if (str1 == String.Empty)
8492 return String.Empty;
8493 if (str2 == String.Empty)
8494 return str1;
8495
8496 int len = str2.Length;
8497 if ((len % 4) != 0) // LL is EVIL!!!!
8498 {
8499 while (str2.EndsWith("="))
8500 str2 = str2.Substring(0, str2.Length - 1);
8501
8502 len = str2.Length;
8503 int mod = len % 4;
8504
8505 if (mod == 1)
8506 str2 = str2.Substring(0, str2.Length - 1);
8507 else if (mod == 2)
8508 str2 += "==";
8509 else if (mod == 3)
8510 str2 += "=";
8511 }
8512
8513 byte[] data1;
8514 byte[] data2;
8515 try
8516 {
8517 data1 = Convert.FromBase64String(str1);
8518 data2 = Convert.FromBase64String(str2);
8519 }
8520 catch (Exception)
8521 {
8522 return new LSL_String(String.Empty);
8523 }
8524
8525 // For cases where the decoded length of s2 is greater
8526 // than the decoded length of s1, simply perform a normal
8527 // decode and XOR
8528 //
8529 if (data2.Length >= data1.Length)
8530 {
8531 for (int pos = 0 ; pos < data1.Length ; pos++ )
8532 data1[pos] ^= data2[pos];
8533
8534 return Convert.ToBase64String(data1);
8535 }
8536
8537 // Remove padding
8538 while (str1.EndsWith("="))
8539 str1 = str1.Substring(0, str1.Length - 1);
8540 while (str2.EndsWith("="))
8541 str2 = str2.Substring(0, str2.Length - 1);
8542
8543 byte[] d1 = new byte[str1.Length];
8544 byte[] d2 = new byte[str2.Length];
8545
8546 for (int i = 0 ; i < str1.Length ; i++)
8547 {
8548 int idx = b64.IndexOf(str1.Substring(i, 1));
8549 if (idx == -1)
8550 idx = 0;
8551 d1[i] = (byte)idx;
8552 }
8553
8554 for (int i = 0 ; i < str2.Length ; i++)
8555 {
8556 int idx = b64.IndexOf(str2.Substring(i, 1));
8557 if (idx == -1)
8558 idx = 0;
8559 d2[i] = (byte)idx;
8560 }
8561
8562 string output = String.Empty;
8563
8564 for (int pos = 0 ; pos < d1.Length ; pos++)
8565 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8566
8567 while (output.Length % 3 > 0)
8568 output += "=";
8569
8570 return output;
7955 } 8571 }
7956 8572
7957 public void llRemoteDataSetRegion() 8573 public void llRemoteDataSetRegion()
@@ -8076,8 +8692,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8076 public LSL_Integer llGetNumberOfPrims() 8692 public LSL_Integer llGetNumberOfPrims()
8077 { 8693 {
8078 m_host.AddScriptLPS(1); 8694 m_host.AddScriptLPS(1);
8079 8695 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
8080 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8696
8697 return m_host.ParentGroup.PrimCount + avatarCount;
8081 } 8698 }
8082 8699
8083 /// <summary> 8700 /// <summary>
@@ -8092,55 +8709,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8092 m_host.AddScriptLPS(1); 8709 m_host.AddScriptLPS(1);
8093 UUID objID = UUID.Zero; 8710 UUID objID = UUID.Zero;
8094 LSL_List result = new LSL_List(); 8711 LSL_List result = new LSL_List();
8712
8713 // If the ID is not valid, return null result
8095 if (!UUID.TryParse(obj, out objID)) 8714 if (!UUID.TryParse(obj, out objID))
8096 { 8715 {
8097 result.Add(new LSL_Vector()); 8716 result.Add(new LSL_Vector());
8098 result.Add(new LSL_Vector()); 8717 result.Add(new LSL_Vector());
8099 return result; 8718 return result;
8100 } 8719 }
8720
8721 // Check if this is an attached prim. If so, replace
8722 // the UUID with the avatar UUID and report it's bounding box
8723 SceneObjectPart part = World.GetSceneObjectPart(objID);
8724 if (part != null && part.ParentGroup.IsAttachment)
8725 objID = part.ParentGroup.AttachedAvatar;
8726
8727 // Find out if this is an avatar ID. If so, return it's box
8101 ScenePresence presence = World.GetScenePresence(objID); 8728 ScenePresence presence = World.GetScenePresence(objID);
8102 if (presence != null) 8729 if (presence != null)
8103 { 8730 {
8104 if (presence.ParentID == 0) // not sat on an object 8731 // As per LSL Wiki, there is no difference between sitting
8732 // and standing avatar since server 1.36
8733 LSL_Vector lower;
8734 LSL_Vector upper;
8735
8736 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8737
8738 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8739 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8740/*
8105 { 8741 {
8106 LSL_Vector lower; 8742 // This is for ground sitting avatars
8107 LSL_Vector upper; 8743 float height = presence.Appearance.AvatarHeight / 2.66666667f;
8108 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8744 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
8109 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8745 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
8110 {
8111 // This is for ground sitting avatars
8112 float height = presence.Appearance.AvatarHeight / 2.66666667f;
8113 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
8114 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
8115 }
8116 else
8117 {
8118 // This is for standing/flying avatars
8119 float height = presence.Appearance.AvatarHeight / 2.0f;
8120 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
8121 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
8122 }
8123 result.Add(lower);
8124 result.Add(upper);
8125 return result;
8126 } 8746 }
8127 else 8747 else
8128 { 8748 {
8129 // sitting on an object so we need the bounding box of that 8749 // This is for standing/flying avatars
8130 // which should include the avatar so set the UUID to the 8750 float height = presence.Appearance.AvatarHeight / 2.0f;
8131 // UUID of the object the avatar is sat on and allow it to fall through 8751 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
8132 // to processing an object 8752 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
8133 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
8134 objID = p.UUID;
8135 } 8753 }
8754
8755 // Adjust to the documented error offsets (see LSL Wiki)
8756 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8757 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8758*/
8759 {
8760 // This is for ground sitting avatars TODO!
8761 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8762 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
8763 }
8764 else
8765 {
8766 // This is for standing/flying avatars
8767 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8768 upper = new LSL_Vector(box.X, box.Y, box.Z);
8769 }
8770
8771 if (lower.x > upper.x)
8772 lower.x = upper.x;
8773 if (lower.y > upper.y)
8774 lower.y = upper.y;
8775 if (lower.z > upper.z)
8776 lower.z = upper.z;
8777
8778 result.Add(lower);
8779 result.Add(upper);
8780 return result;
8136 } 8781 }
8137 SceneObjectPart part = World.GetSceneObjectPart(objID); 8782
8783 part = World.GetSceneObjectPart(objID);
8138 // Currently only works for single prims without a sitting avatar 8784 // Currently only works for single prims without a sitting avatar
8139 if (part != null) 8785 if (part != null)
8140 { 8786 {
8141 Vector3 halfSize = part.Scale / 2.0f; 8787 float minX;
8142 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8788 float maxX;
8143 LSL_Vector upper = new LSL_Vector(halfSize); 8789 float minY;
8790 float maxY;
8791 float minZ;
8792 float maxZ;
8793
8794 // This BBox is in sim coordinates, with the offset being
8795 // a contained point.
8796 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8797 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8798
8799 minX -= offsets[0].X;
8800 maxX -= offsets[0].X;
8801 minY -= offsets[0].Y;
8802 maxY -= offsets[0].Y;
8803 minZ -= offsets[0].Z;
8804 maxZ -= offsets[0].Z;
8805
8806 LSL_Vector lower;
8807 LSL_Vector upper;
8808
8809 // Adjust to the documented error offsets (see LSL Wiki)
8810 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8811 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8812
8813 if (lower.x > upper.x)
8814 lower.x = upper.x;
8815 if (lower.y > upper.y)
8816 lower.y = upper.y;
8817 if (lower.z > upper.z)
8818 lower.z = upper.z;
8819
8144 result.Add(lower); 8820 result.Add(lower);
8145 result.Add(upper); 8821 result.Add(upper);
8146 return result; 8822 return result;
@@ -8157,224 +8833,74 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8157 return new LSL_Vector(m_host.GetGeometricCenter()); 8833 return new LSL_Vector(m_host.GetGeometricCenter());
8158 } 8834 }
8159 8835
8160 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 8836 public LSL_List llGetPrimitiveParams(LSL_List rules)
8161 { 8837 {
8162 LSL_List result = new LSL_List(); 8838 m_host.AddScriptLPS(1);
8163 LSL_List remaining = null;
8164 8839
8165 while (true) 8840 LSL_List result = new LSL_List();
8166 {
8167 if (entity is SceneObjectPart)
8168 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result);
8169 else
8170 remaining = GetAgentParams((ScenePresence)entity, rules, ref result);
8171 8841
8172 if (remaining == null || remaining.Length <= 2) 8842 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
8173 return result;
8174 8843
8844 while ((object)remaining != null && remaining.Length > 2)
8845 {
8175 int linknumber = remaining.GetLSLIntegerItem(0); 8846 int linknumber = remaining.GetLSLIntegerItem(0);
8176 rules = remaining.GetSublist(1, -1); 8847 rules = remaining.GetSublist(1, -1);
8177 entity = GetLinkEntity(linknumber); 8848 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8178 }
8179 }
8180 8849
8181 public LSL_List llGetPrimitiveParams(LSL_List rules) 8850 foreach (SceneObjectPart part in parts)
8182 { 8851 remaining = GetPrimParams(part, rules, ref result);
8183 m_host.AddScriptLPS(1); 8852 }
8184 8853
8185 return GetEntityParams(m_host, rules); 8854 return result;
8186 } 8855 }
8187 8856
8188 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8857 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
8189 { 8858 {
8190 m_host.AddScriptLPS(1); 8859 m_host.AddScriptLPS(1);
8191 8860
8192 return GetEntityParams(GetLinkEntity(linknumber), rules); 8861 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8193 } 8862 // keep other options as before
8194 8863
8195 public LSL_Vector GetAgentSize(ScenePresence sp) 8864 List<SceneObjectPart> parts;
8196 { 8865 List<ScenePresence> avatars;
8197 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); 8866
8198 } 8867 LSL_List res = new LSL_List();
8868 LSL_List remaining = null;
8199 8869
8200 /// <summary> 8870 while (rules.Length > 0)
8201 /// Gets params for a seated avatar in a linkset.
8202 /// </summary>
8203 /// <returns></returns>
8204 /// <param name='sp'></param>
8205 /// <param name='rules'></param>
8206 /// <param name='res'></param>
8207 public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res)
8208 {
8209 int idx = 0;
8210 while (idx < rules.Length)
8211 { 8871 {
8212 int code = (int)rules.GetLSLIntegerItem(idx++); 8872 parts = GetLinkParts(linknumber);
8213 int remain = rules.Length-idx; 8873 avatars = GetLinkAvatars(linknumber);
8214 8874
8215 switch (code) 8875 remaining = null;
8876 foreach (SceneObjectPart part in parts)
8216 { 8877 {
8217 case (int)ScriptBaseClass.PRIM_MATERIAL: 8878 remaining = GetPrimParams(part, rules, ref res);
8218 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 8879 }
8219 break; 8880 foreach (ScenePresence avatar in avatars)
8220 8881 {
8221 case (int)ScriptBaseClass.PRIM_PHYSICS: 8882 remaining = GetPrimParams(avatar, rules, ref res);
8222 res.Add(ScriptBaseClass.FALSE); 8883 }
8223 break;
8224
8225 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8226 res.Add(ScriptBaseClass.FALSE);
8227 break;
8228
8229 case (int)ScriptBaseClass.PRIM_PHANTOM:
8230 res.Add(ScriptBaseClass.FALSE);
8231 break;
8232
8233 case (int)ScriptBaseClass.PRIM_POSITION:
8234 res.Add(new LSL_Vector(sp.AbsolutePosition));
8235 break;
8236
8237 case (int)ScriptBaseClass.PRIM_SIZE:
8238 res.Add(GetAgentSize(sp));
8239 break;
8240
8241 case (int)ScriptBaseClass.PRIM_ROTATION:
8242 res.Add(sp.GetWorldRotation());
8243 break;
8244
8245 case (int)ScriptBaseClass.PRIM_TYPE:
8246 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8247 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8248 res.Add(new LSL_Vector(0, 1, 0));
8249 res.Add(new LSL_Float(0));
8250 res.Add(new LSL_Vector(0, 0, 0));
8251 res.Add(new LSL_Vector(1, 1, 0));
8252 res.Add(new LSL_Vector(0, 0, 0));
8253 break;
8254
8255 case (int)ScriptBaseClass.PRIM_TEXTURE:
8256 if (remain < 1)
8257 return null;
8258
8259 int face = (int)rules.GetLSLIntegerItem(idx++);
8260 if (face > 21)
8261 break;
8262
8263 res.Add(new LSL_String(""));
8264 res.Add(ScriptBaseClass.ZERO_VECTOR);
8265 res.Add(ScriptBaseClass.ZERO_VECTOR);
8266 res.Add(new LSL_Float(0));
8267 break;
8268
8269 case (int)ScriptBaseClass.PRIM_COLOR:
8270 if (remain < 1)
8271 return null;
8272
8273 face = (int)rules.GetLSLIntegerItem(idx++);
8274 if (face > 21)
8275 break;
8276
8277 res.Add(ScriptBaseClass.ZERO_VECTOR);
8278 res.Add(new LSL_Float(0));
8279 break;
8280
8281 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8282 if (remain < 1)
8283 return null;
8284
8285 face = (int)rules.GetLSLIntegerItem(idx++);
8286 if (face > 21)
8287 break;
8288
8289 res.Add(ScriptBaseClass.PRIM_SHINY_NONE);
8290 res.Add(ScriptBaseClass.PRIM_BUMP_NONE);
8291 break;
8292
8293 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8294 if (remain < 1)
8295 return null;
8296
8297 face = (int)rules.GetLSLIntegerItem(idx++);
8298 if (face > 21)
8299 break;
8300
8301 res.Add(ScriptBaseClass.FALSE);
8302 break;
8303
8304 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8305 res.Add(ScriptBaseClass.FALSE);
8306 res.Add(new LSL_Integer(0));
8307 res.Add(new LSL_Float(0));
8308 res.Add(new LSL_Float(0));
8309 res.Add(new LSL_Float(0));
8310 res.Add(new LSL_Float(0));
8311 res.Add(ScriptBaseClass.ZERO_VECTOR);
8312 break;
8313
8314 case (int)ScriptBaseClass.PRIM_TEXGEN:
8315 if (remain < 1)
8316 return null;
8317
8318 face = (int)rules.GetLSLIntegerItem(idx++);
8319 if (face > 21)
8320 break;
8321
8322 res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT);
8323 break;
8324
8325 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8326 res.Add(ScriptBaseClass.FALSE);
8327 res.Add(ScriptBaseClass.ZERO_VECTOR);
8328 res.Add(ScriptBaseClass.ZERO_VECTOR);
8329 break;
8330
8331 case (int)ScriptBaseClass.PRIM_GLOW:
8332 if (remain < 1)
8333 return null;
8334
8335 face = (int)rules.GetLSLIntegerItem(idx++);
8336 if (face > 21)
8337 break;
8338
8339 res.Add(new LSL_Float(0));
8340 break;
8341
8342 case (int)ScriptBaseClass.PRIM_TEXT:
8343 res.Add(new LSL_String(""));
8344 res.Add(ScriptBaseClass.ZERO_VECTOR);
8345 res.Add(new LSL_Float(1));
8346 break;
8347
8348 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8349 res.Add(new LSL_Rotation(sp.Rotation));
8350 break;
8351
8352 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8353 res.Add(new LSL_Vector(sp.OffsetPosition));
8354 break;
8355
8356 case (int)ScriptBaseClass.PRIM_SLICE:
8357 res.Add(new LSL_Vector(0, 1, 0));
8358 break;
8359
8360 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8361 if(remain < 3)
8362 return null;
8363 8884
8364 return rules.GetSublist(idx, -1); 8885 if ((object)remaining != null && remaining.Length > 0)
8886 {
8887 linknumber = remaining.GetLSLIntegerItem(0);
8888 rules = remaining.GetSublist(1, -1);
8365 } 8889 }
8890 else
8891 break;
8366 } 8892 }
8367 8893
8368 return null; 8894 return res;
8369 } 8895 }
8370 8896
8371 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 8897 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
8372 { 8898 {
8373 int idx = 0; 8899 int idx=0;
8374 while (idx < rules.Length) 8900 while (idx < rules.Length)
8375 { 8901 {
8376 int code = (int)rules.GetLSLIntegerItem(idx++); 8902 int code=(int)rules.GetLSLIntegerItem(idx++);
8377 int remain = rules.Length-idx; 8903 int remain=rules.Length-idx;
8378 8904
8379 switch (code) 8905 switch (code)
8380 { 8906 {
@@ -8404,19 +8930,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8404 break; 8930 break;
8405 8931
8406 case (int)ScriptBaseClass.PRIM_POSITION: 8932 case (int)ScriptBaseClass.PRIM_POSITION:
8407 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 8933 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8408 8934 part.AbsolutePosition.Y,
8409 // For some reason, the part.AbsolutePosition.* values do not change if the 8935 part.AbsolutePosition.Z);
8410 // linkset is rotated; they always reflect the child prim's world position
8411 // as though the linkset is unrotated. This is incompatible behavior with SL's
8412 // implementation, so will break scripts imported from there (not to mention it
8413 // makes it more difficult to determine a child prim's actual inworld position).
8414 if (!part.IsRoot)
8415 {
8416 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8417 v = ((v - rootPos) * llGetRootRotation()) + rootPos;
8418 }
8419
8420 res.Add(v); 8936 res.Add(v);
8421 break; 8937 break;
8422 8938
@@ -8586,30 +9102,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8586 if (remain < 1) 9102 if (remain < 1)
8587 return null; 9103 return null;
8588 9104
8589 face=(int)rules.GetLSLIntegerItem(idx++); 9105 face = (int)rules.GetLSLIntegerItem(idx++);
8590 9106
8591 tex = part.Shape.Textures; 9107 tex = part.Shape.Textures;
9108 int shiny;
8592 if (face == ScriptBaseClass.ALL_SIDES) 9109 if (face == ScriptBaseClass.ALL_SIDES)
8593 { 9110 {
8594 for (face = 0; face < GetNumberOfSides(part); face++) 9111 for (face = 0; face < GetNumberOfSides(part); face++)
8595 { 9112 {
8596 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9113 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8597 // Convert Shininess to PRIM_SHINY_* 9114 if (shinyness == Shininess.High)
8598 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9115 {
8599 // PRIM_BUMP_* 9116 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8600 res.Add(new LSL_Integer((int)texface.Bump)); 9117 }
9118 else if (shinyness == Shininess.Medium)
9119 {
9120 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9121 }
9122 else if (shinyness == Shininess.Low)
9123 {
9124 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9125 }
9126 else
9127 {
9128 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9129 }
9130 res.Add(new LSL_Integer(shiny));
9131 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8601 } 9132 }
8602 } 9133 }
8603 else 9134 else
8604 { 9135 {
8605 if (face >= 0 && face < GetNumberOfSides(part)) 9136 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9137 if (shinyness == Shininess.High)
8606 { 9138 {
8607 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9139 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8608 // Convert Shininess to PRIM_SHINY_*
8609 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8610 // PRIM_BUMP_*
8611 res.Add(new LSL_Integer((int)texface.Bump));
8612 } 9140 }
9141 else if (shinyness == Shininess.Medium)
9142 {
9143 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9144 }
9145 else if (shinyness == Shininess.Low)
9146 {
9147 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9148 }
9149 else
9150 {
9151 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9152 }
9153 res.Add(new LSL_Integer(shiny));
9154 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8613 } 9155 }
8614 break; 9156 break;
8615 9157
@@ -8620,21 +9162,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8620 face = (int)rules.GetLSLIntegerItem(idx++); 9162 face = (int)rules.GetLSLIntegerItem(idx++);
8621 9163
8622 tex = part.Shape.Textures; 9164 tex = part.Shape.Textures;
9165 int fullbright;
8623 if (face == ScriptBaseClass.ALL_SIDES) 9166 if (face == ScriptBaseClass.ALL_SIDES)
8624 { 9167 {
8625 for (face = 0; face < GetNumberOfSides(part); face++) 9168 for (face = 0; face < GetNumberOfSides(part); face++)
8626 { 9169 {
8627 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9170 if (tex.GetFace((uint)face).Fullbright == true)
8628 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9171 {
9172 fullbright = ScriptBaseClass.TRUE;
9173 }
9174 else
9175 {
9176 fullbright = ScriptBaseClass.FALSE;
9177 }
9178 res.Add(new LSL_Integer(fullbright));
8629 } 9179 }
8630 } 9180 }
8631 else 9181 else
8632 { 9182 {
8633 if (face >= 0 && face < GetNumberOfSides(part)) 9183 if (tex.GetFace((uint)face).Fullbright == true)
8634 { 9184 {
8635 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9185 fullbright = ScriptBaseClass.TRUE;
8636 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8637 } 9186 }
9187 else
9188 {
9189 fullbright = ScriptBaseClass.FALSE;
9190 }
9191 res.Add(new LSL_Integer(fullbright));
8638 } 9192 }
8639 break; 9193 break;
8640 9194
@@ -8656,27 +9210,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8656 break; 9210 break;
8657 9211
8658 case (int)ScriptBaseClass.PRIM_TEXGEN: 9212 case (int)ScriptBaseClass.PRIM_TEXGEN:
9213 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8659 if (remain < 1) 9214 if (remain < 1)
8660 return null; 9215 return null;
8661 9216
8662 face=(int)rules.GetLSLIntegerItem(idx++); 9217 face = (int)rules.GetLSLIntegerItem(idx++);
8663 9218
8664 tex = part.Shape.Textures; 9219 tex = part.Shape.Textures;
8665 if (face == ScriptBaseClass.ALL_SIDES) 9220 if (face == ScriptBaseClass.ALL_SIDES)
8666 { 9221 {
8667 for (face = 0; face < GetNumberOfSides(part); face++) 9222 for (face = 0; face < GetNumberOfSides(part); face++)
8668 { 9223 {
8669 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9224 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8670 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9225 {
8671 res.Add(new LSL_Integer((uint)texgen >> 1)); 9226 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9227 }
9228 else
9229 {
9230 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9231 }
8672 } 9232 }
8673 } 9233 }
8674 else 9234 else
8675 { 9235 {
8676 if (face >= 0 && face < GetNumberOfSides(part)) 9236 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9237 {
9238 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9239 }
9240 else
8677 { 9241 {
8678 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9242 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8679 res.Add(new LSL_Integer((uint)texgen >> 1));
8680 } 9243 }
8681 } 9244 }
8682 break; 9245 break;
@@ -8700,24 +9263,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8700 if (remain < 1) 9263 if (remain < 1)
8701 return null; 9264 return null;
8702 9265
8703 face=(int)rules.GetLSLIntegerItem(idx++); 9266 face = (int)rules.GetLSLIntegerItem(idx++);
8704 9267
8705 tex = part.Shape.Textures; 9268 tex = part.Shape.Textures;
9269 float primglow;
8706 if (face == ScriptBaseClass.ALL_SIDES) 9270 if (face == ScriptBaseClass.ALL_SIDES)
8707 { 9271 {
8708 for (face = 0; face < GetNumberOfSides(part); face++) 9272 for (face = 0; face < GetNumberOfSides(part); face++)
8709 { 9273 {
8710 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9274 primglow = tex.GetFace((uint)face).Glow;
8711 res.Add(new LSL_Float(texface.Glow)); 9275 res.Add(new LSL_Float(primglow));
8712 } 9276 }
8713 } 9277 }
8714 else 9278 else
8715 { 9279 {
8716 if (face >= 0 && face < GetNumberOfSides(part)) 9280 primglow = tex.GetFace((uint)face).Glow;
8717 { 9281 res.Add(new LSL_Float(primglow));
8718 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8719 res.Add(new LSL_Float(texface.Glow));
8720 }
8721 } 9282 }
8722 break; 9283 break;
8723 9284
@@ -8729,15 +9290,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8729 textColor.B)); 9290 textColor.B));
8730 res.Add(new LSL_Float(textColor.A)); 9291 res.Add(new LSL_Float(textColor.A));
8731 break; 9292 break;
9293
8732 case (int)ScriptBaseClass.PRIM_NAME: 9294 case (int)ScriptBaseClass.PRIM_NAME:
8733 res.Add(new LSL_String(part.Name)); 9295 res.Add(new LSL_String(part.Name));
8734 break; 9296 break;
9297
8735 case (int)ScriptBaseClass.PRIM_DESC: 9298 case (int)ScriptBaseClass.PRIM_DESC:
8736 res.Add(new LSL_String(part.Description)); 9299 res.Add(new LSL_String(part.Description));
8737 break; 9300 break;
8738 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9301 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8739 res.Add(new LSL_Rotation(part.RotationOffset)); 9302 res.Add(new LSL_Rotation(part.RotationOffset));
8740 break; 9303 break;
9304
8741 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9305 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8742 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9306 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8743 break; 9307 break;
@@ -9348,8 +9912,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9348 // The function returns an ordered list 9912 // The function returns an ordered list
9349 // representing the tokens found in the supplied 9913 // representing the tokens found in the supplied
9350 // sources string. If two successive tokenizers 9914 // sources string. If two successive tokenizers
9351 // are encountered, then a NULL entry is added 9915 // are encountered, then a null-string entry is
9352 // to the list. 9916 // added to the list.
9353 // 9917 //
9354 // It is a precondition that the source and 9918 // It is a precondition that the source and
9355 // toekizer lisst are non-null. If they are null, 9919 // toekizer lisst are non-null. If they are null,
@@ -9357,7 +9921,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9357 // while their lengths are being determined. 9921 // while their lengths are being determined.
9358 // 9922 //
9359 // A small amount of working memoryis required 9923 // A small amount of working memoryis required
9360 // of approximately 8*#tokenizers. 9924 // of approximately 8*#tokenizers + 8*srcstrlen.
9361 // 9925 //
9362 // There are many ways in which this function 9926 // There are many ways in which this function
9363 // can be implemented, this implementation is 9927 // can be implemented, this implementation is
@@ -9373,155 +9937,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9373 // and eliminates redundant tokenizers as soon 9937 // and eliminates redundant tokenizers as soon
9374 // as is possible. 9938 // as is possible.
9375 // 9939 //
9376 // The implementation tries to avoid any copying 9940 // The implementation tries to minimize temporary
9377 // of arrays or other objects. 9941 // garbage generation.
9378 // </remarks> 9942 // </remarks>
9379 9943
9380 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9944 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9381 { 9945 {
9382 int beginning = 0; 9946 return ParseString2List(src, separators, spacers, true);
9383 int srclen = src.Length; 9947 }
9384 int seplen = separators.Length;
9385 object[] separray = separators.Data;
9386 int spclen = spacers.Length;
9387 object[] spcarray = spacers.Data;
9388 int mlen = seplen+spclen;
9389
9390 int[] offset = new int[mlen+1];
9391 bool[] active = new bool[mlen];
9392
9393 int best;
9394 int j;
9395
9396 // Initial capacity reduces resize cost
9397 9948
9398 LSL_List tokens = new LSL_List(); 9949 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9950 {
9951 int srclen = src.Length;
9952 int seplen = separators.Length;
9953 object[] separray = separators.Data;
9954 int spclen = spacers.Length;
9955 object[] spcarray = spacers.Data;
9956 int dellen = 0;
9957 string[] delarray = new string[seplen+spclen];
9399 9958
9400 // All entries are initially valid 9959 int outlen = 0;
9960 string[] outarray = new string[srclen*2+1];
9401 9961
9402 for (int i = 0; i < mlen; i++) 9962 int i, j;
9403 active[i] = true; 9963 string d;
9404 9964
9405 offset[mlen] = srclen; 9965 m_host.AddScriptLPS(1);
9406 9966
9407 while (beginning < srclen) 9967 /*
9968 * Convert separator and spacer lists to C# strings.
9969 * Also filter out null strings so we don't hang.
9970 */
9971 for (i = 0; i < seplen; i ++)
9408 { 9972 {
9973 d = separray[i].ToString();
9974 if (d.Length > 0)
9975 {
9976 delarray[dellen++] = d;
9977 }
9978 }
9979 seplen = dellen;
9409 9980
9410 best = mlen; // as bad as it gets 9981 for (i = 0; i < spclen; i ++)
9982 {
9983 d = spcarray[i].ToString();
9984 if (d.Length > 0)
9985 {
9986 delarray[dellen++] = d;
9987 }
9988 }
9411 9989
9412 // Scan for separators 9990 /*
9991 * Scan through source string from beginning to end.
9992 */
9993 for (i = 0;;)
9994 {
9413 9995
9414 for (j = 0; j < seplen; j++) 9996 /*
9997 * Find earliest delimeter in src starting at i (if any).
9998 */
9999 int earliestDel = -1;
10000 int earliestSrc = srclen;
10001 string earliestStr = null;
10002 for (j = 0; j < dellen; j ++)
9415 { 10003 {
9416 if (separray[j].ToString() == String.Empty) 10004 d = delarray[j];
9417 active[j] = false; 10005 if (d != null)
9418
9419 if (active[j])
9420 { 10006 {
9421 // scan all of the markers 10007 int index = src.IndexOf(d, i);
9422 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10008 if (index < 0)
9423 { 10009 {
9424 // not present at all 10010 delarray[j] = null; // delim nowhere in src, don't check it anymore
9425 active[j] = false;
9426 } 10011 }
9427 else 10012 else if (index < earliestSrc)
9428 { 10013 {
9429 // present and correct 10014 earliestSrc = index; // where delimeter starts in source string
9430 if (offset[j] < offset[best]) 10015 earliestDel = j; // where delimeter is in delarray[]
9431 { 10016 earliestStr = d; // the delimeter string from delarray[]
9432 // closest so far 10017 if (index == i) break; // can't do any better than found at beg of string
9433 best = j;
9434 if (offset[best] == beginning)
9435 break;
9436 }
9437 } 10018 }
9438 } 10019 }
9439 } 10020 }
9440 10021
9441 // Scan for spacers 10022 /*
9442 10023 * Output source string starting at i through start of earliest delimeter.
9443 if (offset[best] != beginning) 10024 */
10025 if (keepNulls || (earliestSrc > i))
9444 { 10026 {
9445 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10027 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9446 {
9447 if (spcarray[j-seplen].ToString() == String.Empty)
9448 active[j] = false;
9449
9450 if (active[j])
9451 {
9452 // scan all of the markers
9453 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9454 {
9455 // not present at all
9456 active[j] = false;
9457 }
9458 else
9459 {
9460 // present and correct
9461 if (offset[j] < offset[best])
9462 {
9463 // closest so far
9464 best = j;
9465 }
9466 }
9467 }
9468 }
9469 } 10028 }
9470 10029
9471 // This is the normal exit from the scanning loop 10030 /*
10031 * If no delimeter found at or after i, we're done scanning.
10032 */
10033 if (earliestDel < 0) break;
9472 10034
9473 if (best == mlen) 10035 /*
10036 * If delimeter was a spacer, output the spacer.
10037 */
10038 if (earliestDel >= seplen)
9474 { 10039 {
9475 // no markers were found on this pass 10040 outarray[outlen++] = earliestStr;
9476 // so we're pretty much done
9477 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9478 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9479 break;
9480 } 10041 }
9481 10042
9482 // Otherwise we just add the newly delimited token 10043 /*
9483 // and recalculate where the search should continue. 10044 * Look at rest of src string following delimeter.
9484 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10045 */
9485 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10046 i = earliestSrc + earliestStr.Length;
9486
9487 if (best < seplen)
9488 {
9489 beginning = offset[best] + (separray[best].ToString()).Length;
9490 }
9491 else
9492 {
9493 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9494 string str = spcarray[best - seplen].ToString();
9495 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9496 tokens.Add(new LSL_String(str));
9497 }
9498 } 10047 }
9499 10048
9500 // This an awkward an not very intuitive boundary case. If the 10049 /*
9501 // last substring is a tokenizer, then there is an implied trailing 10050 * Make up an exact-sized output array suitable for an LSL_List object.
9502 // null list entry. Hopefully the single comparison will not be too 10051 */
9503 // arduous. Alternatively the 'break' could be replced with a return 10052 object[] outlist = new object[outlen];
9504 // but that's shabby programming. 10053 for (i = 0; i < outlen; i ++)
9505
9506 if ((beginning == srclen) && (keepNulls))
9507 { 10054 {
9508 if (srclen != 0) 10055 outlist[i] = new LSL_String(outarray[i]);
9509 tokens.Add(new LSL_String(""));
9510 } 10056 }
9511 10057 return new LSL_List(outlist);
9512 return tokens;
9513 }
9514
9515 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9516 {
9517 m_host.AddScriptLPS(1);
9518 return this.ParseString(src, separators, spacers, false);
9519 }
9520
9521 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9522 {
9523 m_host.AddScriptLPS(1);
9524 return this.ParseString(src, separators, spacers, true);
9525 } 10058 }
9526 10059
9527 public LSL_Integer llGetObjectPermMask(int mask) 10060 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9616,6 +10149,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9616 case 4: 10149 case 4:
9617 return (int)item.NextPermissions; 10150 return (int)item.NextPermissions;
9618 } 10151 }
10152 m_host.TaskInventory.LockItemsForRead(false);
9619 10153
9620 return -1; 10154 return -1;
9621 } 10155 }
@@ -9819,31 +10353,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9819 UUID key = new UUID(); 10353 UUID key = new UUID();
9820 if (UUID.TryParse(id, out key)) 10354 if (UUID.TryParse(id, out key))
9821 { 10355 {
9822 try 10356 // return total object mass
9823 { 10357 SceneObjectPart part = World.GetSceneObjectPart(key);
9824 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10358 if (part != null)
9825 if (obj != null) 10359 return part.ParentGroup.GetMass();
9826 return (double)obj.GetMass(); 10360
9827 // the object is null so the key is for an avatar 10361 // the object is null so the key is for an avatar
9828 ScenePresence avatar = World.GetScenePresence(key); 10362 ScenePresence avatar = World.GetScenePresence(key);
9829 if (avatar != null) 10363 if (avatar != null)
9830 if (avatar.IsChildAgent)
9831 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9832 // child agents have a mass of 1.0
9833 return 1;
9834 else
9835 return (double)avatar.GetMass();
9836 }
9837 catch (KeyNotFoundException)
9838 { 10364 {
9839 return 0; // The Object/Agent not in the region so just return zero 10365 if (avatar.IsChildAgent)
10366 {
10367 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10368 // child agents have a mass of 1.0
10369 return 1;
10370 }
10371 else
10372 {
10373 return (double)avatar.GetMass();
10374 }
9840 } 10375 }
9841 } 10376 }
9842 return 0; 10377 return 0;
9843 } 10378 }
9844 10379
9845 /// <summary> 10380 /// <summary>
9846 /// illListReplaceList removes the sub-list defined by the inclusive indices 10381 /// llListReplaceList removes the sub-list defined by the inclusive indices
9847 /// start and end and inserts the src list in its place. The inclusive 10382 /// start and end and inserts the src list in its place. The inclusive
9848 /// nature of the indices means that at least one element must be deleted 10383 /// nature of the indices means that at least one element must be deleted
9849 /// if the indices are within the bounds of the existing list. I.e. 2,2 10384 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9900,16 +10435,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9900 // based upon end. Note that if end exceeds the upper 10435 // based upon end. Note that if end exceeds the upper
9901 // bound in this case, the entire destination list 10436 // bound in this case, the entire destination list
9902 // is removed. 10437 // is removed.
9903 else 10438 else if (start == 0)
9904 { 10439 {
9905 if (end + 1 < dest.Length) 10440 if (end + 1 < dest.Length)
9906 {
9907 return src + dest.GetSublist(end + 1, -1); 10441 return src + dest.GetSublist(end + 1, -1);
9908 }
9909 else 10442 else
9910 {
9911 return src; 10443 return src;
9912 } 10444 }
10445 else // Start < 0
10446 {
10447 if (end + 1 < dest.Length)
10448 return dest.GetSublist(end + 1, -1);
10449 else
10450 return new LSL_List();
9913 } 10451 }
9914 } 10452 }
9915 // Finally, if start > end, we strip away a prefix and 10453 // Finally, if start > end, we strip away a prefix and
@@ -9960,17 +10498,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9960 int width = 0; 10498 int width = 0;
9961 int height = 0; 10499 int height = 0;
9962 10500
9963 ParcelMediaCommandEnum? commandToSend = null; 10501 uint commandToSend = 0;
9964 float time = 0.0f; // default is from start 10502 float time = 0.0f; // default is from start
9965 10503
9966 ScenePresence presence = null; 10504 ScenePresence presence = null;
9967 10505
9968 for (int i = 0; i < commandList.Data.Length; i++) 10506 for (int i = 0; i < commandList.Data.Length; i++)
9969 { 10507 {
9970 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10508 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9971 switch (command) 10509 switch (command)
9972 { 10510 {
9973 case ParcelMediaCommandEnum.Agent: 10511 case (uint)ParcelMediaCommandEnum.Agent:
9974 // we send only to one agent 10512 // we send only to one agent
9975 if ((i + 1) < commandList.Length) 10513 if ((i + 1) < commandList.Length)
9976 { 10514 {
@@ -9987,25 +10525,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9987 } 10525 }
9988 break; 10526 break;
9989 10527
9990 case ParcelMediaCommandEnum.Loop: 10528 case (uint)ParcelMediaCommandEnum.Loop:
9991 loop = 1; 10529 loop = 1;
9992 commandToSend = command; 10530 commandToSend = command;
9993 update = true; //need to send the media update packet to set looping 10531 update = true; //need to send the media update packet to set looping
9994 break; 10532 break;
9995 10533
9996 case ParcelMediaCommandEnum.Play: 10534 case (uint)ParcelMediaCommandEnum.Play:
9997 loop = 0; 10535 loop = 0;
9998 commandToSend = command; 10536 commandToSend = command;
9999 update = true; //need to send the media update packet to make sure it doesn't loop 10537 update = true; //need to send the media update packet to make sure it doesn't loop
10000 break; 10538 break;
10001 10539
10002 case ParcelMediaCommandEnum.Pause: 10540 case (uint)ParcelMediaCommandEnum.Pause:
10003 case ParcelMediaCommandEnum.Stop: 10541 case (uint)ParcelMediaCommandEnum.Stop:
10004 case ParcelMediaCommandEnum.Unload: 10542 case (uint)ParcelMediaCommandEnum.Unload:
10005 commandToSend = command; 10543 commandToSend = command;
10006 break; 10544 break;
10007 10545
10008 case ParcelMediaCommandEnum.Url: 10546 case (uint)ParcelMediaCommandEnum.Url:
10009 if ((i + 1) < commandList.Length) 10547 if ((i + 1) < commandList.Length)
10010 { 10548 {
10011 if (commandList.Data[i + 1] is LSL_String) 10549 if (commandList.Data[i + 1] is LSL_String)
@@ -10018,7 +10556,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10018 } 10556 }
10019 break; 10557 break;
10020 10558
10021 case ParcelMediaCommandEnum.Texture: 10559 case (uint)ParcelMediaCommandEnum.Texture:
10022 if ((i + 1) < commandList.Length) 10560 if ((i + 1) < commandList.Length)
10023 { 10561 {
10024 if (commandList.Data[i + 1] is LSL_String) 10562 if (commandList.Data[i + 1] is LSL_String)
@@ -10031,7 +10569,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10031 } 10569 }
10032 break; 10570 break;
10033 10571
10034 case ParcelMediaCommandEnum.Time: 10572 case (uint)ParcelMediaCommandEnum.Time:
10035 if ((i + 1) < commandList.Length) 10573 if ((i + 1) < commandList.Length)
10036 { 10574 {
10037 if (commandList.Data[i + 1] is LSL_Float) 10575 if (commandList.Data[i + 1] is LSL_Float)
@@ -10043,7 +10581,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10043 } 10581 }
10044 break; 10582 break;
10045 10583
10046 case ParcelMediaCommandEnum.AutoAlign: 10584 case (uint)ParcelMediaCommandEnum.AutoAlign:
10047 if ((i + 1) < commandList.Length) 10585 if ((i + 1) < commandList.Length)
10048 { 10586 {
10049 if (commandList.Data[i + 1] is LSL_Integer) 10587 if (commandList.Data[i + 1] is LSL_Integer)
@@ -10057,7 +10595,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10057 } 10595 }
10058 break; 10596 break;
10059 10597
10060 case ParcelMediaCommandEnum.Type: 10598 case (uint)ParcelMediaCommandEnum.Type:
10061 if ((i + 1) < commandList.Length) 10599 if ((i + 1) < commandList.Length)
10062 { 10600 {
10063 if (commandList.Data[i + 1] is LSL_String) 10601 if (commandList.Data[i + 1] is LSL_String)
@@ -10070,7 +10608,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10070 } 10608 }
10071 break; 10609 break;
10072 10610
10073 case ParcelMediaCommandEnum.Desc: 10611 case (uint)ParcelMediaCommandEnum.Desc:
10074 if ((i + 1) < commandList.Length) 10612 if ((i + 1) < commandList.Length)
10075 { 10613 {
10076 if (commandList.Data[i + 1] is LSL_String) 10614 if (commandList.Data[i + 1] is LSL_String)
@@ -10083,7 +10621,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10083 } 10621 }
10084 break; 10622 break;
10085 10623
10086 case ParcelMediaCommandEnum.Size: 10624 case (uint)ParcelMediaCommandEnum.Size:
10087 if ((i + 2) < commandList.Length) 10625 if ((i + 2) < commandList.Length)
10088 { 10626 {
10089 if (commandList.Data[i + 1] is LSL_Integer) 10627 if (commandList.Data[i + 1] is LSL_Integer)
@@ -10153,7 +10691,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10153 } 10691 }
10154 } 10692 }
10155 10693
10156 if (commandToSend != null) 10694 if (commandToSend != 0)
10157 { 10695 {
10158 // the commandList contained a start/stop/... command, too 10696 // the commandList contained a start/stop/... command, too
10159 if (presence == null) 10697 if (presence == null)
@@ -10190,7 +10728,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10190 10728
10191 if (aList.Data[i] != null) 10729 if (aList.Data[i] != null)
10192 { 10730 {
10193 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10731 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
10194 { 10732 {
10195 case ParcelMediaCommandEnum.Url: 10733 case ParcelMediaCommandEnum.Url:
10196 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10734 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -10247,15 +10785,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10247 10785
10248 if (quick_pay_buttons.Data.Length < 4) 10786 if (quick_pay_buttons.Data.Length < 4)
10249 { 10787 {
10250 LSLError("List must have at least 4 elements"); 10788 int x;
10251 return; 10789 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10790 {
10791 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10792 }
10252 } 10793 }
10253 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10794 int[] nPrice = new int[5];
10254 10795 nPrice[0] = price;
10255 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10796 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
10256 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10797 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
10257 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10798 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
10258 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10799 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10800 m_host.ParentGroup.RootPart.PayPrice = nPrice;
10259 m_host.ParentGroup.HasGroupChanged = true; 10801 m_host.ParentGroup.HasGroupChanged = true;
10260 } 10802 }
10261 10803
@@ -10272,7 +10814,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10272 return Vector3.Zero; 10814 return Vector3.Zero;
10273 } 10815 }
10274 10816
10275 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10817// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10818 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10276 if (presence != null) 10819 if (presence != null)
10277 { 10820 {
10278 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 10821 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
@@ -10295,7 +10838,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10295 return Quaternion.Identity; 10838 return Quaternion.Identity;
10296 } 10839 }
10297 10840
10298 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10841// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10842 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10299 if (presence != null) 10843 if (presence != null)
10300 { 10844 {
10301 return new LSL_Rotation(presence.CameraRotation); 10845 return new LSL_Rotation(presence.CameraRotation);
@@ -10355,14 +10899,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10355 { 10899 {
10356 m_host.AddScriptLPS(1); 10900 m_host.AddScriptLPS(1);
10357 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10901 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10358 if (detectedParams == null) return; // only works on the first detected avatar 10902 if (detectedParams == null)
10359 10903 {
10904 if (m_host.ParentGroup.IsAttachment == true)
10905 {
10906 detectedParams = new DetectParams();
10907 detectedParams.Key = m_host.OwnerID;
10908 }
10909 else
10910 {
10911 return;
10912 }
10913 }
10914
10360 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10915 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10361 if (avatar != null) 10916 if (avatar != null)
10362 { 10917 {
10363 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10918 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10364 simname, pos, lookAt); 10919 simname, pos, lookAt);
10365 } 10920 }
10921
10366 ScriptSleep(1000); 10922 ScriptSleep(1000);
10367 } 10923 }
10368 10924
@@ -10486,12 +11042,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10486 11042
10487 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11043 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10488 object[] data = rules.Data; 11044 object[] data = rules.Data;
10489 for (int i = 0; i < data.Length; ++i) { 11045 for (int i = 0; i < data.Length; ++i)
11046 {
10490 int type = Convert.ToInt32(data[i++].ToString()); 11047 int type = Convert.ToInt32(data[i++].ToString());
10491 if (i >= data.Length) break; // odd number of entries => ignore the last 11048 if (i >= data.Length) break; // odd number of entries => ignore the last
10492 11049
10493 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11050 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10494 switch (type) { 11051 switch (type)
11052 {
10495 case ScriptBaseClass.CAMERA_FOCUS: 11053 case ScriptBaseClass.CAMERA_FOCUS:
10496 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11054 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10497 case ScriptBaseClass.CAMERA_POSITION: 11055 case ScriptBaseClass.CAMERA_POSITION:
@@ -10596,19 +11154,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10596 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11154 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10597 { 11155 {
10598 m_host.AddScriptLPS(1); 11156 m_host.AddScriptLPS(1);
10599 string ret = String.Empty; 11157
10600 string src1 = llBase64ToString(str1); 11158 if (str1 == String.Empty)
10601 string src2 = llBase64ToString(str2); 11159 return String.Empty;
10602 int c = 0; 11160 if (str2 == String.Empty)
10603 for (int i = 0; i < src1.Length; i++) 11161 return str1;
11162
11163 int len = str2.Length;
11164 if ((len % 4) != 0) // LL is EVIL!!!!
11165 {
11166 while (str2.EndsWith("="))
11167 str2 = str2.Substring(0, str2.Length - 1);
11168
11169 len = str2.Length;
11170 int mod = len % 4;
11171
11172 if (mod == 1)
11173 str2 = str2.Substring(0, str2.Length - 1);
11174 else if (mod == 2)
11175 str2 += "==";
11176 else if (mod == 3)
11177 str2 += "=";
11178 }
11179
11180 byte[] data1;
11181 byte[] data2;
11182 try
11183 {
11184 data1 = Convert.FromBase64String(str1);
11185 data2 = Convert.FromBase64String(str2);
11186 }
11187 catch (Exception)
11188 {
11189 return new LSL_String(String.Empty);
11190 }
11191
11192 byte[] d2 = new Byte[data1.Length];
11193 int pos = 0;
11194
11195 if (data1.Length <= data2.Length)
11196 {
11197 Array.Copy(data2, 0, d2, 0, data1.Length);
11198 }
11199 else
10604 { 11200 {
10605 ret += (char) (src1[i] ^ src2[c]); 11201 while (pos < data1.Length)
11202 {
11203 len = data1.Length - pos;
11204 if (len > data2.Length)
11205 len = data2.Length;
10606 11206
10607 c++; 11207 Array.Copy(data2, 0, d2, pos, len);
10608 if (c >= src2.Length) 11208 pos += len;
10609 c = 0; 11209 }
10610 } 11210 }
10611 return llStringToBase64(ret); 11211
11212 for (pos = 0 ; pos < data1.Length ; pos++ )
11213 data1[pos] ^= d2[pos];
11214
11215 return Convert.ToBase64String(data1);
10612 } 11216 }
10613 11217
10614 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11218 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10712,16 +11316,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10712 if (userAgent != null) 11316 if (userAgent != null)
10713 httpHeaders["User-Agent"] = userAgent; 11317 httpHeaders["User-Agent"] = userAgent;
10714 11318
11319 // See if the URL contains any header hacks
11320 string[] urlParts = url.Split(new char[] {'\n'});
11321 if (urlParts.Length > 1)
11322 {
11323 // Iterate the passed headers and parse them
11324 for (int i = 1 ; i < urlParts.Length ; i++ )
11325 {
11326 // The rest of those would be added to the body in SL.
11327 // Let's not do that.
11328 if (urlParts[i] == String.Empty)
11329 break;
11330
11331 // See if this could be a valid header
11332 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11333 if (headerParts.Length != 2)
11334 continue;
11335
11336 string headerName = headerParts[0].Trim();
11337 string headerValue = headerParts[1].Trim();
11338
11339 // Filter out headers that could be used to abuse
11340 // another system or cloak the request
11341 if (headerName.ToLower() == "x-secondlife-shard" ||
11342 headerName.ToLower() == "x-secondlife-object-name" ||
11343 headerName.ToLower() == "x-secondlife-object-key" ||
11344 headerName.ToLower() == "x-secondlife-region" ||
11345 headerName.ToLower() == "x-secondlife-local-position" ||
11346 headerName.ToLower() == "x-secondlife-local-velocity" ||
11347 headerName.ToLower() == "x-secondlife-local-rotation" ||
11348 headerName.ToLower() == "x-secondlife-owner-name" ||
11349 headerName.ToLower() == "x-secondlife-owner-key" ||
11350 headerName.ToLower() == "connection" ||
11351 headerName.ToLower() == "content-length" ||
11352 headerName.ToLower() == "from" ||
11353 headerName.ToLower() == "host" ||
11354 headerName.ToLower() == "proxy-authorization" ||
11355 headerName.ToLower() == "referer" ||
11356 headerName.ToLower() == "trailer" ||
11357 headerName.ToLower() == "transfer-encoding" ||
11358 headerName.ToLower() == "via" ||
11359 headerName.ToLower() == "authorization")
11360 continue;
11361
11362 httpHeaders[headerName] = headerValue;
11363 }
11364
11365 // Finally, strip any protocol specifier from the URL
11366 url = urlParts[0].Trim();
11367 int idx = url.IndexOf(" HTTP/");
11368 if (idx != -1)
11369 url = url.Substring(0, idx);
11370 }
11371
10715 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11372 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10716 Regex r = new Regex(authregex); 11373 Regex r = new Regex(authregex);
10717 int[] gnums = r.GetGroupNumbers(); 11374 int[] gnums = r.GetGroupNumbers();
10718 Match m = r.Match(url); 11375 Match m = r.Match(url);
10719 if (m.Success) { 11376 if (m.Success)
10720 for (int i = 1; i < gnums.Length; i++) { 11377 {
11378 for (int i = 1; i < gnums.Length; i++)
11379 {
10721 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11380 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10722 //CaptureCollection cc = g.Captures; 11381 //CaptureCollection cc = g.Captures;
10723 } 11382 }
10724 if (m.Groups.Count == 5) { 11383 if (m.Groups.Count == 5)
11384 {
10725 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11385 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10726 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11386 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10727 } 11387 }
@@ -10924,6 +11584,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10924 11584
10925 LSL_List ret = new LSL_List(); 11585 LSL_List ret = new LSL_List();
10926 UUID key = new UUID(); 11586 UUID key = new UUID();
11587
11588
10927 if (UUID.TryParse(id, out key)) 11589 if (UUID.TryParse(id, out key))
10928 { 11590 {
10929 ScenePresence av = World.GetScenePresence(key); 11591 ScenePresence av = World.GetScenePresence(key);
@@ -10941,13 +11603,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10941 ret.Add(new LSL_String("")); 11603 ret.Add(new LSL_String(""));
10942 break; 11604 break;
10943 case ScriptBaseClass.OBJECT_POS: 11605 case ScriptBaseClass.OBJECT_POS:
10944 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11606 Vector3 avpos;
11607
11608 if (av.ParentID != 0 && av.ParentPart != null)
11609 {
11610 avpos = av.OffsetPosition;
11611
11612 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11613 avpos -= sitOffset;
11614
11615 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11616 }
11617 else
11618 avpos = av.AbsolutePosition;
11619
11620 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10945 break; 11621 break;
10946 case ScriptBaseClass.OBJECT_ROT: 11622 case ScriptBaseClass.OBJECT_ROT:
10947 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 11623 Quaternion avrot = av.Rotation;
11624 if (av.ParentID != 0 && av.ParentPart != null)
11625 {
11626 avrot = av.ParentPart.GetWorldRotation() * avrot;
11627 }
11628 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10948 break; 11629 break;
10949 case ScriptBaseClass.OBJECT_VELOCITY: 11630 case ScriptBaseClass.OBJECT_VELOCITY:
10950 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11631 Vector3 avvel = av.Velocity;
11632 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10951 break; 11633 break;
10952 case ScriptBaseClass.OBJECT_OWNER: 11634 case ScriptBaseClass.OBJECT_OWNER:
10953 ret.Add(new LSL_String(id)); 11635 ret.Add(new LSL_String(id));
@@ -11032,11 +11714,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11032 case ScriptBaseClass.OBJECT_NAME: 11714 case ScriptBaseClass.OBJECT_NAME:
11033 ret.Add(new LSL_String(obj.Name)); 11715 ret.Add(new LSL_String(obj.Name));
11034 break; 11716 break;
11035 case ScriptBaseClass.OBJECT_DESC: 11717 case ScriptBaseClass.OBJECT_DESC:
11036 ret.Add(new LSL_String(obj.Description)); 11718 ret.Add(new LSL_String(obj.Description));
11037 break; 11719 break;
11038 case ScriptBaseClass.OBJECT_POS: 11720 case ScriptBaseClass.OBJECT_POS:
11039 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11721 Vector3 opos = obj.AbsolutePosition;
11722 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
11040 break; 11723 break;
11041 case ScriptBaseClass.OBJECT_ROT: 11724 case ScriptBaseClass.OBJECT_ROT:
11042 { 11725 {
@@ -11086,9 +11769,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11086 // The value returned in SL for normal prims is prim count 11769 // The value returned in SL for normal prims is prim count
11087 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11770 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
11088 break; 11771 break;
11089 // The following 3 costs I have intentionaly coded to return zero. They are part of 11772
11090 // "Land Impact" calculations. These calculations are probably not applicable 11773 // costs below may need to be diferent for root parts, need to check
11091 // to OpenSim and are not yet complete in SL
11092 case ScriptBaseClass.OBJECT_SERVER_COST: 11774 case ScriptBaseClass.OBJECT_SERVER_COST:
11093 // The linden calculation is here 11775 // The linden calculation is here
11094 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11776 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -11096,16 +11778,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11096 ret.Add(new LSL_Float(0)); 11778 ret.Add(new LSL_Float(0));
11097 break; 11779 break;
11098 case ScriptBaseClass.OBJECT_STREAMING_COST: 11780 case ScriptBaseClass.OBJECT_STREAMING_COST:
11099 // The linden calculation is here 11781 // The value returned in SL for normal prims is prim count * 0.06
11100 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11782 ret.Add(new LSL_Float(obj.StreamingCost));
11101 // The value returned in SL for normal prims looks like the prim count * 0.06
11102 ret.Add(new LSL_Float(0));
11103 break; 11783 break;
11104 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11784 case ScriptBaseClass.OBJECT_PHYSICS_COST:
11105 // The linden calculation is here 11785 // The value returned in SL for normal prims is prim count
11106 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11786 ret.Add(new LSL_Float(obj.PhysicsCost));
11107 // The value returned in SL for normal prims looks like the prim count
11108 ret.Add(new LSL_Float(0));
11109 break; 11787 break;
11110 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11788 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
11111 ret.Add(new LSL_Float(0)); 11789 ret.Add(new LSL_Float(0));
@@ -11364,15 +12042,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11364 return result; 12042 return result;
11365 } 12043 }
11366 12044
11367 public void print(string str) 12045 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
11368 { 12046 {
11369 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 12047 List<SceneObjectPart> parts = GetLinkParts(link);
11370 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 12048 if (parts.Count < 1)
11371 if (ossl != null) 12049 return 0;
11372 { 12050
11373 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12051 return GetNumberOfSides(parts[0]);
11374 m_log.Info("LSL print():" + str);
11375 }
11376 } 12052 }
11377 12053
11378 private string Name2Username(string name) 12054 private string Name2Username(string name)
@@ -11417,7 +12093,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11417 12093
11418 return rq.ToString(); 12094 return rq.ToString();
11419 } 12095 }
11420 12096/*
12097 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12098 {
12099 m_SayShoutCount = 0;
12100 }
12101*/
11421 private struct Tri 12102 private struct Tri
11422 { 12103 {
11423 public Vector3 p1; 12104 public Vector3 p1;
@@ -11566,9 +12247,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11566 12247
11567 ContactResult result = new ContactResult (); 12248 ContactResult result = new ContactResult ();
11568 result.ConsumerID = group.LocalId; 12249 result.ConsumerID = group.LocalId;
11569 result.Depth = intersection.distance; 12250// result.Depth = intersection.distance;
11570 result.Normal = intersection.normal; 12251 result.Normal = intersection.normal;
11571 result.Pos = intersection.ipoint; 12252 result.Pos = intersection.ipoint;
12253 result.Depth = Vector3.Mag(rayStart - result.Pos);
11572 12254
11573 contacts.Add(result); 12255 contacts.Add(result);
11574 }); 12256 });
@@ -11701,6 +12383,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11701 12383
11702 return contacts[0]; 12384 return contacts[0];
11703 } 12385 }
12386/*
12387 // not done:
12388 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12389 {
12390 ContactResult[] contacts = null;
12391 World.ForEachSOG(delegate(SceneObjectGroup group)
12392 {
12393 if (m_host.ParentGroup == group)
12394 return;
12395
12396 if (group.IsAttachment)
12397 return;
12398
12399 if(group.RootPart.PhysActor != null)
12400 return;
12401
12402 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12403 });
12404 return contacts;
12405 }
12406*/
11704 12407
11705 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12408 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11706 { 12409 {
@@ -11824,18 +12527,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11824 } 12527 }
11825 } 12528 }
11826 12529
12530 // Double check this
11827 if (checkTerrain) 12531 if (checkTerrain)
11828 { 12532 {
11829 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12533 bool skipGroundCheck = false;
11830 if (groundContact != null) 12534
11831 results.Add((ContactResult)groundContact); 12535 foreach (ContactResult c in results)
12536 {
12537 if (c.ConsumerID == 0) // Physics gave us a ground collision
12538 skipGroundCheck = true;
12539 }
12540
12541 if (!skipGroundCheck)
12542 {
12543 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12544 if (groundContact != null)
12545 results.Add((ContactResult)groundContact);
12546 }
11832 } 12547 }
11833 12548
11834 results.Sort(delegate(ContactResult a, ContactResult b) 12549 results.Sort(delegate(ContactResult a, ContactResult b)
11835 { 12550 {
11836 return a.Depth.CompareTo(b.Depth); 12551 return a.Depth.CompareTo(b.Depth);
11837 }); 12552 });
11838 12553
11839 int values = 0; 12554 int values = 0;
11840 SceneObjectGroup thisgrp = m_host.ParentGroup; 12555 SceneObjectGroup thisgrp = m_host.ParentGroup;
11841 12556
@@ -11928,7 +12643,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11928 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12643 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11929 if (!isAccount) return 0; 12644 if (!isAccount) return 0;
11930 if (estate.HasAccess(id)) return 1; 12645 if (estate.HasAccess(id)) return 1;
11931 if (estate.IsBanned(id)) 12646 if (estate.IsBanned(id, World.GetUserFlags(id)))
11932 estate.RemoveBan(id); 12647 estate.RemoveBan(id);
11933 estate.AddEstateUser(id); 12648 estate.AddEstateUser(id);
11934 break; 12649 break;
@@ -11947,14 +12662,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11947 break; 12662 break;
11948 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12663 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11949 if (!isAccount) return 0; 12664 if (!isAccount) return 0;
11950 if (estate.IsBanned(id)) return 1; 12665 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11951 EstateBan ban = new EstateBan(); 12666 EstateBan ban = new EstateBan();
11952 ban.EstateID = estate.EstateID; 12667 ban.EstateID = estate.EstateID;
11953 ban.BannedUserID = id; 12668 ban.BannedUserID = id;
11954 estate.AddBan(ban); 12669 estate.AddBan(ban);
11955 break; 12670 break;
11956 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12671 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11957 if (!isAccount || !estate.IsBanned(id)) return 0; 12672 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11958 estate.RemoveBan(id); 12673 estate.RemoveBan(id);
11959 break; 12674 break;
11960 default: return 0; 12675 default: return 0;
@@ -12019,13 +12734,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12019 public void llCollisionSprite(string impact_sprite) 12734 public void llCollisionSprite(string impact_sprite)
12020 { 12735 {
12021 m_host.AddScriptLPS(1); 12736 m_host.AddScriptLPS(1);
12022 NotImplemented("llCollisionSprite"); 12737 // Viewer 2.0 broke this and it's likely LL has no intention
12738 // of fixing it. Therefore, letting this be a NOP seems appropriate.
12023 } 12739 }
12024 12740
12025 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12741 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
12026 { 12742 {
12027 m_host.AddScriptLPS(1); 12743 m_host.AddScriptLPS(1);
12028 NotImplemented("llGodLikeRezObject"); 12744
12745 if (!World.Permissions.IsGod(m_host.OwnerID))
12746 NotImplemented("llGodLikeRezObject");
12747
12748 AssetBase rezAsset = World.AssetService.Get(inventory);
12749 if (rezAsset == null)
12750 {
12751 llSay(0, "Asset not found");
12752 return;
12753 }
12754
12755 SceneObjectGroup group = null;
12756
12757 try
12758 {
12759 string xmlData = Utils.BytesToString(rezAsset.Data);
12760 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12761 }
12762 catch
12763 {
12764 llSay(0, "Asset not found");
12765 return;
12766 }
12767
12768 if (group == null)
12769 {
12770 llSay(0, "Asset not found");
12771 return;
12772 }
12773
12774 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12775 group.RootPart.AttachOffset = group.AbsolutePosition;
12776
12777 group.ResetIDs();
12778
12779 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12780 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12781 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12782 group.ScheduleGroupForFullUpdate();
12783
12784 // objects rezzed with this method are die_at_edge by default.
12785 group.RootPart.SetDieAtEdge(true);
12786
12787 group.ResumeScripts();
12788
12789 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12790 "object_rez", new Object[] {
12791 new LSL_String(
12792 group.RootPart.UUID.ToString()) },
12793 new DetectParams[0]));
12029 } 12794 }
12030 12795
12031 public LSL_String llTransferLindenDollars(string destination, int amount) 12796 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -12077,7 +12842,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12077 } 12842 }
12078 12843
12079 bool result = money.ObjectGiveMoney( 12844 bool result = money.ObjectGiveMoney(
12080 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12845 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn);
12081 12846
12082 if (result) 12847 if (result)
12083 { 12848 {
@@ -12102,6 +12867,610 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12102 } 12867 }
12103 12868
12104 #endregion 12869 #endregion
12870
12871 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12872 {
12873 SceneObjectGroup group = m_host.ParentGroup;
12874
12875 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12876 return;
12877 if (group.IsAttachment)
12878 return;
12879
12880 if (frames.Data.Length > 0) // We are getting a new motion
12881 {
12882 if (group.RootPart.KeyframeMotion != null)
12883 group.RootPart.KeyframeMotion.Delete();
12884 group.RootPart.KeyframeMotion = null;
12885
12886 int idx = 0;
12887
12888 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12889 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12890
12891 while (idx < options.Data.Length)
12892 {
12893 int option = (int)options.GetLSLIntegerItem(idx++);
12894 int remain = options.Data.Length - idx;
12895
12896 switch (option)
12897 {
12898 case ScriptBaseClass.KFM_MODE:
12899 if (remain < 1)
12900 break;
12901 int modeval = (int)options.GetLSLIntegerItem(idx++);
12902 switch(modeval)
12903 {
12904 case ScriptBaseClass.KFM_FORWARD:
12905 mode = KeyframeMotion.PlayMode.Forward;
12906 break;
12907 case ScriptBaseClass.KFM_REVERSE:
12908 mode = KeyframeMotion.PlayMode.Reverse;
12909 break;
12910 case ScriptBaseClass.KFM_LOOP:
12911 mode = KeyframeMotion.PlayMode.Loop;
12912 break;
12913 case ScriptBaseClass.KFM_PING_PONG:
12914 mode = KeyframeMotion.PlayMode.PingPong;
12915 break;
12916 }
12917 break;
12918 case ScriptBaseClass.KFM_DATA:
12919 if (remain < 1)
12920 break;
12921 int dataval = (int)options.GetLSLIntegerItem(idx++);
12922 data = (KeyframeMotion.DataFormat)dataval;
12923 break;
12924 }
12925 }
12926
12927 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12928
12929 idx = 0;
12930
12931 int elemLength = 2;
12932 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12933 elemLength = 3;
12934
12935 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12936 while (idx < frames.Data.Length)
12937 {
12938 int remain = frames.Data.Length - idx;
12939
12940 if (remain < elemLength)
12941 break;
12942
12943 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12944 frame.Position = null;
12945 frame.Rotation = null;
12946
12947 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12948 {
12949 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12950 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12951 }
12952 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12953 {
12954 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12955 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12956 q.Normalize();
12957 frame.Rotation = q;
12958 }
12959
12960 float tempf = (float)frames.GetLSLFloatItem(idx++);
12961 frame.TimeMS = (int)(tempf * 1000.0f);
12962
12963 keyframes.Add(frame);
12964 }
12965
12966 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12967 group.RootPart.KeyframeMotion.Start();
12968 }
12969 else
12970 {
12971 if (group.RootPart.KeyframeMotion == null)
12972 return;
12973
12974 if (options.Data.Length == 0)
12975 {
12976 group.RootPart.KeyframeMotion.Stop();
12977 return;
12978 }
12979
12980 int code = (int)options.GetLSLIntegerItem(0);
12981
12982 int idx = 0;
12983
12984 while (idx < options.Data.Length)
12985 {
12986 int option = (int)options.GetLSLIntegerItem(idx++);
12987 int remain = options.Data.Length - idx;
12988
12989 switch (option)
12990 {
12991 case ScriptBaseClass.KFM_COMMAND:
12992 int cmd = (int)options.GetLSLIntegerItem(idx++);
12993 switch (cmd)
12994 {
12995 case ScriptBaseClass.KFM_CMD_PLAY:
12996 group.RootPart.KeyframeMotion.Start();
12997 break;
12998 case ScriptBaseClass.KFM_CMD_STOP:
12999 group.RootPart.KeyframeMotion.Stop();
13000 break;
13001 case ScriptBaseClass.KFM_CMD_PAUSE:
13002 group.RootPart.KeyframeMotion.Pause();
13003 break;
13004 }
13005 break;
13006 }
13007 }
13008 }
13009 }
13010
13011 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
13012 {
13013 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
13014
13015 int idx = 0;
13016 int idxStart = 0;
13017
13018 bool positionChanged = false;
13019 Vector3 finalPos = Vector3.Zero;
13020
13021 try
13022 {
13023 while (idx < rules.Length)
13024 {
13025 ++rulesParsed;
13026 int code = rules.GetLSLIntegerItem(idx++);
13027
13028 int remain = rules.Length - idx;
13029 idxStart = idx;
13030
13031 switch (code)
13032 {
13033 case (int)ScriptBaseClass.PRIM_POSITION:
13034 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13035 {
13036 if (remain < 1)
13037 return null;
13038
13039 LSL_Vector v;
13040 v = rules.GetVector3Item(idx++);
13041
13042 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
13043 if (part == null)
13044 break;
13045
13046 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
13047 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
13048 if (part.LinkNum > 1)
13049 {
13050 localRot = GetPartLocalRot(part);
13051 localPos = GetPartLocalPos(part);
13052 }
13053
13054 v -= localPos;
13055 v /= localRot;
13056
13057 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
13058
13059 v = v + 2 * sitOffset;
13060
13061 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
13062 av.SendAvatarDataToAllAgents();
13063
13064 }
13065 break;
13066
13067 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13068 case (int)ScriptBaseClass.PRIM_ROTATION:
13069 {
13070 if (remain < 1)
13071 return null;
13072
13073 LSL_Rotation r;
13074 r = rules.GetQuaternionItem(idx++);
13075
13076 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
13077 if (part == null)
13078 break;
13079
13080 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
13081 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
13082
13083 if (part.LinkNum > 1)
13084 localRot = GetPartLocalRot(part);
13085
13086 r = r * llGetRootRotation() / localRot;
13087 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
13088 av.SendAvatarDataToAllAgents();
13089 }
13090 break;
13091
13092 // parse rest doing nothing but number of parameters error check
13093 case (int)ScriptBaseClass.PRIM_SIZE:
13094 case (int)ScriptBaseClass.PRIM_MATERIAL:
13095 case (int)ScriptBaseClass.PRIM_PHANTOM:
13096 case (int)ScriptBaseClass.PRIM_PHYSICS:
13097 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
13098 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13099 case (int)ScriptBaseClass.PRIM_NAME:
13100 case (int)ScriptBaseClass.PRIM_DESC:
13101 if (remain < 1)
13102 return null;
13103 idx++;
13104 break;
13105
13106 case (int)ScriptBaseClass.PRIM_GLOW:
13107 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13108 case (int)ScriptBaseClass.PRIM_TEXGEN:
13109 if (remain < 2)
13110 return null;
13111 idx += 2;
13112 break;
13113
13114 case (int)ScriptBaseClass.PRIM_TYPE:
13115 if (remain < 3)
13116 return null;
13117 code = (int)rules.GetLSLIntegerItem(idx++);
13118 remain = rules.Length - idx;
13119 switch (code)
13120 {
13121 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
13122 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
13123 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
13124 if (remain < 6)
13125 return null;
13126 idx += 6;
13127 break;
13128
13129 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
13130 if (remain < 5)
13131 return null;
13132 idx += 5;
13133 break;
13134
13135 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
13136 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
13137 case (int)ScriptBaseClass.PRIM_TYPE_RING:
13138 if (remain < 11)
13139 return null;
13140 idx += 11;
13141 break;
13142
13143 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
13144 if (remain < 2)
13145 return null;
13146 idx += 2;
13147 break;
13148 }
13149 break;
13150
13151 case (int)ScriptBaseClass.PRIM_COLOR:
13152 case (int)ScriptBaseClass.PRIM_TEXT:
13153 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13154 case (int)ScriptBaseClass.PRIM_OMEGA:
13155 if (remain < 3)
13156 return null;
13157 idx += 3;
13158 break;
13159
13160 case (int)ScriptBaseClass.PRIM_TEXTURE:
13161 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13162 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
13163 if (remain < 5)
13164 return null;
13165 idx += 5;
13166 break;
13167
13168 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13169 if (remain < 7)
13170 return null;
13171
13172 idx += 7;
13173 break;
13174
13175 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13176 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13177 return null;
13178
13179 return rules.GetSublist(idx, -1);
13180 }
13181 }
13182 }
13183 catch (InvalidCastException e)
13184 {
13185 ShoutError(string.Format(
13186 "{0} error running rule #{1}: arg #{2} ",
13187 originFunc, rulesParsed, idx - idxStart) + e.Message);
13188 }
13189 finally
13190 {
13191 if (positionChanged)
13192 {
13193 av.OffsetPosition = finalPos;
13194// av.SendAvatarDataToAllAgents();
13195 av.SendTerseUpdateToAllClients();
13196 positionChanged = false;
13197 }
13198 }
13199 return null;
13200 }
13201
13202 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13203 {
13204 // avatars case
13205 // replies as SL wiki
13206
13207// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13208 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13209
13210 int idx = 0;
13211 while (idx < rules.Length)
13212 {
13213 int code = (int)rules.GetLSLIntegerItem(idx++);
13214 int remain = rules.Length - idx;
13215
13216 switch (code)
13217 {
13218 case (int)ScriptBaseClass.PRIM_MATERIAL:
13219 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13220 break;
13221
13222 case (int)ScriptBaseClass.PRIM_PHYSICS:
13223 res.Add(new LSL_Integer(0));
13224 break;
13225
13226 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13227 res.Add(new LSL_Integer(0));
13228 break;
13229
13230 case (int)ScriptBaseClass.PRIM_PHANTOM:
13231 res.Add(new LSL_Integer(0));
13232 break;
13233
13234 case (int)ScriptBaseClass.PRIM_POSITION:
13235
13236 Vector3 pos = avatar.OffsetPosition;
13237
13238 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13239 pos -= sitOffset;
13240
13241 if( sitPart != null)
13242 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13243
13244 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13245 break;
13246
13247 case (int)ScriptBaseClass.PRIM_SIZE:
13248 // as in llGetAgentSize above
13249// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13250 Vector3 s = avatar.Appearance.AvatarSize;
13251 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13252
13253 break;
13254
13255 case (int)ScriptBaseClass.PRIM_ROTATION:
13256 Quaternion rot = avatar.Rotation;
13257 if (sitPart != null)
13258 {
13259 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13260 }
13261
13262 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13263 break;
13264
13265 case (int)ScriptBaseClass.PRIM_TYPE:
13266 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13267 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13268 res.Add(new LSL_Vector(0f,1.0f,0f));
13269 res.Add(new LSL_Float(0.0f));
13270 res.Add(new LSL_Vector(0, 0, 0));
13271 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13272 res.Add(new LSL_Vector(0, 0, 0));
13273 break;
13274
13275 case (int)ScriptBaseClass.PRIM_TEXTURE:
13276 if (remain < 1)
13277 return null;
13278
13279 int face = (int)rules.GetLSLIntegerItem(idx++);
13280 if (face == ScriptBaseClass.ALL_SIDES)
13281 {
13282 for (face = 0; face < 21; face++)
13283 {
13284 res.Add(new LSL_String(""));
13285 res.Add(new LSL_Vector(0,0,0));
13286 res.Add(new LSL_Vector(0,0,0));
13287 res.Add(new LSL_Float(0.0));
13288 }
13289 }
13290 else
13291 {
13292 if (face >= 0 && face < 21)
13293 {
13294 res.Add(new LSL_String(""));
13295 res.Add(new LSL_Vector(0,0,0));
13296 res.Add(new LSL_Vector(0,0,0));
13297 res.Add(new LSL_Float(0.0));
13298 }
13299 }
13300 break;
13301
13302 case (int)ScriptBaseClass.PRIM_COLOR:
13303 if (remain < 1)
13304 return null;
13305
13306 face = (int)rules.GetLSLIntegerItem(idx++);
13307
13308 if (face == ScriptBaseClass.ALL_SIDES)
13309 {
13310 for (face = 0; face < 21; face++)
13311 {
13312 res.Add(new LSL_Vector(0,0,0));
13313 res.Add(new LSL_Float(0));
13314 }
13315 }
13316 else
13317 {
13318 res.Add(new LSL_Vector(0,0,0));
13319 res.Add(new LSL_Float(0));
13320 }
13321 break;
13322
13323 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13324 if (remain < 1)
13325 return null;
13326 face = (int)rules.GetLSLIntegerItem(idx++);
13327
13328 if (face == ScriptBaseClass.ALL_SIDES)
13329 {
13330 for (face = 0; face < 21; face++)
13331 {
13332 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13333 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13334 }
13335 }
13336 else
13337 {
13338 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13339 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13340 }
13341 break;
13342
13343 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13344 if (remain < 1)
13345 return null;
13346 face = (int)rules.GetLSLIntegerItem(idx++);
13347
13348 if (face == ScriptBaseClass.ALL_SIDES)
13349 {
13350 for (face = 0; face < 21; face++)
13351 {
13352 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13353 }
13354 }
13355 else
13356 {
13357 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13358 }
13359 break;
13360
13361 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13362 res.Add(new LSL_Integer(0));
13363 res.Add(new LSL_Integer(0));// softness
13364 res.Add(new LSL_Float(0.0f)); // gravity
13365 res.Add(new LSL_Float(0.0f)); // friction
13366 res.Add(new LSL_Float(0.0f)); // wind
13367 res.Add(new LSL_Float(0.0f)); // tension
13368 res.Add(new LSL_Vector(0f,0f,0f));
13369 break;
13370
13371 case (int)ScriptBaseClass.PRIM_TEXGEN:
13372 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13373 if (remain < 1)
13374 return null;
13375 face = (int)rules.GetLSLIntegerItem(idx++);
13376
13377 if (face == ScriptBaseClass.ALL_SIDES)
13378 {
13379 for (face = 0; face < 21; face++)
13380 {
13381 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13382 }
13383 }
13384 else
13385 {
13386 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13387 }
13388 break;
13389
13390 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13391 res.Add(new LSL_Integer(0));
13392 res.Add(new LSL_Vector(0f,0f,0f));
13393 res.Add(new LSL_Float(0f)); // intensity
13394 res.Add(new LSL_Float(0f)); // radius
13395 res.Add(new LSL_Float(0f)); // falloff
13396 break;
13397
13398 case (int)ScriptBaseClass.PRIM_GLOW:
13399 if (remain < 1)
13400 return null;
13401 face = (int)rules.GetLSLIntegerItem(idx++);
13402
13403 if (face == ScriptBaseClass.ALL_SIDES)
13404 {
13405 for (face = 0; face < 21; face++)
13406 {
13407 res.Add(new LSL_Float(0f));
13408 }
13409 }
13410 else
13411 {
13412 res.Add(new LSL_Float(0f));
13413 }
13414 break;
13415
13416 case (int)ScriptBaseClass.PRIM_TEXT:
13417 res.Add(new LSL_String(""));
13418 res.Add(new LSL_Vector(0f,0f,0f));
13419 res.Add(new LSL_Float(1.0f));
13420 break;
13421
13422 case (int)ScriptBaseClass.PRIM_NAME:
13423 res.Add(new LSL_String(avatar.Name));
13424 break;
13425
13426 case (int)ScriptBaseClass.PRIM_DESC:
13427 res.Add(new LSL_String(""));
13428 break;
13429
13430 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13431 Quaternion lrot = avatar.Rotation;
13432
13433 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13434 {
13435 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13436 }
13437 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13438 break;
13439
13440 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13441 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13442 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13443 lpos -= lsitOffset;
13444
13445 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13446 {
13447 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13448 }
13449 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13450 break;
13451
13452 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13453 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13454 return null;
13455
13456 return rules.GetSublist(idx, -1);
13457 }
13458 }
13459
13460 return null;
13461 }
13462
13463 public void llSetContentType(LSL_Key id, LSL_Integer content_type)
13464 {
13465 if (m_UrlModule != null)
13466 {
13467 string type = "text.plain";
13468 if (content_type == (int)ScriptBaseClass.CONTENT_TYPE_HTML)
13469 type = "text/html";
13470
13471 m_UrlModule.HttpContentType(new UUID(id),type);
13472 }
13473 }
12105 } 13474 }
12106 13475
12107 public class NotecardCache 13476 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 21bae27..bd776b6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -136,7 +136,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
137 137
138 Type returntype = m_comms.LookupReturnType(fname); 138 Type returntype = m_comms.LookupReturnType(fname);
139 if (returntype != typeof(string)) 139 if (returntype != typeof(void))
140 MODError(String.Format("return type mismatch for {0}",fname)); 140 MODError(String.Format("return type mismatch for {0}",fname));
141 141
142 modInvoke(fname,parms); 142 modInvoke(fname,parms);
@@ -329,6 +329,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 if (result != null) 329 if (result != null)
330 return result; 330 return result;
331 331
332 Type returntype = m_comms.LookupReturnType(fname);
333 if (returntype == typeof(void))
334 return null;
335
332 MODError(String.Format("Invocation of {0} failed; null return value",fname)); 336 MODError(String.Format("Invocation of {0} failed; null return value",fname));
333 } 337 }
334 catch (Exception e) 338 catch (Exception e)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 415166a..f4e4f44 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -139,6 +139,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
139 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 139 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
140 internal float m_ScriptDelayFactor = 1.0f; 140 internal float m_ScriptDelayFactor = 1.0f;
141 internal float m_ScriptDistanceFactor = 1.0f; 141 internal float m_ScriptDistanceFactor = 1.0f;
142 internal bool m_debuggerSafe = false;
142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 143 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
143 144
144 protected IUrlModule m_UrlModule = null; 145 protected IUrlModule m_UrlModule = null;
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
149 m_ScriptEngine = scriptEngine; 150 m_ScriptEngine = scriptEngine;
150 m_host = host; 151 m_host = host;
151 m_item = item; 152 m_item = item;
153 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
152 154
153 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 155 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
154 156
@@ -212,7 +214,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
212 214
213 internal void OSSLError(string msg) 215 internal void OSSLError(string msg)
214 { 216 {
215 throw new ScriptException("OSSL Runtime Error: " + msg); 217 if (m_debuggerSafe)
218 {
219 OSSLShoutError(msg);
220 }
221 else
222 {
223 throw new ScriptException("OSSL Runtime Error: " + msg);
224 }
216 } 225 }
217 226
218 /// <summary> 227 /// <summary>
@@ -931,18 +940,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
931 if (target != null) 940 if (target != null)
932 { 941 {
933 UUID animID=UUID.Zero; 942 UUID animID=UUID.Zero;
934 lock (m_host.TaskInventory) 943 m_host.TaskInventory.LockItemsForRead(true);
944 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
935 { 945 {
936 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 946 if (inv.Value.Name == animation)
937 { 947 {
938 if (inv.Value.Name == animation) 948 if (inv.Value.Type == (int)AssetType.Animation)
939 { 949 animID = inv.Value.AssetID;
940 if (inv.Value.Type == (int)AssetType.Animation) 950 continue;
941 animID = inv.Value.AssetID;
942 continue;
943 }
944 } 951 }
945 } 952 }
953 m_host.TaskInventory.LockItemsForRead(false);
946 if (animID == UUID.Zero) 954 if (animID == UUID.Zero)
947 target.Animator.AddAnimation(animation, m_host.UUID); 955 target.Animator.AddAnimation(animation, m_host.UUID);
948 else 956 else
@@ -983,6 +991,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
983 else 991 else
984 animID = UUID.Zero; 992 animID = UUID.Zero;
985 } 993 }
994 m_host.TaskInventory.LockItemsForRead(false);
986 995
987 if (animID == UUID.Zero) 996 if (animID == UUID.Zero)
988 target.Animator.RemoveAnimation(animation); 997 target.Animator.RemoveAnimation(animation);
@@ -1645,7 +1654,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1645 } 1654 }
1646 } 1655 }
1647 1656
1648 public Object osParseJSONNew(string JSON) 1657 private Object osParseJSONNew(string JSON)
1649 { 1658 {
1650 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew"); 1659 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew");
1651 1660
@@ -1847,15 +1856,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1847 { 1856 {
1848 UUID assetID = UUID.Zero; 1857 UUID assetID = UUID.Zero;
1849 1858
1850 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1859 bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID);
1860
1861 if (!notecardNameIsUUID)
1851 { 1862 {
1852 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1863 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1853 {
1854 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1855 {
1856 assetID = item.AssetID;
1857 }
1858 }
1859 } 1864 }
1860 1865
1861 if (assetID == UUID.Zero) 1866 if (assetID == UUID.Zero)
@@ -1866,7 +1871,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1866 AssetBase a = World.AssetService.Get(assetID.ToString()); 1871 AssetBase a = World.AssetService.Get(assetID.ToString());
1867 1872
1868 if (a == null) 1873 if (a == null)
1869 return UUID.Zero; 1874 {
1875 // Whoops, it's still possible here that the notecard name was properly
1876 // formatted like a UUID but isn't an asset UUID so lets look it up by name after all
1877 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1878 if (assetID == UUID.Zero)
1879 return UUID.Zero;
1880
1881 if (!NotecardCache.IsCached(assetID))
1882 {
1883 a = World.AssetService.Get(assetID.ToString());
1884
1885 if (a == null)
1886 {
1887 return UUID.Zero;
1888 }
1889 }
1890 }
1870 1891
1871 string data = Encoding.UTF8.GetString(a.Data); 1892 string data = Encoding.UTF8.GetString(a.Data);
1872 NotecardCache.Cache(assetID, data); 1893 NotecardCache.Cache(assetID, data);
@@ -1874,6 +1895,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1874 1895
1875 return assetID; 1896 return assetID;
1876 } 1897 }
1898 protected UUID SearchTaskInventoryForAssetId(string name)
1899 {
1900 UUID assetId = UUID.Zero;
1901 m_host.TaskInventory.LockItemsForRead(true);
1902 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1903 {
1904 if (item.Type == 7 && item.Name == name)
1905 {
1906 assetId = item.AssetID;
1907 }
1908 }
1909 m_host.TaskInventory.LockItemsForRead(false);
1910 return assetId;
1911 }
1877 1912
1878 /// <summary> 1913 /// <summary>
1879 /// Directly get an entire notecard at once. 1914 /// Directly get an entire notecard at once.
@@ -2351,7 +2386,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2351 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2386 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2352 m_host.AddScriptLPS(1); 2387 m_host.AddScriptLPS(1);
2353 2388
2354 return NpcCreate(firstname, lastname, position, notecard, false, false); 2389 return NpcCreate(firstname, lastname, position, notecard, true, false);
2355 } 2390 }
2356 2391
2357 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2392 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2362,24 +2397,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2362 return NpcCreate( 2397 return NpcCreate(
2363 firstname, lastname, position, notecard, 2398 firstname, lastname, position, notecard,
2364 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2399 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2365 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2400 false);
2401// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2366 } 2402 }
2367 2403
2368 private LSL_Key NpcCreate( 2404 private LSL_Key NpcCreate(
2369 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2405 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2370 { 2406 {
2407 if (!owned)
2408 OSSLError("Unowned NPCs are unsupported");
2409
2410 string groupTitle = String.Empty;
2411
2412 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2413 return new LSL_Key(UUID.Zero.ToString());
2414
2415 if (firstname != String.Empty || lastname != String.Empty)
2416 {
2417 if (firstname != "Shown outfit:")
2418 groupTitle = "- NPC -";
2419 }
2420
2371 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2421 INPCModule module = World.RequestModuleInterface<INPCModule>();
2372 if (module != null) 2422 if (module != null)
2373 { 2423 {
2374 AvatarAppearance appearance = null; 2424 AvatarAppearance appearance = null;
2375 2425
2376 UUID id; 2426// UUID id;
2377 if (UUID.TryParse(notecard, out id)) 2427// if (UUID.TryParse(notecard, out id))
2378 { 2428// {
2379 ScenePresence clonePresence = World.GetScenePresence(id); 2429// ScenePresence clonePresence = World.GetScenePresence(id);
2380 if (clonePresence != null) 2430// if (clonePresence != null)
2381 appearance = clonePresence.Appearance; 2431// appearance = clonePresence.Appearance;
2382 } 2432// }
2383 2433
2384 if (appearance == null) 2434 if (appearance == null)
2385 { 2435 {
@@ -2387,9 +2437,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2387 2437
2388 if (appearanceSerialized != null) 2438 if (appearanceSerialized != null)
2389 { 2439 {
2390 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2440 try
2391 appearance = new AvatarAppearance(); 2441 {
2392 appearance.Unpack(appearanceOsd); 2442 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2443 appearance = new AvatarAppearance();
2444 appearance.Unpack(appearanceOsd);
2445 }
2446 catch
2447 {
2448 return UUID.Zero.ToString();
2449 }
2393 } 2450 }
2394 else 2451 else
2395 { 2452 {
@@ -2408,6 +2465,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2408 World, 2465 World,
2409 appearance); 2466 appearance);
2410 2467
2468 ScenePresence sp;
2469 if (World.TryGetScenePresence(x, out sp))
2470 {
2471 sp.Grouptitle = groupTitle;
2472 sp.SendAvatarDataToAllAgents();
2473 }
2411 return new LSL_Key(x.ToString()); 2474 return new LSL_Key(x.ToString());
2412 } 2475 }
2413 2476
@@ -2705,16 +2768,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2705 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2768 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2706 m_host.AddScriptLPS(1); 2769 m_host.AddScriptLPS(1);
2707 2770
2708 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2771 ManualResetEvent ev = new ManualResetEvent(false);
2709 if (module != null)
2710 {
2711 UUID npcId = new UUID(npc.m_string);
2712 2772
2713 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2773 Util.FireAndForget(delegate(object x) {
2714 return; 2774 try
2775 {
2776 INPCModule module = World.RequestModuleInterface<INPCModule>();
2777 if (module != null)
2778 {
2779 UUID npcId = new UUID(npc.m_string);
2715 2780
2716 module.DeleteNPC(npcId, World); 2781 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2717 } 2782 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2783 {
2784 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2785 return;
2786 }
2787
2788 module.DeleteNPC(npcId, World);
2789 }
2790 }
2791 finally
2792 {
2793 ev.Set();
2794 }
2795 });
2796 ev.WaitOne();
2718 } 2797 }
2719 2798
2720 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2799 public void osNpcPlayAnimation(LSL_Key npc, string animation)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 88ab515..a47e452 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -93,7 +93,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
93 private const int AGENT = 1; 93 private const int AGENT = 1;
94 private const int AGENT_BY_USERNAME = 0x10; 94 private const int AGENT_BY_USERNAME = 0x10;
95 private const int NPC = 0x20; 95 private const int NPC = 0x20;
96 private const int OS_NPC = 0x01000000;
97 private const int ACTIVE = 2; 96 private const int ACTIVE = 2;
98 private const int PASSIVE = 4; 97 private const int PASSIVE = 4;
99 private const int SCRIPTED = 8; 98 private const int SCRIPTED = 8;
@@ -240,7 +239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
240 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 239 List<SensedEntity> sensedEntities = new List<SensedEntity>();
241 240
242 // Is the sensor type is AGENT and not SCRIPTED then include agents 241 // Is the sensor type is AGENT and not SCRIPTED then include agents
243 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 242 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
244 { 243 {
245 sensedEntities.AddRange(doAgentSensor(ts)); 244 sensedEntities.AddRange(doAgentSensor(ts));
246 } 245 }
@@ -339,7 +338,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
339 float dy; 338 float dy;
340 float dz; 339 float dz;
341 340
342 Quaternion q = SensePoint.GetWorldRotation(); 341// Quaternion q = SensePoint.RotationOffset;
342 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
343 if (SensePoint.ParentGroup.IsAttachment) 343 if (SensePoint.ParentGroup.IsAttachment)
344 { 344 {
345 // In attachments, rotate the sensor cone with the 345 // In attachments, rotate the sensor cone with the
@@ -353,7 +353,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
353 // Position of a sensor in a child prim attached to an avatar 353 // Position of a sensor in a child prim attached to an avatar
354 // will be still wrong. 354 // will be still wrong.
355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
356 q = avatar.GetWorldRotation() * q; 356 fromRegionPos = avatar.AbsolutePosition;
357 q = avatar.Rotation;
357 } 358 }
358 359
359 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 360 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -397,7 +398,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
397 objtype = 0; 398 objtype = 0;
398 399
399 part = ((SceneObjectGroup)ent).RootPart; 400 part = ((SceneObjectGroup)ent).RootPart;
400 if (part.ParentGroup.AttachmentPoint != 0) // Attached so ignore 401 if (part.ParentGroup.RootPart.Shape.PCode != (byte)PCode.Tree &&
402 part.ParentGroup.RootPart.Shape.PCode != (byte)PCode.NewTree &&
403 part.ParentGroup.AttachmentPoint != 0) // Attached so ignore
401 continue; 404 continue;
402 405
403 if (part.Inventory.ContainsScripts()) 406 if (part.Inventory.ContainsScripts())
@@ -480,7 +483,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
480 // Position of a sensor in a child prim attached to an avatar 483 // Position of a sensor in a child prim attached to an avatar
481 // will be still wrong. 484 // will be still wrong.
482 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 485 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
483 q = avatar.GetWorldRotation() * q; 486 if (avatar == null)
487 return sensedEntities;
488 fromRegionPos = avatar.AbsolutePosition;
489 q = avatar.Rotation;
484 } 490 }
485 491
486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 492 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -496,7 +502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
496// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 502// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
497// presence.Name, presence.PresenceType, ts.name, ts.type); 503// presence.Name, presence.PresenceType, ts.name, ts.type);
498 504
499 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 505 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
500 { 506 {
501 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 507 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
502 if (npcData == null || !npcData.SenseAsAgent) 508 if (npcData == null || !npcData.SenseAsAgent)
@@ -696,4 +702,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
696 return retList; 702 return retList;
697 } 703 }
698 } 704 }
699} \ No newline at end of file 705}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index 0b14565..68aacd2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -123,25 +123,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
123 if (Timers.Count == 0) 123 if (Timers.Count == 0)
124 return; 124 return;
125 125
126 Dictionary<string, TimerInfo>.ValueCollection tvals;
126 lock (TimerListLock) 127 lock (TimerListLock)
127 { 128 {
128 // Go through all timers 129 // Go through all timers
129 Dictionary<string, TimerInfo>.ValueCollection tvals = Timers.Values; 130 tvals = Timers.Values;
130 foreach (TimerInfo ts in tvals) 131 }
132
133 foreach (TimerInfo ts in tvals)
134 {
135 // Time has passed?
136 if (ts.next < DateTime.Now.Ticks)
131 { 137 {
132 // Time has passed? 138 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
133 if (ts.next < DateTime.Now.Ticks) 139 // Add it to queue
134 { 140 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
135 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 141 new EventParams("timer", new Object[0],
136 // Add it to queue 142 new DetectParams[0]));
137 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 143 // set next interval
138 new EventParams("timer", new Object[0], 144
139 new DetectParams[0])); 145 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
140 // set next interval 146 ts.next = DateTime.Now.Ticks + ts.interval;
141
142 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
143 ts.next = DateTime.Now.Ticks + ts.interval;
144 }
145 } 147 }
146 } 148 }
147 } 149 }