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.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3195
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs115
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
6 files changed, 2691 insertions, 803 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 47a9cdc..94fd940 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -305,6 +305,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
305 return null; 305 return null;
306 } 306 }
307 307
308 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
309 {
310 // Remove a specific script
311
312 // Remove dataserver events
313 m_Dataserver[engine].RemoveEvents(localID, itemID);
314
315 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
316 if (comms != null)
317 comms.DeleteListener(itemID);
318
319 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
320 xmlrpc.DeleteChannels(itemID);
321 xmlrpc.CancelSRDRequests(itemID);
322
323 // Remove Sensors
324 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
325
326 }
327
308 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 328 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
309 { 329 {
310 List<Object> data = new List<Object>(); 330 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..b5fa6de
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,116 @@
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.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal TaskInventoryItem m_item;
63 internal bool m_CMFunctionsEnabled = false;
64
65 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
66 {
67 m_ScriptEngine = ScriptEngine;
68 m_host = host;
69 m_item = item;
70
71 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
72 m_CMFunctionsEnabled = true;
73 }
74
75 public override Object InitializeLifetimeService()
76 {
77 ILease lease = (ILease)base.InitializeLifetimeService();
78
79 if (lease.CurrentState == LeaseState.Initial)
80 {
81 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
82 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
83 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
84 }
85 return lease;
86 }
87
88 public Scene World
89 {
90 get { return m_ScriptEngine.World; }
91 }
92
93 public string cmDetectedCountry(int number)
94 {
95 m_host.AddScriptLPS(1);
96 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
97 if (detectedParams == null)
98 return String.Empty;
99 return detectedParams.Country;
100 }
101
102 public string cmGetAgentCountry(LSL_Key key)
103 {
104 if (!World.Permissions.IsGod(m_host.OwnerID))
105 return String.Empty;
106
107 UUID uuid;
108
109 if (!UUID.TryParse(key, out uuid))
110 return String.Empty;
111
112 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
113 return account.UserCountry;
114 }
115 }
116}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index ac74bf8..17e3de1 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.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -66,6 +69,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
66using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 69using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
67using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 70using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
68using System.Reflection; 71using System.Reflection;
72using Timer = System.Timers.Timer;
69 73
70namespace OpenSim.Region.ScriptEngine.Shared.Api 74namespace OpenSim.Region.ScriptEngine.Shared.Api
71{ 75{
@@ -104,15 +108,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
104 protected int m_notecardLineReadCharsMax = 255; 108 protected int m_notecardLineReadCharsMax = 255;
105 protected int m_scriptConsoleChannel = 0; 109 protected int m_scriptConsoleChannel = 0;
106 protected bool m_scriptConsoleChannelEnabled = false; 110 protected bool m_scriptConsoleChannelEnabled = false;
111 protected bool m_debuggerSafe = false;
107 protected IUrlModule m_UrlModule = null; 112 protected IUrlModule m_UrlModule = null;
108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 113 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
109 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 114 new Dictionary<UUID, UserInfoCacheEntry>();
115 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
116
117// protected Timer m_ShoutSayTimer;
118 protected int m_SayShoutCount = 0;
119 DateTime m_lastSayShoutCheck;
120
121 private Dictionary<string, string> MovementAnimationsForLSL =
122 new Dictionary<string, string> {
123 {"FLY", "Flying"},
124 {"FLYSLOW", "FlyingSlow"},
125 {"HOVER_UP", "Hovering Up"},
126 {"HOVER_DOWN", "Hovering Down"},
127 {"HOVER", "Hovering"},
128 {"LAND", "Landing"},
129 {"FALLDOWN", "Falling Down"},
130 {"PREJUMP", "PreJumping"},
131 {"JUMP", "Jumping"},
132 {"STANDUP", "Standing Up"},
133 {"SOFT_LAND", "Soft Landing"},
134 {"STAND", "Standing"},
135 {"CROUCHWALK", "CrouchWalking"},
136 {"RUN", "Running"},
137 {"WALK", "Walking"},
138 {"CROUCH", "Crouching"},
139 {"TURNLEFT", "Turning Left"},
140 {"TURNRIGHT", "Turning Right"}
141 };
110 142
111 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
112 { 144 {
145/*
146 m_ShoutSayTimer = new Timer(1000);
147 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
148 m_ShoutSayTimer.AutoReset = true;
149 m_ShoutSayTimer.Start();
150*/
151 m_lastSayShoutCheck = DateTime.UtcNow;
152
113 m_ScriptEngine = ScriptEngine; 153 m_ScriptEngine = ScriptEngine;
114 m_host = host; 154 m_host = host;
115 m_item = item; 155 m_item = item;
156 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
116 157
117 LoadLimits(); // read script limits from config. 158 LoadLimits(); // read script limits from config.
118 159
@@ -172,6 +213,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
172 get { return m_ScriptEngine.World; } 213 get { return m_ScriptEngine.World; }
173 } 214 }
174 215
216 [DebuggerNonUserCode]
175 public void state(string newState) 217 public void state(string newState)
176 { 218 {
177 m_ScriptEngine.SetState(m_item.ItemID, newState); 219 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -181,6 +223,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
181 /// Reset the named script. The script must be present 223 /// Reset the named script. The script must be present
182 /// in the same prim. 224 /// in the same prim.
183 /// </summary> 225 /// </summary>
226 [DebuggerNonUserCode]
184 public void llResetScript() 227 public void llResetScript()
185 { 228 {
186 m_host.AddScriptLPS(1); 229 m_host.AddScriptLPS(1);
@@ -243,6 +286,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
243 } 286 }
244 } 287 }
245 288
289 public List<ScenePresence> GetLinkAvatars(int linkType)
290 {
291 List<ScenePresence> ret = new List<ScenePresence>();
292 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
293 return ret;
294
295 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
296
297 switch (linkType)
298 {
299 case ScriptBaseClass.LINK_SET:
300 return avs;
301
302 case ScriptBaseClass.LINK_ROOT:
303 return ret;
304
305 case ScriptBaseClass.LINK_ALL_OTHERS:
306 return avs;
307
308 case ScriptBaseClass.LINK_ALL_CHILDREN:
309 return avs;
310
311 case ScriptBaseClass.LINK_THIS:
312 return ret;
313
314 default:
315 if (linkType < 0)
316 return ret;
317
318 int partCount = m_host.ParentGroup.GetPartCount();
319
320 if (linkType <= partCount)
321 {
322 return ret;
323 }
324 else
325 {
326 linkType = linkType - partCount;
327 if (linkType > avs.Count)
328 {
329 return ret;
330 }
331 else
332 {
333 ret.Add(avs[linkType-1]);
334 return ret;
335 }
336 }
337 }
338 }
339
246 public List<SceneObjectPart> GetLinkParts(int linkType) 340 public List<SceneObjectPart> GetLinkParts(int linkType)
247 { 341 {
248 return GetLinkParts(m_host, linkType); 342 return GetLinkParts(m_host, linkType);
@@ -251,6 +345,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
251 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 345 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
252 { 346 {
253 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 347 List<SceneObjectPart> ret = new List<SceneObjectPart>();
348 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
349 return ret;
254 ret.Add(part); 350 ret.Add(part);
255 351
256 switch (linkType) 352 switch (linkType)
@@ -441,31 +537,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
441 537
442 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 538 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
443 539
444 /// <summary> 540 // Utility function for llRot2Euler
445 /// Convert an LSL rotation to a Euler vector. 541
446 /// </summary> 542 // normalize an angle between -PI and PI (-180 to +180 degrees)
447 /// <remarks> 543 protected double NormalizeAngle(double angle)
448 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
449 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
450 /// </remarks>
451 /// <param name="r"></param>
452 /// <returns></returns>
453 public LSL_Vector llRot2Euler(LSL_Rotation r)
454 { 544 {
455 m_host.AddScriptLPS(1); 545 if (angle > -Math.PI && angle < Math.PI)
546 return angle;
456 547
457 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 548 int numPis = (int)(Math.PI / angle);
458 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 549 double remainder = angle - Math.PI * numPis;
459 if (m == 0.0) return new LSL_Vector(); 550 if (numPis % 2 == 1)
460 double x = Math.Atan2(-v.y, v.z); 551 return Math.PI - angle;
461 double sin = v.x / m; 552 return remainder;
462 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 553 }
463 double y = Math.Asin(sin);
464 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
465 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)));
466 double z = Math.Atan2(v.y, v.x);
467 554
468 return new LSL_Vector(x, y, z); 555 public LSL_Vector llRot2Euler(LSL_Rotation q1)
556 {
557 m_host.AddScriptLPS(1);
558 LSL_Vector eul = new LSL_Vector();
559
560 double sqw = q1.s*q1.s;
561 double sqx = q1.x*q1.x;
562 double sqy = q1.z*q1.z;
563 double sqz = q1.y*q1.y;
564 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
565 double test = q1.x*q1.z + q1.y*q1.s;
566 if (test > 0.4999*unit) { // singularity at north pole
567 eul.z = 2 * Math.Atan2(q1.x,q1.s);
568 eul.y = Math.PI/2;
569 eul.x = 0;
570 return eul;
571 }
572 if (test < -0.4999*unit) { // singularity at south pole
573 eul.z = -2 * Math.Atan2(q1.x,q1.s);
574 eul.y = -Math.PI/2;
575 eul.x = 0;
576 return eul;
577 }
578 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
579 eul.y = Math.Asin(2*test/unit);
580 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
581 return eul;
469 } 582 }
470 583
471 /* From wiki: 584 /* From wiki:
@@ -518,18 +631,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
518 m_host.AddScriptLPS(1); 631 m_host.AddScriptLPS(1);
519 632
520 double x,y,z,s; 633 double x,y,z,s;
521 634 v.x *= 0.5;
522 double c1 = Math.Cos(v.x * 0.5); 635 v.y *= 0.5;
523 double c2 = Math.Cos(v.y * 0.5); 636 v.z *= 0.5;
524 double c3 = Math.Cos(v.z * 0.5); 637 double c1 = Math.Cos(v.x);
525 double s1 = Math.Sin(v.x * 0.5); 638 double c2 = Math.Cos(v.y);
526 double s2 = Math.Sin(v.y * 0.5); 639 double c1c2 = c1 * c2;
527 double s3 = Math.Sin(v.z * 0.5); 640 double s1 = Math.Sin(v.x);
528 641 double s2 = Math.Sin(v.y);
529 x = s1 * c2 * c3 + c1 * s2 * s3; 642 double s1s2 = s1 * s2;
530 y = c1 * s2 * c3 - s1 * c2 * s3; 643 double c1s2 = c1 * s2;
531 z = s1 * s2 * c3 + c1 * c2 * s3; 644 double s1c2 = s1 * c2;
532 s = c1 * c2 * c3 - s1 * s2 * s3; 645 double c3 = Math.Cos(v.z);
646 double s3 = Math.Sin(v.z);
647
648 x = s1c2 * c3 + c1s2 * s3;
649 y = c1s2 * c3 - s1c2 * s3;
650 z = s1s2 * c3 + c1c2 * s3;
651 s = c1c2 * c3 - s1s2 * s3;
533 652
534 return new LSL_Rotation(x, y, z, s); 653 return new LSL_Rotation(x, y, z, s);
535 } 654 }
@@ -667,77 +786,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
667 { 786 {
668 //A and B should both be normalized 787 //A and B should both be normalized
669 m_host.AddScriptLPS(1); 788 m_host.AddScriptLPS(1);
670 LSL_Rotation rotBetween; 789 /* This method is more accurate than the SL one, and thus causes problems
671 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 790 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
672 // continue calculation. 791
673 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 792 double dotProduct = LSL_Vector.Dot(a, b);
793 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
794 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
795 double angle = Math.Acos(dotProduct / magProduct);
796 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
797 double s = Math.Sin(angle / 2);
798
799 double x = axis.x * s;
800 double y = axis.y * s;
801 double z = axis.z * s;
802 double w = Math.Cos(angle / 2);
803
804 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
805 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
806
807 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
808 */
809
810 // This method mimics the 180 errors found in SL
811 // See www.euclideanspace.com... angleBetween
812 LSL_Vector vec_a = a;
813 LSL_Vector vec_b = b;
814
815 // Eliminate zero length
816 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
817 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
818 if (vec_a_mag < 0.00001 ||
819 vec_b_mag < 0.00001)
674 { 820 {
675 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 821 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
676 } 822 }
677 else 823
824 // Normalize
825 vec_a = llVecNorm(vec_a);
826 vec_b = llVecNorm(vec_b);
827
828 // Calculate axis and rotation angle
829 LSL_Vector axis = vec_a % vec_b;
830 LSL_Float cos_theta = vec_a * vec_b;
831
832 // Check if parallel
833 if (cos_theta > 0.99999)
678 { 834 {
679 a = LSL_Vector.Norm(a); 835 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
680 b = LSL_Vector.Norm(b); 836 }
681 double dotProduct = LSL_Vector.Dot(a, b); 837
682 // There are two degenerate cases possible. These are for vectors 180 or 838 // Check if anti-parallel
683 // 0 degrees apart. These have to be detected and handled individually. 839 else if (cos_theta < -0.99999)
684 // 840 {
685 // Check for vectors 180 degrees apart. 841 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
686 // A dot product of -1 would mean the angle between vectors is 180 degrees. 842 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
687 if (dotProduct < -0.9999999f) 843 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
688 { 844 }
689 // First assume X axis is orthogonal to the vectors. 845 else // other rotation
690 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 846 {
691 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 847 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
692 // Check for near zero vector. A very small non-zero number here will create 848 axis = llVecNorm(axis);
693 // a rotation in an undesired direction. 849 double x, y, z, s, t;
694 if (LSL_Vector.Mag(orthoVector) > 0.0001) 850 s = Math.Cos(theta);
695 { 851 t = Math.Sin(theta);
696 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 852 x = axis.x * t;
697 } 853 y = axis.y * t;
698 // If the magnitude of the vector was near zero, then assume the X axis is not 854 z = axis.z * t;
699 // orthogonal and use the Z axis instead. 855 return new LSL_Rotation(x,y,z,s);
700 else
701 {
702 // Set 180 z rotation.
703 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
704 }
705 }
706 // Check for parallel vectors.
707 // A dot product of 1 would mean the angle between vectors is 0 degrees.
708 else if (dotProduct > 0.9999999f)
709 {
710 // Set zero rotation.
711 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
712 }
713 else
714 {
715 // All special checks have been performed so get the axis of rotation.
716 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
717 // Quarternion s value is the length of the unit vector + dot product.
718 double qs = 1.0 + dotProduct;
719 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
720 // Normalize the rotation.
721 double mag = LSL_Rotation.Mag(rotBetween);
722 // We shouldn't have to worry about a divide by zero here. The qs value will be
723 // non-zero because we already know if we're here, then the dotProduct is not -1 so
724 // qs will not be zero. Also, we've already handled the input vectors being zero so the
725 // crossProduct vector should also not be zero.
726 rotBetween.x = rotBetween.x / mag;
727 rotBetween.y = rotBetween.y / mag;
728 rotBetween.z = rotBetween.z / mag;
729 rotBetween.s = rotBetween.s / mag;
730 // Check for undefined values and set zero rotation if any found. This code might not actually be required
731 // any longer since zero vectors are checked for at the top.
732 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
733 {
734 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
735 }
736 }
737 } 856 }
738 return rotBetween;
739 } 857 }
740 858
741 public void llWhisper(int channelID, string text) 859 public void llWhisper(int channelID, string text)
742 { 860 {
743 m_host.AddScriptLPS(1); 861 m_host.AddScriptLPS(1);
@@ -753,10 +871,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
753 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 871 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
754 } 872 }
755 873
874 private void CheckSayShoutTime()
875 {
876 DateTime now = DateTime.UtcNow;
877 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
878 {
879 m_lastSayShoutCheck = now;
880 m_SayShoutCount = 0;
881 }
882 else
883 m_SayShoutCount++;
884 }
885
756 public void llSay(int channelID, string text) 886 public void llSay(int channelID, string text)
757 { 887 {
758 m_host.AddScriptLPS(1); 888 m_host.AddScriptLPS(1);
759 889
890 if (channelID == 0)
891// m_SayShoutCount++;
892 CheckSayShoutTime();
893
894 if (m_SayShoutCount >= 11)
895 ScriptSleep(2000);
896
760 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 897 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
761 { 898 {
762 Console.WriteLine(text); 899 Console.WriteLine(text);
@@ -779,6 +916,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
779 { 916 {
780 m_host.AddScriptLPS(1); 917 m_host.AddScriptLPS(1);
781 918
919 if (channelID == 0)
920// m_SayShoutCount++;
921 CheckSayShoutTime();
922
923 if (m_SayShoutCount >= 11)
924 ScriptSleep(2000);
925
782 if (text.Length > 1023) 926 if (text.Length > 1023)
783 text = text.Substring(0, 1023); 927 text = text.Substring(0, 1023);
784 928
@@ -810,22 +954,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
810 954
811 public void llRegionSayTo(string target, int channel, string msg) 955 public void llRegionSayTo(string target, int channel, string msg)
812 { 956 {
957 string error = String.Empty;
958
813 if (msg.Length > 1023) 959 if (msg.Length > 1023)
814 msg = msg.Substring(0, 1023); 960 msg = msg.Substring(0, 1023);
815 961
816 m_host.AddScriptLPS(1); 962 m_host.AddScriptLPS(1);
817 963
818 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
819 {
820 return;
821 }
822
823 UUID TargetID; 964 UUID TargetID;
824 UUID.TryParse(target, out TargetID); 965 UUID.TryParse(target, out TargetID);
825 966
826 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 967 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
827 if (wComm != null) 968 if (wComm != null)
828 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 969 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
970 LSLError(error);
829 } 971 }
830 972
831 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 973 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1081,10 +1223,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1081 return detectedParams.TouchUV; 1223 return detectedParams.TouchUV;
1082 } 1224 }
1083 1225
1226 [DebuggerNonUserCode]
1084 public virtual void llDie() 1227 public virtual void llDie()
1085 { 1228 {
1086 m_host.AddScriptLPS(1); 1229 m_host.AddScriptLPS(1);
1087 throw new SelfDeleteException(); 1230 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1088 } 1231 }
1089 1232
1090 public LSL_Float llGround(LSL_Vector offset) 1233 public LSL_Float llGround(LSL_Vector offset)
@@ -1155,6 +1298,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1155 1298
1156 public void llSetStatus(int status, int value) 1299 public void llSetStatus(int status, int value)
1157 { 1300 {
1301 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1302 return;
1158 m_host.AddScriptLPS(1); 1303 m_host.AddScriptLPS(1);
1159 1304
1160 int statusrotationaxis = 0; 1305 int statusrotationaxis = 0;
@@ -1178,6 +1323,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1178 if (!allow) 1323 if (!allow)
1179 return; 1324 return;
1180 1325
1326 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1327 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1328 return;
1329
1181 m_host.ScriptSetPhysicsStatus(true); 1330 m_host.ScriptSetPhysicsStatus(true);
1182 } 1331 }
1183 else 1332 else
@@ -1377,6 +1526,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1377 { 1526 {
1378 m_host.AddScriptLPS(1); 1527 m_host.AddScriptLPS(1);
1379 1528
1529 SetColor(m_host, color, face);
1530 }
1531
1532 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1533 {
1534 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1535 return;
1536
1537 Primitive.TextureEntry tex = part.Shape.Textures;
1538 Color4 texcolor;
1539 if (face >= 0 && face < GetNumberOfSides(part))
1540 {
1541 texcolor = tex.CreateFace((uint)face).RGBA;
1542 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1543 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1544 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1545 tex.FaceTextures[face].RGBA = texcolor;
1546 part.UpdateTextureEntry(tex.GetBytes());
1547 return;
1548 }
1549 else if (face == ScriptBaseClass.ALL_SIDES)
1550 {
1551 for (uint i = 0; i < GetNumberOfSides(part); i++)
1552 {
1553 if (tex.FaceTextures[i] != null)
1554 {
1555 texcolor = tex.FaceTextures[i].RGBA;
1556 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1557 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1558 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1559 tex.FaceTextures[i].RGBA = texcolor;
1560 }
1561 texcolor = tex.DefaultTexture.RGBA;
1562 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1563 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1564 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1565 tex.DefaultTexture.RGBA = texcolor;
1566 }
1567 part.UpdateTextureEntry(tex.GetBytes());
1568 return;
1569 }
1570
1380 if (face == ScriptBaseClass.ALL_SIDES) 1571 if (face == ScriptBaseClass.ALL_SIDES)
1381 face = SceneObjectPart.ALL_SIDES; 1572 face = SceneObjectPart.ALL_SIDES;
1382 1573
@@ -1385,6 +1576,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1385 1576
1386 public void SetTexGen(SceneObjectPart part, int face,int style) 1577 public void SetTexGen(SceneObjectPart part, int face,int style)
1387 { 1578 {
1579 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1580 return;
1581
1388 Primitive.TextureEntry tex = part.Shape.Textures; 1582 Primitive.TextureEntry tex = part.Shape.Textures;
1389 MappingType textype; 1583 MappingType textype;
1390 textype = MappingType.Default; 1584 textype = MappingType.Default;
@@ -1415,6 +1609,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1415 1609
1416 public void SetGlow(SceneObjectPart part, int face, float glow) 1610 public void SetGlow(SceneObjectPart part, int face, float glow)
1417 { 1611 {
1612 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1613 return;
1614
1418 Primitive.TextureEntry tex = part.Shape.Textures; 1615 Primitive.TextureEntry tex = part.Shape.Textures;
1419 if (face >= 0 && face < GetNumberOfSides(part)) 1616 if (face >= 0 && face < GetNumberOfSides(part))
1420 { 1617 {
@@ -1440,6 +1637,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1440 1637
1441 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1638 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1442 { 1639 {
1640 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1641 return;
1443 1642
1444 Shininess sval = new Shininess(); 1643 Shininess sval = new Shininess();
1445 1644
@@ -1490,6 +1689,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1490 1689
1491 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1690 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1492 { 1691 {
1692 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1693 return;
1694
1493 Primitive.TextureEntry tex = part.Shape.Textures; 1695 Primitive.TextureEntry tex = part.Shape.Textures;
1494 if (face >= 0 && face < GetNumberOfSides(part)) 1696 if (face >= 0 && face < GetNumberOfSides(part))
1495 { 1697 {
@@ -1550,13 +1752,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1550 m_host.AddScriptLPS(1); 1752 m_host.AddScriptLPS(1);
1551 1753
1552 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1754 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1553 1755 if (parts.Count > 0)
1554 foreach (SceneObjectPart part in parts) 1756 {
1555 SetAlpha(part, alpha, face); 1757 try
1758 {
1759 foreach (SceneObjectPart part in parts)
1760 SetAlpha(part, alpha, face);
1761 }
1762 finally
1763 {
1764 }
1765 }
1556 } 1766 }
1557 1767
1558 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1768 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1559 { 1769 {
1770 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1771 return;
1772
1560 Primitive.TextureEntry tex = part.Shape.Textures; 1773 Primitive.TextureEntry tex = part.Shape.Textures;
1561 Color4 texcolor; 1774 Color4 texcolor;
1562 if (face >= 0 && face < GetNumberOfSides(part)) 1775 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1609,7 +1822,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1609 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1822 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1610 float wind, float tension, LSL_Vector Force) 1823 float wind, float tension, LSL_Vector Force)
1611 { 1824 {
1612 if (part == null) 1825 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1613 return; 1826 return;
1614 1827
1615 if (flexi) 1828 if (flexi)
@@ -1643,7 +1856,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1643 /// <param name="falloff"></param> 1856 /// <param name="falloff"></param>
1644 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1857 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1645 { 1858 {
1646 if (part == null) 1859 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1647 return; 1860 return;
1648 1861
1649 if (light) 1862 if (light)
@@ -1676,11 +1889,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1676 Primitive.TextureEntry tex = part.Shape.Textures; 1889 Primitive.TextureEntry tex = part.Shape.Textures;
1677 Color4 texcolor; 1890 Color4 texcolor;
1678 LSL_Vector rgb = new LSL_Vector(); 1891 LSL_Vector rgb = new LSL_Vector();
1892 int nsides = GetNumberOfSides(part);
1893
1679 if (face == ScriptBaseClass.ALL_SIDES) 1894 if (face == ScriptBaseClass.ALL_SIDES)
1680 { 1895 {
1681 int i; 1896 int i;
1682 1897 for (i = 0; i < nsides; i++)
1683 for (i = 0 ; i < GetNumberOfSides(part); i++)
1684 { 1898 {
1685 texcolor = tex.GetFace((uint)i).RGBA; 1899 texcolor = tex.GetFace((uint)i).RGBA;
1686 rgb.x += texcolor.R; 1900 rgb.x += texcolor.R;
@@ -1688,14 +1902,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1688 rgb.z += texcolor.B; 1902 rgb.z += texcolor.B;
1689 } 1903 }
1690 1904
1691 rgb.x /= (float)GetNumberOfSides(part); 1905 float invnsides = 1.0f / (float)nsides;
1692 rgb.y /= (float)GetNumberOfSides(part); 1906
1693 rgb.z /= (float)GetNumberOfSides(part); 1907 rgb.x *= invnsides;
1908 rgb.y *= invnsides;
1909 rgb.z *= invnsides;
1694 1910
1695 return rgb; 1911 return rgb;
1696 } 1912 }
1697 1913 if (face >= 0 && face < nsides)
1698 if (face >= 0 && face < GetNumberOfSides(part))
1699 { 1914 {
1700 texcolor = tex.GetFace((uint)face).RGBA; 1915 texcolor = tex.GetFace((uint)face).RGBA;
1701 rgb.x = texcolor.R; 1916 rgb.x = texcolor.R;
@@ -1722,15 +1937,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1722 m_host.AddScriptLPS(1); 1937 m_host.AddScriptLPS(1);
1723 1938
1724 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1939 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1725 1940 if (parts.Count > 0)
1726 foreach (SceneObjectPart part in parts) 1941 {
1727 SetTexture(part, texture, face); 1942 try
1728 1943 {
1944 foreach (SceneObjectPart part in parts)
1945 SetTexture(part, texture, face);
1946 }
1947 finally
1948 {
1949 }
1950 }
1729 ScriptSleep(200); 1951 ScriptSleep(200);
1730 } 1952 }
1731 1953
1732 protected void SetTexture(SceneObjectPart part, string texture, int face) 1954 protected void SetTexture(SceneObjectPart part, string texture, int face)
1733 { 1955 {
1956 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1957 return;
1958
1734 UUID textureID = new UUID(); 1959 UUID textureID = new UUID();
1735 1960
1736 textureID = InventoryKey(texture, (int)AssetType.Texture); 1961 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1775,6 +2000,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1775 2000
1776 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2001 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1777 { 2002 {
2003 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2004 return;
2005
1778 Primitive.TextureEntry tex = part.Shape.Textures; 2006 Primitive.TextureEntry tex = part.Shape.Textures;
1779 if (face >= 0 && face < GetNumberOfSides(part)) 2007 if (face >= 0 && face < GetNumberOfSides(part))
1780 { 2008 {
@@ -1811,6 +2039,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1811 2039
1812 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2040 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1813 { 2041 {
2042 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2043 return;
2044
1814 Primitive.TextureEntry tex = part.Shape.Textures; 2045 Primitive.TextureEntry tex = part.Shape.Textures;
1815 if (face >= 0 && face < GetNumberOfSides(part)) 2046 if (face >= 0 && face < GetNumberOfSides(part))
1816 { 2047 {
@@ -1847,6 +2078,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1847 2078
1848 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2079 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1849 { 2080 {
2081 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2082 return;
2083
1850 Primitive.TextureEntry tex = part.Shape.Textures; 2084 Primitive.TextureEntry tex = part.Shape.Textures;
1851 if (face >= 0 && face < GetNumberOfSides(part)) 2085 if (face >= 0 && face < GetNumberOfSides(part))
1852 { 2086 {
@@ -2017,24 +2251,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2017 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2251 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2018 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2252 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2019 { 2253 {
2020 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2254 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2255 return;
2256
2021 LSL_Vector currentPos = GetPartLocalPos(part); 2257 LSL_Vector currentPos = GetPartLocalPos(part);
2258 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2022 2259
2023 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2024 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2025 2260
2026 if (part.ParentGroup.RootPart == part) 2261 if (part.ParentGroup.RootPart == part)
2027 { 2262 {
2028 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2029 targetPos.z = ground;
2030 SceneObjectGroup parent = part.ParentGroup; 2263 SceneObjectGroup parent = part.ParentGroup;
2031 parent.UpdateGroupPosition(!adjust ? targetPos : 2264 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2032 SetPosAdjust(currentPos, targetPos)); 2265 return;
2266 Util.FireAndForget(delegate(object x) {
2267 parent.UpdateGroupPosition((Vector3)toPos);
2268 });
2033 } 2269 }
2034 else 2270 else
2035 { 2271 {
2036 part.OffsetPosition = !adjust ? targetPos : 2272 part.OffsetPosition = (Vector3)toPos;
2037 SetPosAdjust(currentPos, targetPos);
2038 SceneObjectGroup parent = part.ParentGroup; 2273 SceneObjectGroup parent = part.ParentGroup;
2039 parent.HasGroupChanged = true; 2274 parent.HasGroupChanged = true;
2040 parent.ScheduleGroupForTerseUpdate(); 2275 parent.ScheduleGroupForTerseUpdate();
@@ -2067,13 +2302,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2067 else 2302 else
2068 { 2303 {
2069 if (part.ParentGroup.IsAttachment) 2304 if (part.ParentGroup.IsAttachment)
2070 {
2071 pos = part.AttachedPos; 2305 pos = part.AttachedPos;
2072 }
2073 else 2306 else
2074 {
2075 pos = part.AbsolutePosition; 2307 pos = part.AbsolutePosition;
2076 }
2077 } 2308 }
2078 2309
2079// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2310// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2113,25 +2344,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2113 2344
2114 protected void SetRot(SceneObjectPart part, Quaternion rot) 2345 protected void SetRot(SceneObjectPart part, Quaternion rot)
2115 { 2346 {
2116 part.UpdateRotation(rot); 2347 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2117 // Update rotation does not move the object in the physics scene if it's a linkset. 2348 return;
2118 2349
2119//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2350 bool isroot = (part == part.ParentGroup.RootPart);
2120// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2351 bool isphys;
2121 2352
2122 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2123 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2124 // It's perfectly okay when the object is not an active physical body though.
2125 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2126 // but only if the object is not physial and active. This is important for rotating doors.
2127 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2128 // scene
2129 PhysicsActor pa = part.PhysActor; 2353 PhysicsActor pa = part.PhysActor;
2130 2354
2131 if (pa != null && !pa.IsPhysical) 2355 // keep using physactor ideia of isphysical
2356 // it should be SOP ideia of that
2357 // not much of a issue with ubitODE
2358 if (pa != null && pa.IsPhysical)
2359 isphys = true;
2360 else
2361 isphys = false;
2362
2363 // SL doesn't let scripts rotate root of physical linksets
2364 if (isroot && isphys)
2365 return;
2366
2367 part.UpdateRotation(rot);
2368
2369 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2370 // so do a nasty update of parts positions if is a root part rotation
2371 if (isroot && pa != null) // with if above implies non physical root part
2132 { 2372 {
2133 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2373 part.ParentGroup.ResetChildPrimPhysicsPositions();
2134 } 2374 }
2375 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2376 {
2377 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2378 if (sittingavas.Count > 0)
2379 {
2380 foreach (ScenePresence av in sittingavas)
2381 {
2382 if (isroot || part.LocalId == av.ParentID)
2383 av.SendTerseUpdateToAllClients();
2384 }
2385 }
2386 }
2135 } 2387 }
2136 2388
2137 /// <summary> 2389 /// <summary>
@@ -2179,8 +2431,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2179 2431
2180 public LSL_Rotation llGetLocalRot() 2432 public LSL_Rotation llGetLocalRot()
2181 { 2433 {
2434 return GetPartLocalRot(m_host);
2435 }
2436
2437 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2438 {
2182 m_host.AddScriptLPS(1); 2439 m_host.AddScriptLPS(1);
2183 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2440 Quaternion rot = part.RotationOffset;
2441 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2184 } 2442 }
2185 2443
2186 public void llSetForce(LSL_Vector force, int local) 2444 public void llSetForce(LSL_Vector force, int local)
@@ -2260,16 +2518,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2260 m_host.ApplyImpulse(v, local != 0); 2518 m_host.ApplyImpulse(v, local != 0);
2261 } 2519 }
2262 2520
2521
2263 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2522 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2264 { 2523 {
2265 m_host.AddScriptLPS(1); 2524 m_host.AddScriptLPS(1);
2266 m_host.ApplyAngularImpulse(force, local != 0); 2525 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2267 } 2526 }
2268 2527
2269 public void llSetTorque(LSL_Vector torque, int local) 2528 public void llSetTorque(LSL_Vector torque, int local)
2270 { 2529 {
2271 m_host.AddScriptLPS(1); 2530 m_host.AddScriptLPS(1);
2272 m_host.SetAngularImpulse(torque, local != 0); 2531 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2273 } 2532 }
2274 2533
2275 public LSL_Vector llGetTorque() 2534 public LSL_Vector llGetTorque()
@@ -2286,20 +2545,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2286 llSetTorque(torque, local); 2545 llSetTorque(torque, local);
2287 } 2546 }
2288 2547
2548 public void llSetVelocity(LSL_Vector vel, int local)
2549 {
2550 m_host.AddScriptLPS(1);
2551 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2552 }
2553
2289 public LSL_Vector llGetVel() 2554 public LSL_Vector llGetVel()
2290 { 2555 {
2291 m_host.AddScriptLPS(1); 2556 m_host.AddScriptLPS(1);
2292 2557
2293 Vector3 vel; 2558 Vector3 vel = Vector3.Zero;
2294 2559
2295 if (m_host.ParentGroup.IsAttachment) 2560 if (m_host.ParentGroup.IsAttachment)
2296 { 2561 {
2297 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2562 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2298 vel = avatar.Velocity; 2563 if (avatar != null)
2564 vel = avatar.Velocity;
2299 } 2565 }
2300 else 2566 else
2301 { 2567 {
2302 vel = m_host.Velocity; 2568 vel = m_host.ParentGroup.RootPart.Velocity;
2303 } 2569 }
2304 2570
2305 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2571 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2311,10 +2577,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2311 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2577 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2312 } 2578 }
2313 2579
2580 public void llSetAngularVelocity(LSL_Vector avel, int local)
2581 {
2582 m_host.AddScriptLPS(1);
2583 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2584 }
2585
2314 public LSL_Vector llGetOmega() 2586 public LSL_Vector llGetOmega()
2315 { 2587 {
2316 m_host.AddScriptLPS(1); 2588 m_host.AddScriptLPS(1);
2317 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2589 Vector3 avel = m_host.AngularVelocity;
2590 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2318 } 2591 }
2319 2592
2320 public LSL_Float llGetTimeOfDay() 2593 public LSL_Float llGetTimeOfDay()
@@ -2840,16 +3113,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2840 new_group.RootPart.UUID.ToString()) }, 3113 new_group.RootPart.UUID.ToString()) },
2841 new DetectParams[0])); 3114 new DetectParams[0]));
2842 3115
2843 float groupmass = new_group.GetMass(); 3116 // do recoil
3117 SceneObjectGroup hostgrp = m_host.ParentGroup;
3118 if (hostgrp == null)
3119 return;
3120
3121 if (hostgrp.IsAttachment) // don't recoil avatars
3122 return;
2844 3123
2845 PhysicsActor pa = new_group.RootPart.PhysActor; 3124 PhysicsActor pa = new_group.RootPart.PhysActor;
2846 3125
2847 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3126 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2848 { 3127 {
2849 //Recoil. 3128 float groupmass = new_group.GetMass();
2850 llApplyImpulse(vel * groupmass, 0); 3129 vel *= -groupmass;
3130 llApplyImpulse(vel, 0);
2851 } 3131 }
2852 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3132 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3133 return;
3134
2853 }); 3135 });
2854 3136
2855 //ScriptSleep((int)((groupmass * velmag) / 10)); 3137 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2864,35 +3146,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2864 public void llLookAt(LSL_Vector target, double strength, double damping) 3146 public void llLookAt(LSL_Vector target, double strength, double damping)
2865 { 3147 {
2866 m_host.AddScriptLPS(1); 3148 m_host.AddScriptLPS(1);
2867 // Determine where we are looking from
2868 LSL_Vector from = llGetPos();
2869 3149
2870 // Work out the normalised vector from the source to the target 3150 // Get the normalized vector to the target
2871 LSL_Vector delta = llVecNorm(target - from); 3151 LSL_Vector d1 = llVecNorm(target - llGetPos());
2872 LSL_Vector angle = new LSL_Vector(0,0,0);
2873 3152
2874 // Calculate the yaw 3153 // Get the bearing (yaw)
2875 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3154 LSL_Vector a1 = new LSL_Vector(0,0,0);
2876 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3155 a1.z = llAtan2(d1.y, d1.x);
2877 3156
2878 // Calculate pitch 3157 // Get the elevation (pitch)
2879 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3158 LSL_Vector a2 = new LSL_Vector(0,0,0);
3159 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2880 3160
2881 // we need to convert from a vector describing 3161 LSL_Rotation r1 = llEuler2Rot(a1);
2882 // the angles of rotation in radians into rotation value 3162 LSL_Rotation r2 = llEuler2Rot(a2);
2883 LSL_Rotation rot = llEuler2Rot(angle); 3163 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2884
2885 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2886 // set the rotation of the object, copy that behavior
2887 PhysicsActor pa = m_host.PhysActor;
2888 3164
2889 if (strength == 0 || pa == null || !pa.IsPhysical) 3165 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2890 { 3166 {
2891 llSetRot(rot); 3167 // Do nothing if either value is 0 (this has been checked in SL)
3168 if (strength <= 0.0 || damping <= 0.0)
3169 return;
3170
3171 llSetRot(r3 * r2 * r1);
2892 } 3172 }
2893 else 3173 else
2894 { 3174 {
2895 m_host.StartLookAt(rot, (float)strength, (float)damping); 3175 if (strength == 0)
3176 {
3177 llSetRot(r3 * r2 * r1);
3178 return;
3179 }
3180
3181 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2896 } 3182 }
2897 } 3183 }
2898 3184
@@ -2938,17 +3224,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2938 } 3224 }
2939 else 3225 else
2940 { 3226 {
2941 if (m_host.IsRoot) 3227 // new SL always returns object mass
2942 { 3228// if (m_host.IsRoot)
3229// {
2943 return m_host.ParentGroup.GetMass(); 3230 return m_host.ParentGroup.GetMass();
2944 } 3231// }
2945 else 3232// else
2946 { 3233// {
2947 return m_host.GetMass(); 3234// return m_host.GetMass();
2948 } 3235// }
2949 } 3236 }
2950 } 3237 }
2951 3238
3239
3240 public LSL_Float llGetMassMKS()
3241 {
3242 return 100f * llGetMass();
3243 }
3244
2952 public void llCollisionFilter(string name, string id, int accept) 3245 public void llCollisionFilter(string name, string id, int accept)
2953 { 3246 {
2954 m_host.AddScriptLPS(1); 3247 m_host.AddScriptLPS(1);
@@ -2996,8 +3289,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2996 { 3289 {
2997 // Unregister controls from Presence 3290 // Unregister controls from Presence
2998 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3291 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2999 // Remove Take Control permission.
3000 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3001 } 3292 }
3002 } 3293 }
3003 } 3294 }
@@ -3023,7 +3314,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3023 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3314 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3024 3315
3025 if (attachmentsModule != null) 3316 if (attachmentsModule != null)
3026 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3317 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3027 else 3318 else
3028 return false; 3319 return false;
3029 } 3320 }
@@ -3053,9 +3344,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3053 { 3344 {
3054 m_host.AddScriptLPS(1); 3345 m_host.AddScriptLPS(1);
3055 3346
3056// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3057// return;
3058
3059 if (m_item.PermsGranter != m_host.OwnerID) 3347 if (m_item.PermsGranter != m_host.OwnerID)
3060 return; 3348 return;
3061 3349
@@ -3098,6 +3386,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3098 3386
3099 public void llInstantMessage(string user, string message) 3387 public void llInstantMessage(string user, string message)
3100 { 3388 {
3389 UUID result;
3390 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3391 {
3392 ShoutError("An invalid key was passed to llInstantMessage");
3393 ScriptSleep(2000);
3394 return;
3395 }
3396
3397
3101 m_host.AddScriptLPS(1); 3398 m_host.AddScriptLPS(1);
3102 3399
3103 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3400 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3112,14 +3409,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3112 UUID friendTransactionID = UUID.Random(); 3409 UUID friendTransactionID = UUID.Random();
3113 3410
3114 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3411 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3115 3412
3116 GridInstantMessage msg = new GridInstantMessage(); 3413 GridInstantMessage msg = new GridInstantMessage();
3117 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3414 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3118 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3415 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3119 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3416 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3120// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3417// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3121// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3418// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3122 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3419// DateTime dt = DateTime.UtcNow;
3420//
3421// // Ticks from UtcNow, but make it look like local. Evil, huh?
3422// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3423//
3424// try
3425// {
3426// // Convert that to the PST timezone
3427// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3428// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3429// }
3430// catch
3431// {
3432// // No logging here, as it could be VERY spammy
3433// }
3434//
3435// // And make it look local again to fool the unix time util
3436// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3437
3438 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3439
3123 //if (client != null) 3440 //if (client != null)
3124 //{ 3441 //{
3125 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3442 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3133,12 +3450,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3133 msg.message = message.Substring(0, 1024); 3450 msg.message = message.Substring(0, 1024);
3134 else 3451 else
3135 msg.message = message; 3452 msg.message = message;
3136 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3453 msg.dialog = (byte)19; // MessageFromObject
3137 msg.fromGroup = false;// fromGroup; 3454 msg.fromGroup = false;// fromGroup;
3138 msg.offline = (byte)0; //offline; 3455 msg.offline = (byte)0; //offline;
3139 msg.ParentEstateID = 0; //ParentEstateID; 3456 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3140 msg.Position = new Vector3(m_host.AbsolutePosition); 3457 msg.Position = new Vector3(m_host.AbsolutePosition);
3141 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3458 msg.RegionID = World.RegionInfo.RegionID.Guid;
3142 msg.binaryBucket 3459 msg.binaryBucket
3143 = Util.StringToBytes256( 3460 = Util.StringToBytes256(
3144 "{0}/{1}/{2}/{3}", 3461 "{0}/{1}/{2}/{3}",
@@ -3166,7 +3483,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3166 } 3483 }
3167 3484
3168 emailModule.SendEmail(m_host.UUID, address, subject, message); 3485 emailModule.SendEmail(m_host.UUID, address, subject, message);
3169 llSleep(EMAIL_PAUSE_TIME); 3486 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3170 } 3487 }
3171 3488
3172 public void llGetNextEmail(string address, string subject) 3489 public void llGetNextEmail(string address, string subject)
@@ -3412,7 +3729,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3412 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3729 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3413 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3730 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3414 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3731 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3732 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3415 ScriptBaseClass.PERMISSION_ATTACH; 3733 ScriptBaseClass.PERMISSION_ATTACH;
3734
3416 } 3735 }
3417 else 3736 else
3418 { 3737 {
@@ -3443,15 +3762,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3443 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3762 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3444 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3763 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3445 } 3764 }
3765 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3766 {
3767 implicitPerms = perm;
3768 }
3446 } 3769 }
3447 3770
3448 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3771 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3449 { 3772 {
3450 lock (m_host.TaskInventory) 3773 m_host.TaskInventory.LockItemsForWrite(true);
3451 { 3774 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3452 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3775 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3453 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3776 m_host.TaskInventory.LockItemsForWrite(false);
3454 }
3455 3777
3456 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3778 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3457 "run_time_permissions", new Object[] { 3779 "run_time_permissions", new Object[] {
@@ -3494,11 +3816,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3494 3816
3495 if (!m_waitingForScriptAnswer) 3817 if (!m_waitingForScriptAnswer)
3496 { 3818 {
3497 lock (m_host.TaskInventory) 3819 m_host.TaskInventory.LockItemsForWrite(true);
3498 { 3820 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3499 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3821 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3500 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3822 m_host.TaskInventory.LockItemsForWrite(false);
3501 }
3502 3823
3503 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3824 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3504 m_waitingForScriptAnswer=true; 3825 m_waitingForScriptAnswer=true;
@@ -3527,14 +3848,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3527 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3848 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3528 llReleaseControls(); 3849 llReleaseControls();
3529 3850
3530 lock (m_host.TaskInventory) 3851 m_host.TaskInventory.LockItemsForWrite(true);
3531 { 3852 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3532 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3853 m_host.TaskInventory.LockItemsForWrite(false);
3533 } 3854
3534 3855 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3535 m_ScriptEngine.PostScriptEvent( 3856 "run_time_permissions", new Object[] {
3536 m_item.ItemID, 3857 new LSL_Integer(answer) },
3537 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3858 new DetectParams[0]));
3538 } 3859 }
3539 3860
3540 public LSL_String llGetPermissionsKey() 3861 public LSL_String llGetPermissionsKey()
@@ -3573,14 +3894,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3573 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3894 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3574 { 3895 {
3575 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3896 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3576 3897 if (parts.Count > 0)
3577 foreach (SceneObjectPart part in parts) 3898 {
3578 part.SetFaceColorAlpha(face, color, null); 3899 try
3900 {
3901 foreach (SceneObjectPart part in parts)
3902 part.SetFaceColorAlpha(face, color, null);
3903 }
3904 finally
3905 {
3906 }
3907 }
3579 } 3908 }
3580 3909
3581 public void llCreateLink(string target, int parent) 3910 public void llCreateLink(string target, int parent)
3582 { 3911 {
3583 m_host.AddScriptLPS(1); 3912 m_host.AddScriptLPS(1);
3913
3584 UUID targetID; 3914 UUID targetID;
3585 3915
3586 if (!UUID.TryParse(target, out targetID)) 3916 if (!UUID.TryParse(target, out targetID))
@@ -3686,10 +4016,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3686 // Restructuring Multiple Prims. 4016 // Restructuring Multiple Prims.
3687 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4017 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3688 parts.Remove(parentPrim.RootPart); 4018 parts.Remove(parentPrim.RootPart);
3689 foreach (SceneObjectPart part in parts) 4019 if (parts.Count > 0)
3690 { 4020 {
3691 parentPrim.DelinkFromGroup(part.LocalId, true); 4021 try
4022 {
4023 foreach (SceneObjectPart part in parts)
4024 {
4025 parentPrim.DelinkFromGroup(part.LocalId, true);
4026 }
4027 }
4028 finally
4029 {
4030 }
3692 } 4031 }
4032
3693 parentPrim.HasGroupChanged = true; 4033 parentPrim.HasGroupChanged = true;
3694 parentPrim.ScheduleGroupForFullUpdate(); 4034 parentPrim.ScheduleGroupForFullUpdate();
3695 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4035 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3698,12 +4038,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3698 { 4038 {
3699 SceneObjectPart newRoot = parts[0]; 4039 SceneObjectPart newRoot = parts[0];
3700 parts.Remove(newRoot); 4040 parts.Remove(newRoot);
3701 foreach (SceneObjectPart part in parts) 4041
4042 try
3702 { 4043 {
3703 // Required for linking 4044 foreach (SceneObjectPart part in parts)
3704 part.ClearUpdateSchedule(); 4045 {
3705 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4046 part.ClearUpdateSchedule();
4047 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4048 }
3706 } 4049 }
4050 finally
4051 {
4052 }
4053
4054
3707 newRoot.ParentGroup.HasGroupChanged = true; 4055 newRoot.ParentGroup.HasGroupChanged = true;
3708 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4056 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3709 } 4057 }
@@ -3723,6 +4071,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3723 public void llBreakAllLinks() 4071 public void llBreakAllLinks()
3724 { 4072 {
3725 m_host.AddScriptLPS(1); 4073 m_host.AddScriptLPS(1);
4074
4075 TaskInventoryItem item = m_item;
4076
4077 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4078 && !m_automaticLinkPermission)
4079 {
4080 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4081 return;
4082 }
4083
3726 SceneObjectGroup parentPrim = m_host.ParentGroup; 4084 SceneObjectGroup parentPrim = m_host.ParentGroup;
3727 if (parentPrim.AttachmentPoint != 0) 4085 if (parentPrim.AttachmentPoint != 0)
3728 return; // Fail silently if attached 4086 return; // Fail silently if attached
@@ -3742,25 +4100,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3742 public LSL_String llGetLinkKey(int linknum) 4100 public LSL_String llGetLinkKey(int linknum)
3743 { 4101 {
3744 m_host.AddScriptLPS(1); 4102 m_host.AddScriptLPS(1);
3745 List<UUID> keytable = new List<UUID>();
3746 // parse for sitting avatare-uuids
3747 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3748 {
3749 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3750 keytable.Add(presence.UUID);
3751 });
3752
3753 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3754 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3755 {
3756 return keytable[totalprims - linknum].ToString();
3757 }
3758
3759 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3760 {
3761 return m_host.UUID.ToString();
3762 }
3763
3764 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4103 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3765 if (part != null) 4104 if (part != null)
3766 { 4105 {
@@ -3768,6 +4107,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3768 } 4107 }
3769 else 4108 else
3770 { 4109 {
4110 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4111 {
4112 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4113
4114 if (linknum < 0)
4115 return UUID.Zero.ToString();
4116
4117 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4118 if (avatars.Count > linknum)
4119 {
4120 return avatars[linknum].UUID.ToString();
4121 }
4122 }
3771 return UUID.Zero.ToString(); 4123 return UUID.Zero.ToString();
3772 } 4124 }
3773 } 4125 }
@@ -3867,17 +4219,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3867 m_host.AddScriptLPS(1); 4219 m_host.AddScriptLPS(1);
3868 int count = 0; 4220 int count = 0;
3869 4221
3870 lock (m_host.TaskInventory) 4222 m_host.TaskInventory.LockItemsForRead(true);
4223 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3871 { 4224 {
3872 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4225 if (inv.Value.Type == type || type == -1)
3873 { 4226 {
3874 if (inv.Value.Type == type || type == -1) 4227 count = count + 1;
3875 {
3876 count = count + 1;
3877 }
3878 } 4228 }
3879 } 4229 }
3880 4230
4231 m_host.TaskInventory.LockItemsForRead(false);
3881 return count; 4232 return count;
3882 } 4233 }
3883 4234
@@ -3886,16 +4237,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3886 m_host.AddScriptLPS(1); 4237 m_host.AddScriptLPS(1);
3887 ArrayList keys = new ArrayList(); 4238 ArrayList keys = new ArrayList();
3888 4239
3889 lock (m_host.TaskInventory) 4240 m_host.TaskInventory.LockItemsForRead(true);
4241 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3890 { 4242 {
3891 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4243 if (inv.Value.Type == type || type == -1)
3892 { 4244 {
3893 if (inv.Value.Type == type || type == -1) 4245 keys.Add(inv.Value.Name);
3894 {
3895 keys.Add(inv.Value.Name);
3896 }
3897 } 4246 }
3898 } 4247 }
4248 m_host.TaskInventory.LockItemsForRead(false);
3899 4249
3900 if (keys.Count == 0) 4250 if (keys.Count == 0)
3901 { 4251 {
@@ -3933,7 +4283,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3933 if (item == null) 4283 if (item == null)
3934 { 4284 {
3935 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4285 llSay(0, String.Format("Could not find object '{0}'", inventory));
3936 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4286 return;
4287// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3937 } 4288 }
3938 4289
3939 UUID objId = item.ItemID; 4290 UUID objId = item.ItemID;
@@ -3961,33 +4312,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3961 return; 4312 return;
3962 } 4313 }
3963 } 4314 }
4315
3964 // destination is an avatar 4316 // destination is an avatar
3965 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4317 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3966 4318
3967 if (agentItem == null) 4319 if (agentItem == null)
3968 return; 4320 return;
3969 4321
3970 if (m_TransferModule != null) 4322 byte[] bucket = new byte[1];
3971 { 4323 bucket[0] = (byte)item.Type;
3972 byte[] bucket = new byte[] { (byte)item.Type }; 4324 //byte[] objBytes = agentItem.ID.GetBytes();
4325 //Array.Copy(objBytes, 0, bucket, 1, 16);
3973 4326
3974 GridInstantMessage msg = new GridInstantMessage(World, 4327 GridInstantMessage msg = new GridInstantMessage(World,
3975 m_host.UUID, m_host.Name + ", an object owned by " + 4328 m_host.OwnerID, m_host.Name, destId,
3976 resolveName(m_host.OwnerID) + ",", destId, 4329 (byte)InstantMessageDialog.TaskInventoryOffered,
3977 (byte)InstantMessageDialog.TaskInventoryOffered, 4330 false, item.Name+". "+m_host.Name+" is located at "+
3978 false, item.Name + "\n" + m_host.Name + " is located at " + 4331 World.RegionInfo.RegionName+" "+
3979 World.RegionInfo.RegionName+" "+ 4332 m_host.AbsolutePosition.ToString(),
3980 m_host.AbsolutePosition.ToString(), 4333 agentItem.ID, true, m_host.AbsolutePosition,
3981 agentItem.ID, true, m_host.AbsolutePosition, 4334 bucket, true);
3982 bucket, true); // TODO: May actually send no timestamp
3983 4335
3984 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4336 ScenePresence sp;
3985 }
3986 4337
4338 if (World.TryGetScenePresence(destId, out sp))
4339 {
4340 sp.ControllingClient.SendInstantMessage(msg);
4341 }
4342 else
4343 {
4344 if (m_TransferModule != null)
4345 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4346 }
4347
4348 //This delay should only occur when giving inventory to avatars.
3987 ScriptSleep(3000); 4349 ScriptSleep(3000);
3988 } 4350 }
3989 } 4351 }
3990 4352
4353 [DebuggerNonUserCode]
3991 public void llRemoveInventory(string name) 4354 public void llRemoveInventory(string name)
3992 { 4355 {
3993 m_host.AddScriptLPS(1); 4356 m_host.AddScriptLPS(1);
@@ -4042,109 +4405,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4042 { 4405 {
4043 m_host.AddScriptLPS(1); 4406 m_host.AddScriptLPS(1);
4044 4407
4045 UUID uuid = (UUID)id; 4408 UUID uuid;
4046 PresenceInfo pinfo = null; 4409 if (UUID.TryParse(id, out uuid))
4047 UserAccount account;
4048
4049 UserInfoCacheEntry ce;
4050 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4051 { 4410 {
4052 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4411 PresenceInfo pinfo = null;
4053 if (account == null) 4412 UserAccount account;
4413
4414 UserInfoCacheEntry ce;
4415 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4054 { 4416 {
4055 m_userInfoCache[uuid] = null; // Cache negative 4417 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4056 return UUID.Zero.ToString(); 4418 if (account == null)
4057 } 4419 {
4420 m_userInfoCache[uuid] = null; // Cache negative
4421 return UUID.Zero.ToString();
4422 }
4058 4423
4059 4424
4060 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4425 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4061 if (pinfos != null && pinfos.Length > 0) 4426 if (pinfos != null && pinfos.Length > 0)
4062 {
4063 foreach (PresenceInfo p in pinfos)
4064 { 4427 {
4065 if (p.RegionID != UUID.Zero) 4428 foreach (PresenceInfo p in pinfos)
4066 { 4429 {
4067 pinfo = p; 4430 if (p.RegionID != UUID.Zero)
4431 {
4432 pinfo = p;
4433 }
4068 } 4434 }
4069 } 4435 }
4070 }
4071 4436
4072 ce = new UserInfoCacheEntry(); 4437 ce = new UserInfoCacheEntry();
4073 ce.time = Util.EnvironmentTickCount(); 4438 ce.time = Util.EnvironmentTickCount();
4074 ce.account = account; 4439 ce.account = account;
4075 ce.pinfo = pinfo; 4440 ce.pinfo = pinfo;
4076 } 4441 m_userInfoCache[uuid] = ce;
4077 else 4442 }
4078 { 4443 else
4079 if (ce == null) 4444 {
4080 return UUID.Zero.ToString(); 4445 if (ce == null)
4446 return UUID.Zero.ToString();
4081 4447
4082 account = ce.account; 4448 account = ce.account;
4083 pinfo = ce.pinfo; 4449 pinfo = ce.pinfo;
4084 } 4450 }
4085 4451
4086 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4452 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4087 {
4088 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4089 if (pinfos != null && pinfos.Length > 0)
4090 { 4453 {
4091 foreach (PresenceInfo p in pinfos) 4454 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4455 if (pinfos != null && pinfos.Length > 0)
4092 { 4456 {
4093 if (p.RegionID != UUID.Zero) 4457 foreach (PresenceInfo p in pinfos)
4094 { 4458 {
4095 pinfo = p; 4459 if (p.RegionID != UUID.Zero)
4460 {
4461 pinfo = p;
4462 }
4096 } 4463 }
4097 } 4464 }
4098 } 4465 else
4099 else 4466 pinfo = null;
4100 pinfo = null;
4101 4467
4102 ce.time = Util.EnvironmentTickCount(); 4468 ce.time = Util.EnvironmentTickCount();
4103 ce.pinfo = pinfo; 4469 ce.pinfo = pinfo;
4104 } 4470 }
4105 4471
4106 string reply = String.Empty; 4472 string reply = String.Empty;
4107 4473
4108 switch (data) 4474 switch (data)
4109 { 4475 {
4110 case 1: // DATA_ONLINE (0|1) 4476 case 1: // DATA_ONLINE (0|1)
4111 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4477 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4112 reply = "1"; 4478 reply = "1";
4113 else 4479 else
4114 reply = "0"; 4480 reply = "0";
4115 break; 4481 break;
4116 case 2: // DATA_NAME (First Last) 4482 case 2: // DATA_NAME (First Last)
4117 reply = account.FirstName + " " + account.LastName; 4483 reply = account.FirstName + " " + account.LastName;
4118 break; 4484 break;
4119 case 3: // DATA_BORN (YYYY-MM-DD) 4485 case 3: // DATA_BORN (YYYY-MM-DD)
4120 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4486 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4121 born = born.AddSeconds(account.Created); 4487 born = born.AddSeconds(account.Created);
4122 reply = born.ToString("yyyy-MM-dd"); 4488 reply = born.ToString("yyyy-MM-dd");
4123 break; 4489 break;
4124 case 4: // DATA_RATING (0,0,0,0,0,0) 4490 case 4: // DATA_RATING (0,0,0,0,0,0)
4125 reply = "0,0,0,0,0,0"; 4491 reply = "0,0,0,0,0,0";
4126 break; 4492 break;
4127 case 7: // DATA_USERLEVEL (integer) 4493 case 8: // DATA_PAYINFO (0|1|2|3)
4128 reply = account.UserLevel.ToString(); 4494 reply = "0";
4129 break; 4495 break;
4130 case 8: // DATA_PAYINFO (0|1|2|3) 4496 default:
4131 reply = "0"; 4497 return UUID.Zero.ToString(); // Raise no event
4132 break; 4498 }
4133 default:
4134 return UUID.Zero.ToString(); // Raise no event
4135 }
4136 4499
4137 UUID rq = UUID.Random(); 4500 UUID rq = UUID.Random();
4138 4501
4139 UUID tid = AsyncCommands. 4502 UUID tid = AsyncCommands.
4140 DataserverPlugin.RegisterRequest(m_host.LocalId, 4503 DataserverPlugin.RegisterRequest(m_host.LocalId,
4141 m_item.ItemID, rq.ToString()); 4504 m_item.ItemID, rq.ToString());
4142 4505
4143 AsyncCommands. 4506 AsyncCommands.
4144 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4507 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4145 4508
4146 ScriptSleep(100); 4509 ScriptSleep(100);
4147 return tid.ToString(); 4510 return tid.ToString();
4511 }
4512 else
4513 {
4514 ShoutError("Invalid UUID passed to llRequestAgentData.");
4515 }
4516 return "";
4148 } 4517 }
4149 4518
4150 public LSL_String llRequestInventoryData(string name) 4519 public LSL_String llRequestInventoryData(string name)
@@ -4201,13 +4570,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4201 if (UUID.TryParse(agent, out agentId)) 4570 if (UUID.TryParse(agent, out agentId))
4202 { 4571 {
4203 ScenePresence presence = World.GetScenePresence(agentId); 4572 ScenePresence presence = World.GetScenePresence(agentId);
4204 if (presence != null) 4573 if (presence != null && presence.PresenceType != PresenceType.Npc)
4205 { 4574 {
4575 // agent must not be a god
4576 if (presence.UserLevel >= 200) return;
4577
4206 // agent must be over the owners land 4578 // agent must be over the owners land
4207 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4579 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4208 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4580 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4209 { 4581 {
4210 World.TeleportClientHome(agentId, presence.ControllingClient); 4582 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4583 {
4584 // They can't be teleported home for some reason
4585 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4586 if (regionInfo != null)
4587 {
4588 World.RequestTeleportLocation(
4589 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4590 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4591 }
4592 }
4211 } 4593 }
4212 } 4594 }
4213 } 4595 }
@@ -4314,7 +4696,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4314 UUID av = new UUID(); 4696 UUID av = new UUID();
4315 if (!UUID.TryParse(agent,out av)) 4697 if (!UUID.TryParse(agent,out av))
4316 { 4698 {
4317 LSLError("First parameter to llDialog needs to be a key"); 4699 //LSLError("First parameter to llDialog needs to be a key");
4318 return; 4700 return;
4319 } 4701 }
4320 4702
@@ -4346,7 +4728,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4346 public void llCollisionSound(string impact_sound, double impact_volume) 4728 public void llCollisionSound(string impact_sound, double impact_volume)
4347 { 4729 {
4348 m_host.AddScriptLPS(1); 4730 m_host.AddScriptLPS(1);
4349 4731
4732 if(impact_sound == "")
4733 {
4734 m_host.CollisionSoundVolume = (float)impact_volume;
4735 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4736 m_host.CollisionSoundType = 0;
4737 return;
4738 }
4350 // TODO: Parameter check logic required. 4739 // TODO: Parameter check logic required.
4351 UUID soundId = UUID.Zero; 4740 UUID soundId = UUID.Zero;
4352 if (!UUID.TryParse(impact_sound, out soundId)) 4741 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4359,6 +4748,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4359 4748
4360 m_host.CollisionSound = soundId; 4749 m_host.CollisionSound = soundId;
4361 m_host.CollisionSoundVolume = (float)impact_volume; 4750 m_host.CollisionSoundVolume = (float)impact_volume;
4751 m_host.CollisionSoundType = 1;
4362 } 4752 }
4363 4753
4364 public LSL_String llGetAnimation(string id) 4754 public LSL_String llGetAnimation(string id)
@@ -4372,14 +4762,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4372 4762
4373 if (m_host.RegionHandle == presence.RegionHandle) 4763 if (m_host.RegionHandle == presence.RegionHandle)
4374 { 4764 {
4375 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4376
4377 if (presence != null) 4765 if (presence != null)
4378 { 4766 {
4379 AnimationSet currentAnims = presence.Animator.Animations; 4767 if (presence.SitGround)
4380 string currentAnimationState = String.Empty; 4768 return "Sitting on Ground";
4381 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4769 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4382 return currentAnimationState; 4770 return "Sitting";
4771
4772 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4773 string lslMovementAnimation;
4774
4775 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4776 return lslMovementAnimation;
4383 } 4777 }
4384 } 4778 }
4385 4779
@@ -4526,7 +4920,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4526 { 4920 {
4527 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4921 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4528 float distance_term = distance * distance * distance; // Script Energy 4922 float distance_term = distance * distance * distance; // Script Energy
4529 float pusher_mass = m_host.GetMass(); 4923 // use total object mass and not part
4924 float pusher_mass = m_host.ParentGroup.GetMass();
4530 4925
4531 float PUSH_ATTENUATION_DISTANCE = 17f; 4926 float PUSH_ATTENUATION_DISTANCE = 17f;
4532 float PUSH_ATTENUATION_SCALE = 5f; 4927 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4776,6 +5171,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4776 { 5171 {
4777 return item.AssetID.ToString(); 5172 return item.AssetID.ToString();
4778 } 5173 }
5174 m_host.TaskInventory.LockItemsForRead(false);
4779 5175
4780 return UUID.Zero.ToString(); 5176 return UUID.Zero.ToString();
4781 } 5177 }
@@ -4909,7 +5305,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4909 public LSL_Vector llGetCenterOfMass() 5305 public LSL_Vector llGetCenterOfMass()
4910 { 5306 {
4911 m_host.AddScriptLPS(1); 5307 m_host.AddScriptLPS(1);
4912 Vector3 center = m_host.GetGeometricCenter(); 5308 Vector3 center = m_host.GetCenterOfMass();
4913 return new LSL_Vector(center.X,center.Y,center.Z); 5309 return new LSL_Vector(center.X,center.Y,center.Z);
4914 } 5310 }
4915 5311
@@ -4928,14 +5324,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4928 { 5324 {
4929 m_host.AddScriptLPS(1); 5325 m_host.AddScriptLPS(1);
4930 5326
4931 if (src == null) 5327 return src.Length;
4932 {
4933 return 0;
4934 }
4935 else
4936 {
4937 return src.Length;
4938 }
4939 } 5328 }
4940 5329
4941 public LSL_Integer llList2Integer(LSL_List src, int index) 5330 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5006,7 +5395,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5006 else if (src.Data[index] is LSL_Float) 5395 else if (src.Data[index] is LSL_Float)
5007 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5396 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5008 else if (src.Data[index] is LSL_String) 5397 else if (src.Data[index] is LSL_String)
5009 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5398 {
5399 string str = ((LSL_String) src.Data[index]).m_string;
5400 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5401 if (m != Match.Empty)
5402 {
5403 str = m.Value;
5404 double d = 0.0;
5405 if (!Double.TryParse(str, out d))
5406 return 0.0;
5407
5408 return d;
5409 }
5410 return 0.0;
5411 }
5010 return Convert.ToDouble(src.Data[index]); 5412 return Convert.ToDouble(src.Data[index]);
5011 } 5413 }
5012 catch (FormatException) 5414 catch (FormatException)
@@ -5048,7 +5450,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5048 // for completion and should LSL_Key ever be implemented 5450 // for completion and should LSL_Key ever be implemented
5049 // as it's own struct 5451 // as it's own struct
5050 else if (!(src.Data[index] is LSL_String || 5452 else if (!(src.Data[index] is LSL_String ||
5051 src.Data[index] is LSL_Key)) 5453 src.Data[index] is LSL_Key ||
5454 src.Data[index] is String))
5052 { 5455 {
5053 return ""; 5456 return "";
5054 } 5457 }
@@ -5306,7 +5709,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5306 } 5709 }
5307 } 5710 }
5308 } 5711 }
5309 else { 5712 else
5713 {
5310 object[] array = new object[src.Length]; 5714 object[] array = new object[src.Length];
5311 Array.Copy(src.Data, 0, array, 0, src.Length); 5715 Array.Copy(src.Data, 0, array, 0, src.Length);
5312 result = new LSL_List(array); 5716 result = new LSL_List(array);
@@ -5413,7 +5817,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5413 public LSL_Integer llGetRegionAgentCount() 5817 public LSL_Integer llGetRegionAgentCount()
5414 { 5818 {
5415 m_host.AddScriptLPS(1); 5819 m_host.AddScriptLPS(1);
5416 return new LSL_Integer(World.GetRootAgentCount()); 5820
5821 int count = 0;
5822 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5823 count++;
5824 });
5825
5826 return new LSL_Integer(count);
5417 } 5827 }
5418 5828
5419 public LSL_Vector llGetRegionCorner() 5829 public LSL_Vector llGetRegionCorner()
@@ -5654,6 +6064,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5654 flags |= ScriptBaseClass.AGENT_AWAY; 6064 flags |= ScriptBaseClass.AGENT_AWAY;
5655 } 6065 }
5656 6066
6067 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6068 UUID[] anims = agent.Animator.GetAnimationArray();
6069 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6070 {
6071 flags |= ScriptBaseClass.AGENT_BUSY;
6072 }
6073
5657 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6074 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5658 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6075 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5659 { 6076 {
@@ -5701,6 +6118,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5701 flags |= ScriptBaseClass.AGENT_SITTING; 6118 flags |= ScriptBaseClass.AGENT_SITTING;
5702 } 6119 }
5703 6120
6121 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6122 {
6123 flags |= ScriptBaseClass.AGENT_MALE;
6124 }
6125
5704 return flags; 6126 return flags;
5705 } 6127 }
5706 6128
@@ -5848,9 +6270,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5848 6270
5849 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6271 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5850 6272
5851 foreach (SceneObjectPart part in parts) 6273 try
6274 {
6275 foreach (SceneObjectPart part in parts)
6276 {
6277 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6278 }
6279 }
6280 finally
5852 { 6281 {
5853 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5854 } 6282 }
5855 } 6283 }
5856 6284
@@ -5902,13 +6330,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5902 6330
5903 if (m_host.OwnerID == land.LandData.OwnerID) 6331 if (m_host.OwnerID == land.LandData.OwnerID)
5904 { 6332 {
5905 World.TeleportClientHome(agentID, presence.ControllingClient); 6333 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6334 presence.TeleportWithMomentum(pos, null);
6335 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5906 } 6336 }
5907 } 6337 }
5908 } 6338 }
5909 ScriptSleep(5000); 6339 ScriptSleep(5000);
5910 } 6340 }
5911 6341
6342 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6343 {
6344 return ParseString2List(str, separators, in_spacers, false);
6345 }
6346
5912 public LSL_Integer llOverMyLand(string id) 6347 public LSL_Integer llOverMyLand(string id)
5913 { 6348 {
5914 m_host.AddScriptLPS(1); 6349 m_host.AddScriptLPS(1);
@@ -5967,20 +6402,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5967 return agentSize; 6402 return agentSize;
5968 } 6403 }
5969 6404
5970 public LSL_Integer llSameGroup(string agent) 6405 public LSL_Integer llSameGroup(string id)
5971 { 6406 {
5972 m_host.AddScriptLPS(1); 6407 m_host.AddScriptLPS(1);
5973 UUID agentId = new UUID(); 6408 UUID uuid = new UUID();
5974 if (!UUID.TryParse(agent, out agentId)) 6409 if (!UUID.TryParse(id, out uuid))
5975 return new LSL_Integer(0); 6410 return new LSL_Integer(0);
5976 ScenePresence presence = World.GetScenePresence(agentId); 6411
5977 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6412 // Check if it's a group key
5978 return new LSL_Integer(0); 6413 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5979 IClientAPI client = presence.ControllingClient;
5980 if (m_host.GroupID == client.ActiveGroupId)
5981 return new LSL_Integer(1); 6414 return new LSL_Integer(1);
5982 else 6415
6416 // We got passed a UUID.Zero
6417 if (uuid == UUID.Zero)
5983 return new LSL_Integer(0); 6418 return new LSL_Integer(0);
6419
6420 // Handle the case where id names an avatar
6421 ScenePresence presence = World.GetScenePresence(uuid);
6422 if (presence != null)
6423 {
6424 if (presence.IsChildAgent)
6425 return new LSL_Integer(0);
6426
6427 IClientAPI client = presence.ControllingClient;
6428 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6429 return new LSL_Integer(1);
6430
6431 return new LSL_Integer(0);
6432 }
6433
6434 // Handle object case
6435 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6436 if (part != null)
6437 {
6438 // This will handle both deed and non-deed and also the no
6439 // group case
6440 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6441 return new LSL_Integer(1);
6442
6443 return new LSL_Integer(0);
6444 }
6445
6446 return new LSL_Integer(0);
5984 } 6447 }
5985 6448
5986 public void llUnSit(string id) 6449 public void llUnSit(string id)
@@ -6105,7 +6568,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6105 return m_host.ParentGroup.AttachmentPoint; 6568 return m_host.ParentGroup.AttachmentPoint;
6106 } 6569 }
6107 6570
6108 public LSL_Integer llGetFreeMemory() 6571 public virtual LSL_Integer llGetFreeMemory()
6109 { 6572 {
6110 m_host.AddScriptLPS(1); 6573 m_host.AddScriptLPS(1);
6111 // Make scripts designed for LSO happy 6574 // Make scripts designed for LSO happy
@@ -6222,7 +6685,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6222 SetParticleSystem(m_host, rules); 6685 SetParticleSystem(m_host, rules);
6223 } 6686 }
6224 6687
6225 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6688 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6689 {
6226 6690
6227 6691
6228 if (rules.Length == 0) 6692 if (rules.Length == 0)
@@ -6537,6 +7001,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6537 7001
6538 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7002 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6539 { 7003 {
7004 // LSL quaternions can normalize to 0, normal Quaternions can't.
7005 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7006 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7007
6540 part.SitTargetPosition = offset; 7008 part.SitTargetPosition = offset;
6541 part.SitTargetOrientation = rot; 7009 part.SitTargetOrientation = rot;
6542 part.ParentGroup.HasGroupChanged = true; 7010 part.ParentGroup.HasGroupChanged = true;
@@ -6692,13 +7160,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6692 UUID av = new UUID(); 7160 UUID av = new UUID();
6693 if (!UUID.TryParse(avatar,out av)) 7161 if (!UUID.TryParse(avatar,out av))
6694 { 7162 {
6695 LSLError("First parameter to llDialog needs to be a key"); 7163 //LSLError("First parameter to llDialog needs to be a key");
6696 return; 7164 return;
6697 } 7165 }
6698 if (buttons.Length < 1) 7166 if (buttons.Length < 1)
6699 { 7167 {
6700 LSLError("No less than 1 button can be shown"); 7168 buttons.Add("OK");
6701 return;
6702 } 7169 }
6703 if (buttons.Length > 12) 7170 if (buttons.Length > 12)
6704 { 7171 {
@@ -6715,7 +7182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6715 } 7182 }
6716 if (buttons.Data[i].ToString().Length > 24) 7183 if (buttons.Data[i].ToString().Length > 24)
6717 { 7184 {
6718 LSLError("button label cannot be longer than 24 characters"); 7185 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6719 return; 7186 return;
6720 } 7187 }
6721 buts[i] = buttons.Data[i].ToString(); 7188 buts[i] = buttons.Data[i].ToString();
@@ -6782,9 +7249,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6782 return; 7249 return;
6783 } 7250 }
6784 7251
6785 // the rest of the permission checks are done in RezScript, so check the pin there as well 7252 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6786 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7253 if (dest != null)
7254 {
7255 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7256 {
7257 // the rest of the permission checks are done in RezScript, so check the pin there as well
7258 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6787 7259
7260 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7261 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7262 }
7263 }
6788 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7264 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6789 ScriptSleep(3000); 7265 ScriptSleep(3000);
6790 } 7266 }
@@ -6847,19 +7323,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6847 public LSL_String llMD5String(string src, int nonce) 7323 public LSL_String llMD5String(string src, int nonce)
6848 { 7324 {
6849 m_host.AddScriptLPS(1); 7325 m_host.AddScriptLPS(1);
6850 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7326 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6851 } 7327 }
6852 7328
6853 public LSL_String llSHA1String(string src) 7329 public LSL_String llSHA1String(string src)
6854 { 7330 {
6855 m_host.AddScriptLPS(1); 7331 m_host.AddScriptLPS(1);
6856 return Util.SHA1Hash(src).ToLower(); 7332 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6857 } 7333 }
6858 7334
6859 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7335 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6860 { 7336 {
6861 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7337 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6862 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7338 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7339 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7340 return shapeBlock;
6863 7341
6864 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7342 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6865 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7343 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6964,6 +7442,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6964 // Prim type box, cylinder and prism. 7442 // Prim type box, cylinder and prism.
6965 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) 7443 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)
6966 { 7444 {
7445 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7446 return;
7447
6967 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7448 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6968 ObjectShapePacket.ObjectDataBlock shapeBlock; 7449 ObjectShapePacket.ObjectDataBlock shapeBlock;
6969 7450
@@ -7017,6 +7498,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7017 // Prim type sphere. 7498 // Prim type sphere.
7018 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7499 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7019 { 7500 {
7501 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7502 return;
7503
7020 ObjectShapePacket.ObjectDataBlock shapeBlock; 7504 ObjectShapePacket.ObjectDataBlock shapeBlock;
7021 7505
7022 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7506 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7058,6 +7542,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7058 // Prim type torus, tube and ring. 7542 // Prim type torus, tube and ring.
7059 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) 7543 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)
7060 { 7544 {
7545 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7546 return;
7547
7061 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7548 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7062 ObjectShapePacket.ObjectDataBlock shapeBlock; 7549 ObjectShapePacket.ObjectDataBlock shapeBlock;
7063 7550
@@ -7193,6 +7680,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7193 // Prim type sculpt. 7680 // Prim type sculpt.
7194 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7681 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7195 { 7682 {
7683 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7684 return;
7685
7196 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7686 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7197 UUID sculptId; 7687 UUID sculptId;
7198 7688
@@ -7217,7 +7707,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7217 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7707 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7218 { 7708 {
7219 // default 7709 // default
7220 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7710 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7221 } 7711 }
7222 7712
7223 part.Shape.SetSculptProperties((byte)type, sculptId); 7713 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7234,48 +7724,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7234 ScriptSleep(200); 7724 ScriptSleep(200);
7235 } 7725 }
7236 7726
7237 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7727 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7238 { 7728 {
7239 m_host.AddScriptLPS(1); 7729 m_host.AddScriptLPS(1);
7240 7730
7241 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7731 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7242 7732
7243 ScriptSleep(200); 7733 ScriptSleep(200);
7244 } 7734 }
7245 7735
7246 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7736 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7247 { 7737 {
7248 m_host.AddScriptLPS(1); 7738 List<object> parts = new List<object>();
7739 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7740 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7741 foreach (SceneObjectPart p in prims)
7742 parts.Add(p);
7743 foreach (ScenePresence p in avatars)
7744 parts.Add(p);
7249 7745
7250 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7746 LSL_List remaining = null;
7747 uint rulesParsed = 0;
7748
7749 if (parts.Count > 0)
7750 {
7751 foreach (object part in parts)
7752 {
7753 if (part is SceneObjectPart)
7754 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7755 else
7756 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7757 }
7758
7759 while ((object)remaining != null && remaining.Length > 2)
7760 {
7761 linknumber = remaining.GetLSLIntegerItem(0);
7762 rules = remaining.GetSublist(1, -1);
7763 parts.Clear();
7764 prims = GetLinkParts(linknumber);
7765 avatars = GetLinkAvatars(linknumber);
7766 foreach (SceneObjectPart p in prims)
7767 parts.Add(p);
7768 foreach (ScenePresence p in avatars)
7769 parts.Add(p);
7770
7771 remaining = null;
7772 foreach (object part in parts)
7773 {
7774 if (part is SceneObjectPart)
7775 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7776 else
7777 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7778 }
7779 }
7780 }
7251 } 7781 }
7252 7782
7253 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7783 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7784 float material_density, float material_friction,
7785 float material_restitution, float material_gravity_modifier)
7254 { 7786 {
7255 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7787 ExtraPhysicsData physdata = new ExtraPhysicsData();
7788 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7789 physdata.Density = part.Density;
7790 physdata.Friction = part.Friction;
7791 physdata.Bounce = part.Bounciness;
7792 physdata.GravitationModifier = part.GravityModifier;
7256 7793
7257 LSL_List remaining = null; 7794 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7258 uint rulesParsed = 0; 7795 physdata.Density = material_density;
7796 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7797 physdata.Friction = material_friction;
7798 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7799 physdata.Bounce = material_restitution;
7800 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7801 physdata.GravitationModifier = material_gravity_modifier;
7259 7802
7260 foreach (SceneObjectPart part in parts) 7803 part.UpdateExtraPhysics(physdata);
7261 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7804 }
7262 7805
7263 while (remaining != null && remaining.Length > 2) 7806 public void llSetPhysicsMaterial(int material_bits,
7264 { 7807 float material_gravity_modifier, float material_restitution,
7265 linknumber = remaining.GetLSLIntegerItem(0); 7808 float material_friction, float material_density)
7266 rules = remaining.GetSublist(1, -1); 7809 {
7267 parts = GetLinkParts(linknumber); 7810 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7811 }
7268 7812
7269 foreach (SceneObjectPart part in parts) 7813 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7270 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7814 {
7815 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7816 llSetLinkPrimitiveParamsFast(linknumber, rules);
7817 ScriptSleep(200);
7818 }
7819
7820 // vector up using libomv (c&p from sop )
7821 // vector up rotated by r
7822 private Vector3 Zrot(Quaternion r)
7823 {
7824 double x, y, z, m;
7825
7826 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7827 if (Math.Abs(1.0 - m) > 0.000001)
7828 {
7829 m = 1.0 / Math.Sqrt(m);
7830 r.X *= (float)m;
7831 r.Y *= (float)m;
7832 r.Z *= (float)m;
7833 r.W *= (float)m;
7271 } 7834 }
7835
7836 x = 2 * (r.X * r.Z + r.Y * r.W);
7837 y = 2 * (-r.X * r.W + r.Y * r.Z);
7838 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7839
7840 return new Vector3((float)x, (float)y, (float)z);
7272 } 7841 }
7273 7842
7274 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7843 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7275 { 7844 {
7845 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7846 return null;
7847
7276 int idx = 0; 7848 int idx = 0;
7277 int idxStart = 0; 7849 int idxStart = 0;
7278 7850
7851 SceneObjectGroup parentgrp = part.ParentGroup;
7852
7279 bool positionChanged = false; 7853 bool positionChanged = false;
7280 LSL_Vector currentPosition = GetPartLocalPos(part); 7854 LSL_Vector currentPosition = GetPartLocalPos(part);
7281 7855
@@ -7300,8 +7874,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7300 return null; 7874 return null;
7301 7875
7302 v=rules.GetVector3Item(idx++); 7876 v=rules.GetVector3Item(idx++);
7303 positionChanged = true;
7304 currentPosition = GetSetPosTarget(part, v, currentPosition); 7877 currentPosition = GetSetPosTarget(part, v, currentPosition);
7878 positionChanged = true;
7305 7879
7306 break; 7880 break;
7307 case (int)ScriptBaseClass.PRIM_SIZE: 7881 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7578,7 +8152,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7578 return null; 8152 return null;
7579 8153
7580 string ph = rules.Data[idx++].ToString(); 8154 string ph = rules.Data[idx++].ToString();
7581 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8155 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7582 8156
7583 break; 8157 break;
7584 8158
@@ -7596,12 +8170,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7596 part.ScriptSetPhysicsStatus(physics); 8170 part.ScriptSetPhysicsStatus(physics);
7597 break; 8171 break;
7598 8172
8173 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8174 if (remain < 1)
8175 return null;
8176
8177 int shape_type = rules.GetLSLIntegerItem(idx++);
8178
8179 ExtraPhysicsData physdata = new ExtraPhysicsData();
8180 physdata.Density = part.Density;
8181 physdata.Bounce = part.Bounciness;
8182 physdata.GravitationModifier = part.GravityModifier;
8183 physdata.PhysShapeType = (PhysShapeType)shape_type;
8184
8185 part.UpdateExtraPhysics(physdata);
8186
8187 break;
8188
8189 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8190 if (remain < 5)
8191 return null;
8192
8193 int material_bits = rules.GetLSLIntegerItem(idx++);
8194 float material_density = (float)rules.GetLSLFloatItem(idx++);
8195 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8196 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8197 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8198
8199 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8200
8201 break;
8202
7599 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8203 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7600 if (remain < 1) 8204 if (remain < 1)
7601 return null; 8205 return null;
7602 string temp = rules.Data[idx++].ToString(); 8206 string temp = rules.Data[idx++].ToString();
7603 8207
7604 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8208 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7605 8209
7606 break; 8210 break;
7607 8211
@@ -7675,7 +8279,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7675 if (part.ParentGroup.RootPart == part) 8279 if (part.ParentGroup.RootPart == part)
7676 { 8280 {
7677 SceneObjectGroup parent = part.ParentGroup; 8281 SceneObjectGroup parent = part.ParentGroup;
7678 parent.UpdateGroupPosition(currentPosition); 8282 Util.FireAndForget(delegate(object x) {
8283 parent.UpdateGroupPosition(currentPosition);
8284 });
7679 } 8285 }
7680 else 8286 else
7681 { 8287 {
@@ -7720,10 +8326,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7720 8326
7721 public LSL_String llXorBase64Strings(string str1, string str2) 8327 public LSL_String llXorBase64Strings(string str1, string str2)
7722 { 8328 {
7723 m_host.AddScriptLPS(1); 8329 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7724 Deprecated("llXorBase64Strings"); 8330
7725 ScriptSleep(300); 8331 ScriptSleep(300);
7726 return String.Empty; 8332 m_host.AddScriptLPS(1);
8333
8334 if (str1 == String.Empty)
8335 return String.Empty;
8336 if (str2 == String.Empty)
8337 return str1;
8338
8339 int len = str2.Length;
8340 if ((len % 4) != 0) // LL is EVIL!!!!
8341 {
8342 while (str2.EndsWith("="))
8343 str2 = str2.Substring(0, str2.Length - 1);
8344
8345 len = str2.Length;
8346 int mod = len % 4;
8347
8348 if (mod == 1)
8349 str2 = str2.Substring(0, str2.Length - 1);
8350 else if (mod == 2)
8351 str2 += "==";
8352 else if (mod == 3)
8353 str2 += "=";
8354 }
8355
8356 byte[] data1;
8357 byte[] data2;
8358 try
8359 {
8360 data1 = Convert.FromBase64String(str1);
8361 data2 = Convert.FromBase64String(str2);
8362 }
8363 catch (Exception)
8364 {
8365 return new LSL_String(String.Empty);
8366 }
8367
8368 // For cases where the decoded length of s2 is greater
8369 // than the decoded length of s1, simply perform a normal
8370 // decode and XOR
8371 //
8372 if (data2.Length >= data1.Length)
8373 {
8374 for (int pos = 0 ; pos < data1.Length ; pos++ )
8375 data1[pos] ^= data2[pos];
8376
8377 return Convert.ToBase64String(data1);
8378 }
8379
8380 // Remove padding
8381 while (str1.EndsWith("="))
8382 str1 = str1.Substring(0, str1.Length - 1);
8383 while (str2.EndsWith("="))
8384 str2 = str2.Substring(0, str2.Length - 1);
8385
8386 byte[] d1 = new byte[str1.Length];
8387 byte[] d2 = new byte[str2.Length];
8388
8389 for (int i = 0 ; i < str1.Length ; i++)
8390 {
8391 int idx = b64.IndexOf(str1.Substring(i, 1));
8392 if (idx == -1)
8393 idx = 0;
8394 d1[i] = (byte)idx;
8395 }
8396
8397 for (int i = 0 ; i < str2.Length ; i++)
8398 {
8399 int idx = b64.IndexOf(str2.Substring(i, 1));
8400 if (idx == -1)
8401 idx = 0;
8402 d2[i] = (byte)idx;
8403 }
8404
8405 string output = String.Empty;
8406
8407 for (int pos = 0 ; pos < d1.Length ; pos++)
8408 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8409
8410 while (output.Length % 3 > 0)
8411 output += "=";
8412
8413 return output;
7727 } 8414 }
7728 8415
7729 public void llRemoteDataSetRegion() 8416 public void llRemoteDataSetRegion()
@@ -7847,13 +8534,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7847 public LSL_Integer llGetNumberOfPrims() 8534 public LSL_Integer llGetNumberOfPrims()
7848 { 8535 {
7849 m_host.AddScriptLPS(1); 8536 m_host.AddScriptLPS(1);
7850 int avatarCount = 0; 8537 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7851 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8538
7852 {
7853 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7854 avatarCount++;
7855 });
7856
7857 return m_host.ParentGroup.PrimCount + avatarCount; 8539 return m_host.ParentGroup.PrimCount + avatarCount;
7858 } 8540 }
7859 8541
@@ -7869,55 +8551,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7869 m_host.AddScriptLPS(1); 8551 m_host.AddScriptLPS(1);
7870 UUID objID = UUID.Zero; 8552 UUID objID = UUID.Zero;
7871 LSL_List result = new LSL_List(); 8553 LSL_List result = new LSL_List();
8554
8555 // If the ID is not valid, return null result
7872 if (!UUID.TryParse(obj, out objID)) 8556 if (!UUID.TryParse(obj, out objID))
7873 { 8557 {
7874 result.Add(new LSL_Vector()); 8558 result.Add(new LSL_Vector());
7875 result.Add(new LSL_Vector()); 8559 result.Add(new LSL_Vector());
7876 return result; 8560 return result;
7877 } 8561 }
8562
8563 // Check if this is an attached prim. If so, replace
8564 // the UUID with the avatar UUID and report it's bounding box
8565 SceneObjectPart part = World.GetSceneObjectPart(objID);
8566 if (part != null && part.ParentGroup.IsAttachment)
8567 objID = part.ParentGroup.AttachedAvatar;
8568
8569 // Find out if this is an avatar ID. If so, return it's box
7878 ScenePresence presence = World.GetScenePresence(objID); 8570 ScenePresence presence = World.GetScenePresence(objID);
7879 if (presence != null) 8571 if (presence != null)
7880 { 8572 {
7881 if (presence.ParentID == 0) // not sat on an object 8573 // As per LSL Wiki, there is no difference between sitting
8574 // and standing avatar since server 1.36
8575 LSL_Vector lower;
8576 LSL_Vector upper;
8577 if (presence.Animator.Animations.DefaultAnimation.AnimID
8578 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7882 { 8579 {
7883 LSL_Vector lower; 8580 // This is for ground sitting avatars
7884 LSL_Vector upper; 8581 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7885 if (presence.Animator.Animations.DefaultAnimation.AnimID 8582 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7886 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8583 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7887 {
7888 // This is for ground sitting avatars
7889 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7890 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7891 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7892 }
7893 else
7894 {
7895 // This is for standing/flying avatars
7896 float height = presence.Appearance.AvatarHeight / 2.0f;
7897 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7898 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7899 }
7900 result.Add(lower);
7901 result.Add(upper);
7902 return result;
7903 } 8584 }
7904 else 8585 else
7905 { 8586 {
7906 // sitting on an object so we need the bounding box of that 8587 // This is for standing/flying avatars
7907 // which should include the avatar so set the UUID to the 8588 float height = presence.Appearance.AvatarHeight / 2.0f;
7908 // UUID of the object the avatar is sat on and allow it to fall through 8589 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7909 // to processing an object 8590 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7910 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7911 objID = p.UUID;
7912 } 8591 }
8592
8593 // Adjust to the documented error offsets (see LSL Wiki)
8594 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8595 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8596
8597 if (lower.x > upper.x)
8598 lower.x = upper.x;
8599 if (lower.y > upper.y)
8600 lower.y = upper.y;
8601 if (lower.z > upper.z)
8602 lower.z = upper.z;
8603
8604 result.Add(lower);
8605 result.Add(upper);
8606 return result;
7913 } 8607 }
7914 SceneObjectPart part = World.GetSceneObjectPart(objID); 8608
8609 part = World.GetSceneObjectPart(objID);
7915 // Currently only works for single prims without a sitting avatar 8610 // Currently only works for single prims without a sitting avatar
7916 if (part != null) 8611 if (part != null)
7917 { 8612 {
7918 Vector3 halfSize = part.Scale / 2.0f; 8613 float minX;
7919 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8614 float maxX;
7920 LSL_Vector upper = new LSL_Vector(halfSize); 8615 float minY;
8616 float maxY;
8617 float minZ;
8618 float maxZ;
8619
8620 // This BBox is in sim coordinates, with the offset being
8621 // a contained point.
8622 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8623 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8624
8625 minX -= offsets[0].X;
8626 maxX -= offsets[0].X;
8627 minY -= offsets[0].Y;
8628 maxY -= offsets[0].Y;
8629 minZ -= offsets[0].Z;
8630 maxZ -= offsets[0].Z;
8631
8632 LSL_Vector lower;
8633 LSL_Vector upper;
8634
8635 // Adjust to the documented error offsets (see LSL Wiki)
8636 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8637 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8638
8639 if (lower.x > upper.x)
8640 lower.x = upper.x;
8641 if (lower.y > upper.y)
8642 lower.y = upper.y;
8643 if (lower.z > upper.z)
8644 lower.z = upper.z;
8645
7921 result.Add(lower); 8646 result.Add(lower);
7922 result.Add(upper); 8647 result.Add(upper);
7923 return result; 8648 return result;
@@ -7931,7 +8656,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7931 8656
7932 public LSL_Vector llGetGeometricCenter() 8657 public LSL_Vector llGetGeometricCenter()
7933 { 8658 {
7934 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8659 Vector3 tmp = m_host.GetGeometricCenter();
8660 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7935 } 8661 }
7936 8662
7937 public LSL_List llGetPrimitiveParams(LSL_List rules) 8663 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7959,24 +8685,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7959 { 8685 {
7960 m_host.AddScriptLPS(1); 8686 m_host.AddScriptLPS(1);
7961 8687
7962 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8688 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8689 // keep other options as before
7963 8690
8691 List<SceneObjectPart> parts;
8692 List<ScenePresence> avatars;
8693
7964 LSL_List res = new LSL_List(); 8694 LSL_List res = new LSL_List();
7965 LSL_List remaining = null; 8695 LSL_List remaining = null;
7966 8696
7967 foreach (SceneObjectPart part in parts) 8697 while (rules.Length > 0)
7968 { 8698 {
7969 remaining = GetPrimParams(part, rules, ref res);
7970 }
7971
7972 while (remaining != null && remaining.Length > 2)
7973 {
7974 linknumber = remaining.GetLSLIntegerItem(0);
7975 rules = remaining.GetSublist(1, -1);
7976 parts = GetLinkParts(linknumber); 8699 parts = GetLinkParts(linknumber);
8700 avatars = GetLinkAvatars(linknumber);
7977 8701
8702 remaining = null;
7978 foreach (SceneObjectPart part in parts) 8703 foreach (SceneObjectPart part in parts)
8704 {
7979 remaining = GetPrimParams(part, rules, ref res); 8705 remaining = GetPrimParams(part, rules, ref res);
8706 }
8707 foreach (ScenePresence avatar in avatars)
8708 {
8709 remaining = GetPrimParams(avatar, rules, ref res);
8710 }
8711
8712 if (remaining != null && remaining.Length > 0)
8713 {
8714 linknumber = remaining.GetLSLIntegerItem(0);
8715 rules = remaining.GetSublist(1, -1);
8716 }
7980 } 8717 }
7981 8718
7982 return res; 8719 return res;
@@ -8021,13 +8758,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8021 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8758 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8022 part.AbsolutePosition.Y, 8759 part.AbsolutePosition.Y,
8023 part.AbsolutePosition.Z); 8760 part.AbsolutePosition.Z);
8024 // For some reason, the part.AbsolutePosition.* values do not change if the
8025 // linkset is rotated; they always reflect the child prim's world position
8026 // as though the linkset is unrotated. This is incompatible behavior with SL's
8027 // implementation, so will break scripts imported from there (not to mention it
8028 // makes it more difficult to determine a child prim's actual inworld position).
8029 if (part.ParentID != 0)
8030 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8031 res.Add(v); 8761 res.Add(v);
8032 break; 8762 break;
8033 8763
@@ -8199,30 +8929,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8199 if (remain < 1) 8929 if (remain < 1)
8200 return null; 8930 return null;
8201 8931
8202 face=(int)rules.GetLSLIntegerItem(idx++); 8932 face = (int)rules.GetLSLIntegerItem(idx++);
8203 8933
8204 tex = part.Shape.Textures; 8934 tex = part.Shape.Textures;
8935 int shiny;
8205 if (face == ScriptBaseClass.ALL_SIDES) 8936 if (face == ScriptBaseClass.ALL_SIDES)
8206 { 8937 {
8207 for (face = 0; face < GetNumberOfSides(part); face++) 8938 for (face = 0; face < GetNumberOfSides(part); face++)
8208 { 8939 {
8209 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8940 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8210 // Convert Shininess to PRIM_SHINY_* 8941 if (shinyness == Shininess.High)
8211 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8942 {
8212 // PRIM_BUMP_* 8943 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8213 res.Add(new LSL_Integer((int)texface.Bump)); 8944 }
8945 else if (shinyness == Shininess.Medium)
8946 {
8947 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8948 }
8949 else if (shinyness == Shininess.Low)
8950 {
8951 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8952 }
8953 else
8954 {
8955 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8956 }
8957 res.Add(new LSL_Integer(shiny));
8958 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8214 } 8959 }
8215 } 8960 }
8216 else 8961 else
8217 { 8962 {
8218 if (face >= 0 && face < GetNumberOfSides(part)) 8963 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8964 if (shinyness == Shininess.High)
8219 { 8965 {
8220 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8966 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8221 // Convert Shininess to PRIM_SHINY_* 8967 }
8222 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8968 else if (shinyness == Shininess.Medium)
8223 // PRIM_BUMP_* 8969 {
8224 res.Add(new LSL_Integer((int)texface.Bump)); 8970 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8971 }
8972 else if (shinyness == Shininess.Low)
8973 {
8974 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8225 } 8975 }
8976 else
8977 {
8978 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8979 }
8980 res.Add(new LSL_Integer(shiny));
8981 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8226 } 8982 }
8227 break; 8983 break;
8228 8984
@@ -8230,24 +8986,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8230 if (remain < 1) 8986 if (remain < 1)
8231 return null; 8987 return null;
8232 8988
8233 face=(int)rules.GetLSLIntegerItem(idx++); 8989 face = (int)rules.GetLSLIntegerItem(idx++);
8234 8990
8235 tex = part.Shape.Textures; 8991 tex = part.Shape.Textures;
8992 int fullbright;
8236 if (face == ScriptBaseClass.ALL_SIDES) 8993 if (face == ScriptBaseClass.ALL_SIDES)
8237 { 8994 {
8238 for (face = 0; face < GetNumberOfSides(part); face++) 8995 for (face = 0; face < GetNumberOfSides(part); face++)
8239 { 8996 {
8240 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8997 if (tex.GetFace((uint)face).Fullbright == true)
8241 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8998 {
8999 fullbright = ScriptBaseClass.TRUE;
9000 }
9001 else
9002 {
9003 fullbright = ScriptBaseClass.FALSE;
9004 }
9005 res.Add(new LSL_Integer(fullbright));
8242 } 9006 }
8243 } 9007 }
8244 else 9008 else
8245 { 9009 {
8246 if (face >= 0 && face < GetNumberOfSides(part)) 9010 if (tex.GetFace((uint)face).Fullbright == true)
8247 { 9011 {
8248 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9012 fullbright = ScriptBaseClass.TRUE;
8249 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8250 } 9013 }
9014 else
9015 {
9016 fullbright = ScriptBaseClass.FALSE;
9017 }
9018 res.Add(new LSL_Integer(fullbright));
8251 } 9019 }
8252 break; 9020 break;
8253 9021
@@ -8269,27 +9037,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8269 break; 9037 break;
8270 9038
8271 case (int)ScriptBaseClass.PRIM_TEXGEN: 9039 case (int)ScriptBaseClass.PRIM_TEXGEN:
9040 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8272 if (remain < 1) 9041 if (remain < 1)
8273 return null; 9042 return null;
8274 9043
8275 face=(int)rules.GetLSLIntegerItem(idx++); 9044 face = (int)rules.GetLSLIntegerItem(idx++);
8276 9045
8277 tex = part.Shape.Textures; 9046 tex = part.Shape.Textures;
8278 if (face == ScriptBaseClass.ALL_SIDES) 9047 if (face == ScriptBaseClass.ALL_SIDES)
8279 { 9048 {
8280 for (face = 0; face < GetNumberOfSides(part); face++) 9049 for (face = 0; face < GetNumberOfSides(part); face++)
8281 { 9050 {
8282 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9051 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8283 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9052 {
8284 res.Add(new LSL_Integer((uint)texgen >> 1)); 9053 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9054 }
9055 else
9056 {
9057 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9058 }
8285 } 9059 }
8286 } 9060 }
8287 else 9061 else
8288 { 9062 {
8289 if (face >= 0 && face < GetNumberOfSides(part)) 9063 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8290 { 9064 {
8291 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9065 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8292 res.Add(new LSL_Integer((uint)texgen >> 1)); 9066 }
9067 else
9068 {
9069 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8293 } 9070 }
8294 } 9071 }
8295 break; 9072 break;
@@ -8313,24 +9090,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8313 if (remain < 1) 9090 if (remain < 1)
8314 return null; 9091 return null;
8315 9092
8316 face=(int)rules.GetLSLIntegerItem(idx++); 9093 face = (int)rules.GetLSLIntegerItem(idx++);
8317 9094
8318 tex = part.Shape.Textures; 9095 tex = part.Shape.Textures;
9096 float primglow;
8319 if (face == ScriptBaseClass.ALL_SIDES) 9097 if (face == ScriptBaseClass.ALL_SIDES)
8320 { 9098 {
8321 for (face = 0; face < GetNumberOfSides(part); face++) 9099 for (face = 0; face < GetNumberOfSides(part); face++)
8322 { 9100 {
8323 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9101 primglow = tex.GetFace((uint)face).Glow;
8324 res.Add(new LSL_Float(texface.Glow)); 9102 res.Add(new LSL_Float(primglow));
8325 } 9103 }
8326 } 9104 }
8327 else 9105 else
8328 { 9106 {
8329 if (face >= 0 && face < GetNumberOfSides(part)) 9107 primglow = tex.GetFace((uint)face).Glow;
8330 { 9108 res.Add(new LSL_Float(primglow));
8331 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8332 res.Add(new LSL_Float(texface.Glow));
8333 }
8334 } 9109 }
8335 break; 9110 break;
8336 9111
@@ -8342,15 +9117,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8342 textColor.B)); 9117 textColor.B));
8343 res.Add(new LSL_Float(textColor.A)); 9118 res.Add(new LSL_Float(textColor.A));
8344 break; 9119 break;
9120
8345 case (int)ScriptBaseClass.PRIM_NAME: 9121 case (int)ScriptBaseClass.PRIM_NAME:
8346 res.Add(new LSL_String(part.Name)); 9122 res.Add(new LSL_String(part.Name));
8347 break; 9123 break;
9124
8348 case (int)ScriptBaseClass.PRIM_DESC: 9125 case (int)ScriptBaseClass.PRIM_DESC:
8349 res.Add(new LSL_String(part.Description)); 9126 res.Add(new LSL_String(part.Description));
8350 break; 9127 break;
9128
8351 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9129 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8352 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9130 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8353 break; 9131 break;
9132
8354 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9133 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8355 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9134 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8356 break; 9135 break;
@@ -8961,8 +9740,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8961 // The function returns an ordered list 9740 // The function returns an ordered list
8962 // representing the tokens found in the supplied 9741 // representing the tokens found in the supplied
8963 // sources string. If two successive tokenizers 9742 // sources string. If two successive tokenizers
8964 // are encountered, then a NULL entry is added 9743 // are encountered, then a null-string entry is
8965 // to the list. 9744 // added to the list.
8966 // 9745 //
8967 // It is a precondition that the source and 9746 // It is a precondition that the source and
8968 // toekizer lisst are non-null. If they are null, 9747 // toekizer lisst are non-null. If they are null,
@@ -8970,7 +9749,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8970 // while their lengths are being determined. 9749 // while their lengths are being determined.
8971 // 9750 //
8972 // A small amount of working memoryis required 9751 // A small amount of working memoryis required
8973 // of approximately 8*#tokenizers. 9752 // of approximately 8*#tokenizers + 8*srcstrlen.
8974 // 9753 //
8975 // There are many ways in which this function 9754 // There are many ways in which this function
8976 // can be implemented, this implementation is 9755 // can be implemented, this implementation is
@@ -8986,155 +9765,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8986 // and eliminates redundant tokenizers as soon 9765 // and eliminates redundant tokenizers as soon
8987 // as is possible. 9766 // as is possible.
8988 // 9767 //
8989 // The implementation tries to avoid any copying 9768 // The implementation tries to minimize temporary
8990 // of arrays or other objects. 9769 // garbage generation.
8991 // </remarks> 9770 // </remarks>
8992 9771
8993 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9772 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8994 { 9773 {
8995 int beginning = 0; 9774 return ParseString2List(src, separators, spacers, true);
8996 int srclen = src.Length; 9775 }
8997 int seplen = separators.Length;
8998 object[] separray = separators.Data;
8999 int spclen = spacers.Length;
9000 object[] spcarray = spacers.Data;
9001 int mlen = seplen+spclen;
9002
9003 int[] offset = new int[mlen+1];
9004 bool[] active = new bool[mlen];
9005
9006 int best;
9007 int j;
9008
9009 // Initial capacity reduces resize cost
9010 9776
9011 LSL_List tokens = new LSL_List(); 9777 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9778 {
9779 int srclen = src.Length;
9780 int seplen = separators.Length;
9781 object[] separray = separators.Data;
9782 int spclen = spacers.Length;
9783 object[] spcarray = spacers.Data;
9784 int dellen = 0;
9785 string[] delarray = new string[seplen+spclen];
9012 9786
9013 // All entries are initially valid 9787 int outlen = 0;
9788 string[] outarray = new string[srclen*2+1];
9014 9789
9015 for (int i = 0; i < mlen; i++) 9790 int i, j;
9016 active[i] = true; 9791 string d;
9017 9792
9018 offset[mlen] = srclen; 9793 m_host.AddScriptLPS(1);
9019 9794
9020 while (beginning < srclen) 9795 /*
9796 * Convert separator and spacer lists to C# strings.
9797 * Also filter out null strings so we don't hang.
9798 */
9799 for (i = 0; i < seplen; i ++)
9021 { 9800 {
9801 d = separray[i].ToString();
9802 if (d.Length > 0)
9803 {
9804 delarray[dellen++] = d;
9805 }
9806 }
9807 seplen = dellen;
9022 9808
9023 best = mlen; // as bad as it gets 9809 for (i = 0; i < spclen; i ++)
9810 {
9811 d = spcarray[i].ToString();
9812 if (d.Length > 0)
9813 {
9814 delarray[dellen++] = d;
9815 }
9816 }
9024 9817
9025 // Scan for separators 9818 /*
9819 * Scan through source string from beginning to end.
9820 */
9821 for (i = 0;;)
9822 {
9026 9823
9027 for (j = 0; j < seplen; j++) 9824 /*
9825 * Find earliest delimeter in src starting at i (if any).
9826 */
9827 int earliestDel = -1;
9828 int earliestSrc = srclen;
9829 string earliestStr = null;
9830 for (j = 0; j < dellen; j ++)
9028 { 9831 {
9029 if (separray[j].ToString() == String.Empty) 9832 d = delarray[j];
9030 active[j] = false; 9833 if (d != null)
9031
9032 if (active[j])
9033 { 9834 {
9034 // scan all of the markers 9835 int index = src.IndexOf(d, i);
9035 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9836 if (index < 0)
9036 { 9837 {
9037 // not present at all 9838 delarray[j] = null; // delim nowhere in src, don't check it anymore
9038 active[j] = false;
9039 } 9839 }
9040 else 9840 else if (index < earliestSrc)
9041 { 9841 {
9042 // present and correct 9842 earliestSrc = index; // where delimeter starts in source string
9043 if (offset[j] < offset[best]) 9843 earliestDel = j; // where delimeter is in delarray[]
9044 { 9844 earliestStr = d; // the delimeter string from delarray[]
9045 // closest so far 9845 if (index == i) break; // can't do any better than found at beg of string
9046 best = j;
9047 if (offset[best] == beginning)
9048 break;
9049 }
9050 } 9846 }
9051 } 9847 }
9052 } 9848 }
9053 9849
9054 // Scan for spacers 9850 /*
9055 9851 * Output source string starting at i through start of earliest delimeter.
9056 if (offset[best] != beginning) 9852 */
9853 if (keepNulls || (earliestSrc > i))
9057 { 9854 {
9058 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9855 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9059 {
9060 if (spcarray[j-seplen].ToString() == String.Empty)
9061 active[j] = false;
9062
9063 if (active[j])
9064 {
9065 // scan all of the markers
9066 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9067 {
9068 // not present at all
9069 active[j] = false;
9070 }
9071 else
9072 {
9073 // present and correct
9074 if (offset[j] < offset[best])
9075 {
9076 // closest so far
9077 best = j;
9078 }
9079 }
9080 }
9081 }
9082 } 9856 }
9083 9857
9084 // This is the normal exit from the scanning loop 9858 /*
9859 * If no delimeter found at or after i, we're done scanning.
9860 */
9861 if (earliestDel < 0) break;
9085 9862
9086 if (best == mlen) 9863 /*
9864 * If delimeter was a spacer, output the spacer.
9865 */
9866 if (earliestDel >= seplen)
9087 { 9867 {
9088 // no markers were found on this pass 9868 outarray[outlen++] = earliestStr;
9089 // so we're pretty much done
9090 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9091 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9092 break;
9093 } 9869 }
9094 9870
9095 // Otherwise we just add the newly delimited token 9871 /*
9096 // and recalculate where the search should continue. 9872 * Look at rest of src string following delimeter.
9097 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9873 */
9098 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9874 i = earliestSrc + earliestStr.Length;
9099
9100 if (best < seplen)
9101 {
9102 beginning = offset[best] + (separray[best].ToString()).Length;
9103 }
9104 else
9105 {
9106 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9107 string str = spcarray[best - seplen].ToString();
9108 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9109 tokens.Add(new LSL_String(str));
9110 }
9111 } 9875 }
9112 9876
9113 // This an awkward an not very intuitive boundary case. If the 9877 /*
9114 // last substring is a tokenizer, then there is an implied trailing 9878 * Make up an exact-sized output array suitable for an LSL_List object.
9115 // null list entry. Hopefully the single comparison will not be too 9879 */
9116 // arduous. Alternatively the 'break' could be replced with a return 9880 object[] outlist = new object[outlen];
9117 // but that's shabby programming. 9881 for (i = 0; i < outlen; i ++)
9118
9119 if ((beginning == srclen) && (keepNulls))
9120 { 9882 {
9121 if (srclen != 0) 9883 outlist[i] = new LSL_String(outarray[i]);
9122 tokens.Add(new LSL_String(""));
9123 } 9884 }
9124 9885 return new LSL_List(outlist);
9125 return tokens;
9126 }
9127
9128 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9129 {
9130 m_host.AddScriptLPS(1);
9131 return this.ParseString(src, separators, spacers, false);
9132 }
9133
9134 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9135 {
9136 m_host.AddScriptLPS(1);
9137 return this.ParseString(src, separators, spacers, true);
9138 } 9886 }
9139 9887
9140 public LSL_Integer llGetObjectPermMask(int mask) 9888 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9229,6 +9977,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9229 case 4: 9977 case 4:
9230 return (int)item.NextPermissions; 9978 return (int)item.NextPermissions;
9231 } 9979 }
9980 m_host.TaskInventory.LockItemsForRead(false);
9232 9981
9233 return -1; 9982 return -1;
9234 } 9983 }
@@ -9431,31 +10180,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9431 UUID key = new UUID(); 10180 UUID key = new UUID();
9432 if (UUID.TryParse(id, out key)) 10181 if (UUID.TryParse(id, out key))
9433 { 10182 {
9434 try 10183 // return total object mass
9435 { 10184 SceneObjectPart part = World.GetSceneObjectPart(key);
9436 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10185 if (part != null)
9437 if (obj != null) 10186 return part.ParentGroup.GetMass();
9438 return (double)obj.GetMass(); 10187
9439 // the object is null so the key is for an avatar 10188 // the object is null so the key is for an avatar
9440 ScenePresence avatar = World.GetScenePresence(key); 10189 ScenePresence avatar = World.GetScenePresence(key);
9441 if (avatar != null) 10190 if (avatar != null)
9442 if (avatar.IsChildAgent)
9443 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9444 // child agents have a mass of 1.0
9445 return 1;
9446 else
9447 return (double)avatar.GetMass();
9448 }
9449 catch (KeyNotFoundException)
9450 { 10191 {
9451 return 0; // The Object/Agent not in the region so just return zero 10192 if (avatar.IsChildAgent)
10193 {
10194 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10195 // child agents have a mass of 1.0
10196 return 1;
10197 }
10198 else
10199 {
10200 return (double)avatar.GetMass();
10201 }
9452 } 10202 }
9453 } 10203 }
9454 return 0; 10204 return 0;
9455 } 10205 }
9456 10206
9457 /// <summary> 10207 /// <summary>
9458 /// illListReplaceList removes the sub-list defined by the inclusive indices 10208 /// llListReplaceList removes the sub-list defined by the inclusive indices
9459 /// start and end and inserts the src list in its place. The inclusive 10209 /// start and end and inserts the src list in its place. The inclusive
9460 /// nature of the indices means that at least one element must be deleted 10210 /// nature of the indices means that at least one element must be deleted
9461 /// if the indices are within the bounds of the existing list. I.e. 2,2 10211 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9512,16 +10262,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9512 // based upon end. Note that if end exceeds the upper 10262 // based upon end. Note that if end exceeds the upper
9513 // bound in this case, the entire destination list 10263 // bound in this case, the entire destination list
9514 // is removed. 10264 // is removed.
9515 else 10265 else if (start == 0)
9516 { 10266 {
9517 if (end + 1 < dest.Length) 10267 if (end + 1 < dest.Length)
9518 {
9519 return src + dest.GetSublist(end + 1, -1); 10268 return src + dest.GetSublist(end + 1, -1);
9520 }
9521 else 10269 else
9522 {
9523 return src; 10270 return src;
9524 } 10271 }
10272 else // Start < 0
10273 {
10274 if (end + 1 < dest.Length)
10275 return dest.GetSublist(end + 1, -1);
10276 else
10277 return new LSL_List();
9525 } 10278 }
9526 } 10279 }
9527 // Finally, if start > end, we strip away a prefix and 10280 // Finally, if start > end, we strip away a prefix and
@@ -9572,17 +10325,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9572 int width = 0; 10325 int width = 0;
9573 int height = 0; 10326 int height = 0;
9574 10327
9575 ParcelMediaCommandEnum? commandToSend = null; 10328 uint commandToSend = 0;
9576 float time = 0.0f; // default is from start 10329 float time = 0.0f; // default is from start
9577 10330
9578 ScenePresence presence = null; 10331 ScenePresence presence = null;
9579 10332
9580 for (int i = 0; i < commandList.Data.Length; i++) 10333 for (int i = 0; i < commandList.Data.Length; i++)
9581 { 10334 {
9582 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10335 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9583 switch (command) 10336 switch (command)
9584 { 10337 {
9585 case ParcelMediaCommandEnum.Agent: 10338 case (uint)ParcelMediaCommandEnum.Agent:
9586 // we send only to one agent 10339 // we send only to one agent
9587 if ((i + 1) < commandList.Length) 10340 if ((i + 1) < commandList.Length)
9588 { 10341 {
@@ -9599,25 +10352,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9599 } 10352 }
9600 break; 10353 break;
9601 10354
9602 case ParcelMediaCommandEnum.Loop: 10355 case (uint)ParcelMediaCommandEnum.Loop:
9603 loop = 1; 10356 loop = 1;
9604 commandToSend = command; 10357 commandToSend = command;
9605 update = true; //need to send the media update packet to set looping 10358 update = true; //need to send the media update packet to set looping
9606 break; 10359 break;
9607 10360
9608 case ParcelMediaCommandEnum.Play: 10361 case (uint)ParcelMediaCommandEnum.Play:
9609 loop = 0; 10362 loop = 0;
9610 commandToSend = command; 10363 commandToSend = command;
9611 update = true; //need to send the media update packet to make sure it doesn't loop 10364 update = true; //need to send the media update packet to make sure it doesn't loop
9612 break; 10365 break;
9613 10366
9614 case ParcelMediaCommandEnum.Pause: 10367 case (uint)ParcelMediaCommandEnum.Pause:
9615 case ParcelMediaCommandEnum.Stop: 10368 case (uint)ParcelMediaCommandEnum.Stop:
9616 case ParcelMediaCommandEnum.Unload: 10369 case (uint)ParcelMediaCommandEnum.Unload:
9617 commandToSend = command; 10370 commandToSend = command;
9618 break; 10371 break;
9619 10372
9620 case ParcelMediaCommandEnum.Url: 10373 case (uint)ParcelMediaCommandEnum.Url:
9621 if ((i + 1) < commandList.Length) 10374 if ((i + 1) < commandList.Length)
9622 { 10375 {
9623 if (commandList.Data[i + 1] is LSL_String) 10376 if (commandList.Data[i + 1] is LSL_String)
@@ -9630,7 +10383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9630 } 10383 }
9631 break; 10384 break;
9632 10385
9633 case ParcelMediaCommandEnum.Texture: 10386 case (uint)ParcelMediaCommandEnum.Texture:
9634 if ((i + 1) < commandList.Length) 10387 if ((i + 1) < commandList.Length)
9635 { 10388 {
9636 if (commandList.Data[i + 1] is LSL_String) 10389 if (commandList.Data[i + 1] is LSL_String)
@@ -9643,7 +10396,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9643 } 10396 }
9644 break; 10397 break;
9645 10398
9646 case ParcelMediaCommandEnum.Time: 10399 case (uint)ParcelMediaCommandEnum.Time:
9647 if ((i + 1) < commandList.Length) 10400 if ((i + 1) < commandList.Length)
9648 { 10401 {
9649 if (commandList.Data[i + 1] is LSL_Float) 10402 if (commandList.Data[i + 1] is LSL_Float)
@@ -9655,7 +10408,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9655 } 10408 }
9656 break; 10409 break;
9657 10410
9658 case ParcelMediaCommandEnum.AutoAlign: 10411 case (uint)ParcelMediaCommandEnum.AutoAlign:
9659 if ((i + 1) < commandList.Length) 10412 if ((i + 1) < commandList.Length)
9660 { 10413 {
9661 if (commandList.Data[i + 1] is LSL_Integer) 10414 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9669,7 +10422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9669 } 10422 }
9670 break; 10423 break;
9671 10424
9672 case ParcelMediaCommandEnum.Type: 10425 case (uint)ParcelMediaCommandEnum.Type:
9673 if ((i + 1) < commandList.Length) 10426 if ((i + 1) < commandList.Length)
9674 { 10427 {
9675 if (commandList.Data[i + 1] is LSL_String) 10428 if (commandList.Data[i + 1] is LSL_String)
@@ -9682,7 +10435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9682 } 10435 }
9683 break; 10436 break;
9684 10437
9685 case ParcelMediaCommandEnum.Desc: 10438 case (uint)ParcelMediaCommandEnum.Desc:
9686 if ((i + 1) < commandList.Length) 10439 if ((i + 1) < commandList.Length)
9687 { 10440 {
9688 if (commandList.Data[i + 1] is LSL_String) 10441 if (commandList.Data[i + 1] is LSL_String)
@@ -9695,7 +10448,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9695 } 10448 }
9696 break; 10449 break;
9697 10450
9698 case ParcelMediaCommandEnum.Size: 10451 case (uint)ParcelMediaCommandEnum.Size:
9699 if ((i + 2) < commandList.Length) 10452 if ((i + 2) < commandList.Length)
9700 { 10453 {
9701 if (commandList.Data[i + 1] is LSL_Integer) 10454 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9765,7 +10518,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9765 } 10518 }
9766 } 10519 }
9767 10520
9768 if (commandToSend != null) 10521 if (commandToSend != 0)
9769 { 10522 {
9770 // the commandList contained a start/stop/... command, too 10523 // the commandList contained a start/stop/... command, too
9771 if (presence == null) 10524 if (presence == null)
@@ -9802,7 +10555,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9802 10555
9803 if (aList.Data[i] != null) 10556 if (aList.Data[i] != null)
9804 { 10557 {
9805 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10558 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9806 { 10559 {
9807 case ParcelMediaCommandEnum.Url: 10560 case ParcelMediaCommandEnum.Url:
9808 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10561 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9859,15 +10612,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9859 10612
9860 if (quick_pay_buttons.Data.Length < 4) 10613 if (quick_pay_buttons.Data.Length < 4)
9861 { 10614 {
9862 LSLError("List must have at least 4 elements"); 10615 int x;
9863 return; 10616 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10617 {
10618 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10619 }
9864 } 10620 }
9865 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10621 int[] nPrice = new int[5];
9866 10622 nPrice[0] = price;
9867 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10623 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9868 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10624 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9869 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10625 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9870 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10626 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10627 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9871 m_host.ParentGroup.HasGroupChanged = true; 10628 m_host.ParentGroup.HasGroupChanged = true;
9872 } 10629 }
9873 10630
@@ -9884,7 +10641,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9884 return new LSL_Vector(); 10641 return new LSL_Vector();
9885 } 10642 }
9886 10643
9887 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10644// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10645 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9888 if (presence != null) 10646 if (presence != null)
9889 { 10647 {
9890 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10648 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9906,7 +10664,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9906 return new LSL_Rotation(); 10664 return new LSL_Rotation();
9907 } 10665 }
9908 10666
9909 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10667// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10668 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9910 if (presence != null) 10669 if (presence != null)
9911 { 10670 {
9912 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10671 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9966,14 +10725,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9966 { 10725 {
9967 m_host.AddScriptLPS(1); 10726 m_host.AddScriptLPS(1);
9968 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10727 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9969 if (detectedParams == null) return; // only works on the first detected avatar 10728 if (detectedParams == null)
9970 10729 {
10730 if (m_host.ParentGroup.IsAttachment == true)
10731 {
10732 detectedParams = new DetectParams();
10733 detectedParams.Key = m_host.OwnerID;
10734 }
10735 else
10736 {
10737 return;
10738 }
10739 }
10740
9971 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10741 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9972 if (avatar != null) 10742 if (avatar != null)
9973 { 10743 {
9974 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10744 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9975 simname, pos, lookAt); 10745 simname, pos, lookAt);
9976 } 10746 }
10747
9977 ScriptSleep(1000); 10748 ScriptSleep(1000);
9978 } 10749 }
9979 10750
@@ -10097,12 +10868,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10097 10868
10098 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10869 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10099 object[] data = rules.Data; 10870 object[] data = rules.Data;
10100 for (int i = 0; i < data.Length; ++i) { 10871 for (int i = 0; i < data.Length; ++i)
10872 {
10101 int type = Convert.ToInt32(data[i++].ToString()); 10873 int type = Convert.ToInt32(data[i++].ToString());
10102 if (i >= data.Length) break; // odd number of entries => ignore the last 10874 if (i >= data.Length) break; // odd number of entries => ignore the last
10103 10875
10104 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10876 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10105 switch (type) { 10877 switch (type)
10878 {
10106 case ScriptBaseClass.CAMERA_FOCUS: 10879 case ScriptBaseClass.CAMERA_FOCUS:
10107 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10880 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10108 case ScriptBaseClass.CAMERA_POSITION: 10881 case ScriptBaseClass.CAMERA_POSITION:
@@ -10207,19 +10980,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10207 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10980 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10208 { 10981 {
10209 m_host.AddScriptLPS(1); 10982 m_host.AddScriptLPS(1);
10210 string ret = String.Empty; 10983
10211 string src1 = llBase64ToString(str1); 10984 if (str1 == String.Empty)
10212 string src2 = llBase64ToString(str2); 10985 return String.Empty;
10213 int c = 0; 10986 if (str2 == String.Empty)
10214 for (int i = 0; i < src1.Length; i++) 10987 return str1;
10988
10989 int len = str2.Length;
10990 if ((len % 4) != 0) // LL is EVIL!!!!
10215 { 10991 {
10216 ret += (char) (src1[i] ^ src2[c]); 10992 while (str2.EndsWith("="))
10993 str2 = str2.Substring(0, str2.Length - 1);
10217 10994
10218 c++; 10995 len = str2.Length;
10219 if (c >= src2.Length) 10996 int mod = len % 4;
10220 c = 0; 10997
10998 if (mod == 1)
10999 str2 = str2.Substring(0, str2.Length - 1);
11000 else if (mod == 2)
11001 str2 += "==";
11002 else if (mod == 3)
11003 str2 += "=";
10221 } 11004 }
10222 return llStringToBase64(ret); 11005
11006 byte[] data1;
11007 byte[] data2;
11008 try
11009 {
11010 data1 = Convert.FromBase64String(str1);
11011 data2 = Convert.FromBase64String(str2);
11012 }
11013 catch (Exception)
11014 {
11015 return new LSL_String(String.Empty);
11016 }
11017
11018 byte[] d2 = new Byte[data1.Length];
11019 int pos = 0;
11020
11021 if (data1.Length <= data2.Length)
11022 {
11023 Array.Copy(data2, 0, d2, 0, data1.Length);
11024 }
11025 else
11026 {
11027 while (pos < data1.Length)
11028 {
11029 len = data1.Length - pos;
11030 if (len > data2.Length)
11031 len = data2.Length;
11032
11033 Array.Copy(data2, 0, d2, pos, len);
11034 pos += len;
11035 }
11036 }
11037
11038 for (pos = 0 ; pos < data1.Length ; pos++ )
11039 data1[pos] ^= d2[pos];
11040
11041 return Convert.ToBase64String(data1);
10223 } 11042 }
10224 11043
10225 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11044 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10272,16 +11091,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10272 if (userAgent != null) 11091 if (userAgent != null)
10273 httpHeaders["User-Agent"] = userAgent; 11092 httpHeaders["User-Agent"] = userAgent;
10274 11093
11094 // See if the URL contains any header hacks
11095 string[] urlParts = url.Split(new char[] {'\n'});
11096 if (urlParts.Length > 1)
11097 {
11098 // Iterate the passed headers and parse them
11099 for (int i = 1 ; i < urlParts.Length ; i++ )
11100 {
11101 // The rest of those would be added to the body in SL.
11102 // Let's not do that.
11103 if (urlParts[i] == String.Empty)
11104 break;
11105
11106 // See if this could be a valid header
11107 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11108 if (headerParts.Length != 2)
11109 continue;
11110
11111 string headerName = headerParts[0].Trim();
11112 string headerValue = headerParts[1].Trim();
11113
11114 // Filter out headers that could be used to abuse
11115 // another system or cloak the request
11116 if (headerName.ToLower() == "x-secondlife-shard" ||
11117 headerName.ToLower() == "x-secondlife-object-name" ||
11118 headerName.ToLower() == "x-secondlife-object-key" ||
11119 headerName.ToLower() == "x-secondlife-region" ||
11120 headerName.ToLower() == "x-secondlife-local-position" ||
11121 headerName.ToLower() == "x-secondlife-local-velocity" ||
11122 headerName.ToLower() == "x-secondlife-local-rotation" ||
11123 headerName.ToLower() == "x-secondlife-owner-name" ||
11124 headerName.ToLower() == "x-secondlife-owner-key" ||
11125 headerName.ToLower() == "connection" ||
11126 headerName.ToLower() == "content-length" ||
11127 headerName.ToLower() == "from" ||
11128 headerName.ToLower() == "host" ||
11129 headerName.ToLower() == "proxy-authorization" ||
11130 headerName.ToLower() == "referer" ||
11131 headerName.ToLower() == "trailer" ||
11132 headerName.ToLower() == "transfer-encoding" ||
11133 headerName.ToLower() == "via" ||
11134 headerName.ToLower() == "authorization")
11135 continue;
11136
11137 httpHeaders[headerName] = headerValue;
11138 }
11139
11140 // Finally, strip any protocol specifier from the URL
11141 url = urlParts[0].Trim();
11142 int idx = url.IndexOf(" HTTP/");
11143 if (idx != -1)
11144 url = url.Substring(0, idx);
11145 }
11146
10275 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11147 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10276 Regex r = new Regex(authregex); 11148 Regex r = new Regex(authregex);
10277 int[] gnums = r.GetGroupNumbers(); 11149 int[] gnums = r.GetGroupNumbers();
10278 Match m = r.Match(url); 11150 Match m = r.Match(url);
10279 if (m.Success) { 11151 if (m.Success)
10280 for (int i = 1; i < gnums.Length; i++) { 11152 {
11153 for (int i = 1; i < gnums.Length; i++)
11154 {
10281 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11155 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10282 //CaptureCollection cc = g.Captures; 11156 //CaptureCollection cc = g.Captures;
10283 } 11157 }
10284 if (m.Groups.Count == 5) { 11158 if (m.Groups.Count == 5)
11159 {
10285 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11160 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10286 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11161 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10287 } 11162 }
@@ -10484,6 +11359,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10484 11359
10485 LSL_List ret = new LSL_List(); 11360 LSL_List ret = new LSL_List();
10486 UUID key = new UUID(); 11361 UUID key = new UUID();
11362
11363
10487 if (UUID.TryParse(id, out key)) 11364 if (UUID.TryParse(id, out key))
10488 { 11365 {
10489 ScenePresence av = World.GetScenePresence(key); 11366 ScenePresence av = World.GetScenePresence(key);
@@ -10501,13 +11378,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10501 ret.Add(new LSL_String("")); 11378 ret.Add(new LSL_String(""));
10502 break; 11379 break;
10503 case ScriptBaseClass.OBJECT_POS: 11380 case ScriptBaseClass.OBJECT_POS:
10504 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11381 Vector3 avpos;
11382
11383 if (av.ParentID != 0 && av.ParentPart != null)
11384 {
11385 avpos = av.OffsetPosition;
11386
11387 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11388 avpos -= sitOffset;
11389
11390 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11391 }
11392 else
11393 avpos = av.AbsolutePosition;
11394
11395 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10505 break; 11396 break;
10506 case ScriptBaseClass.OBJECT_ROT: 11397 case ScriptBaseClass.OBJECT_ROT:
10507 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11398 Quaternion avrot = av.Rotation;
11399 if (av.ParentID != 0 && av.ParentPart != null)
11400 {
11401 avrot = av.ParentPart.GetWorldRotation() * avrot;
11402 }
11403 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10508 break; 11404 break;
10509 case ScriptBaseClass.OBJECT_VELOCITY: 11405 case ScriptBaseClass.OBJECT_VELOCITY:
10510 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11406 Vector3 avvel = av.Velocity;
11407 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10511 break; 11408 break;
10512 case ScriptBaseClass.OBJECT_OWNER: 11409 case ScriptBaseClass.OBJECT_OWNER:
10513 ret.Add(new LSL_String(id)); 11410 ret.Add(new LSL_String(id));
@@ -10563,11 +11460,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10563 case ScriptBaseClass.OBJECT_NAME: 11460 case ScriptBaseClass.OBJECT_NAME:
10564 ret.Add(new LSL_String(obj.Name)); 11461 ret.Add(new LSL_String(obj.Name));
10565 break; 11462 break;
10566 case ScriptBaseClass.OBJECT_DESC: 11463 case ScriptBaseClass.OBJECT_DESC:
10567 ret.Add(new LSL_String(obj.Description)); 11464 ret.Add(new LSL_String(obj.Description));
10568 break; 11465 break;
10569 case ScriptBaseClass.OBJECT_POS: 11466 case ScriptBaseClass.OBJECT_POS:
10570 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11467 Vector3 opos = obj.AbsolutePosition;
11468 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10571 break; 11469 break;
10572 case ScriptBaseClass.OBJECT_ROT: 11470 case ScriptBaseClass.OBJECT_ROT:
10573 { 11471 {
@@ -10617,9 +11515,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10617 // The value returned in SL for normal prims is prim count 11515 // The value returned in SL for normal prims is prim count
10618 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11516 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10619 break; 11517 break;
10620 // The following 3 costs I have intentionaly coded to return zero. They are part of 11518
10621 // "Land Impact" calculations. These calculations are probably not applicable 11519 // costs below may need to be diferent for root parts, need to check
10622 // to OpenSim and are not yet complete in SL
10623 case ScriptBaseClass.OBJECT_SERVER_COST: 11520 case ScriptBaseClass.OBJECT_SERVER_COST:
10624 // The linden calculation is here 11521 // The linden calculation is here
10625 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11522 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10627,16 +11524,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10627 ret.Add(new LSL_Float(0)); 11524 ret.Add(new LSL_Float(0));
10628 break; 11525 break;
10629 case ScriptBaseClass.OBJECT_STREAMING_COST: 11526 case ScriptBaseClass.OBJECT_STREAMING_COST:
10630 // The linden calculation is here 11527 // The value returned in SL for normal prims is prim count * 0.06
10631 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11528 ret.Add(new LSL_Float(obj.StreamingCost));
10632 // The value returned in SL for normal prims looks like the prim count * 0.06
10633 ret.Add(new LSL_Float(0));
10634 break; 11529 break;
10635 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11530 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10636 // The linden calculation is here 11531 // The value returned in SL for normal prims is prim count
10637 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11532 ret.Add(new LSL_Float(obj.PhysicsCost));
10638 // The value returned in SL for normal prims looks like the prim count
10639 ret.Add(new LSL_Float(0));
10640 break; 11533 break;
10641 default: 11534 default:
10642 // Invalid or unhandled constant. 11535 // Invalid or unhandled constant.
@@ -10847,15 +11740,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10847 return result; 11740 return result;
10848 } 11741 }
10849 11742
10850 public void print(string str) 11743 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10851 { 11744 {
10852 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11745 List<SceneObjectPart> parts = GetLinkParts(link);
10853 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11746 if (parts.Count < 1)
10854 if (ossl != null) 11747 return 0;
10855 { 11748
10856 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11749 return GetNumberOfSides(parts[0]);
10857 m_log.Info("LSL print():" + str);
10858 }
10859 } 11750 }
10860 11751
10861 private string Name2Username(string name) 11752 private string Name2Username(string name)
@@ -10900,7 +11791,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10900 11791
10901 return rq.ToString(); 11792 return rq.ToString();
10902 } 11793 }
10903 11794/*
11795 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11796 {
11797 m_SayShoutCount = 0;
11798 }
11799*/
10904 private struct Tri 11800 private struct Tri
10905 { 11801 {
10906 public Vector3 p1; 11802 public Vector3 p1;
@@ -11040,9 +11936,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11040 11936
11041 ContactResult result = new ContactResult (); 11937 ContactResult result = new ContactResult ();
11042 result.ConsumerID = group.LocalId; 11938 result.ConsumerID = group.LocalId;
11043 result.Depth = intersection.distance; 11939// result.Depth = intersection.distance;
11044 result.Normal = intersection.normal; 11940 result.Normal = intersection.normal;
11045 result.Pos = intersection.ipoint; 11941 result.Pos = intersection.ipoint;
11942 result.Depth = Vector3.Mag(rayStart - result.Pos);
11046 11943
11047 contacts.Add(result); 11944 contacts.Add(result);
11048 }); 11945 });
@@ -11175,6 +12072,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11175 12072
11176 return contacts[0]; 12073 return contacts[0];
11177 } 12074 }
12075/*
12076 // not done:
12077 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12078 {
12079 ContactResult[] contacts = null;
12080 World.ForEachSOG(delegate(SceneObjectGroup group)
12081 {
12082 if (m_host.ParentGroup == group)
12083 return;
12084
12085 if (group.IsAttachment)
12086 return;
12087
12088 if(group.RootPart.PhysActor != null)
12089 return;
12090
12091 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12092 });
12093 return contacts;
12094 }
12095*/
11178 12096
11179 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12097 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11180 { 12098 {
@@ -11216,32 +12134,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11216 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12134 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11217 12135
11218 12136
11219 if (checkTerrain) 12137 if (World.SuportsRayCastFiltered())
11220 { 12138 {
11221 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12139 if (dist == 0)
11222 if (groundContact != null) 12140 return list;
11223 results.Add((ContactResult)groundContact);
11224 }
11225 12141
11226 if (checkAgents) 12142 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11227 { 12143 if (checkTerrain)
11228 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12144 rayfilter |= RayFilterFlags.land;
11229 foreach (ContactResult r in agentHits) 12145// if (checkAgents)
11230 results.Add(r); 12146// rayfilter |= RayFilterFlags.agent;
11231 } 12147 if (checkPhysical)
12148 rayfilter |= RayFilterFlags.physical;
12149 if (checkNonPhysical)
12150 rayfilter |= RayFilterFlags.nonphysical;
12151 if (detectPhantom)
12152 rayfilter |= RayFilterFlags.LSLPhanton;
12153
12154 Vector3 direction = dir * ( 1/dist);
12155
12156 if(rayfilter == 0)
12157 {
12158 list.Add(new LSL_Integer(0));
12159 return list;
12160 }
11232 12161
11233 if (checkPhysical || checkNonPhysical || detectPhantom) 12162 // get some more contacts to sort ???
12163 int physcount = 4 * count;
12164 if (physcount > 20)
12165 physcount = 20;
12166
12167 object physresults;
12168 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12169
12170 if (physresults == null)
12171 {
12172 list.Add(new LSL_Integer(-3)); // timeout error
12173 return list;
12174 }
12175
12176 results = (List<ContactResult>)physresults;
12177
12178 // for now physics doesn't detect sitted avatars so do it outside physics
12179 if (checkAgents)
12180 {
12181 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12182 foreach (ContactResult r in agentHits)
12183 results.Add(r);
12184 }
12185
12186 // TODO: Replace this with a better solution. ObjectIntersection can only
12187 // detect nonphysical phantoms. They are detected by virtue of being
12188 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12189 // physicsl phantoms as done by the physics scene
12190 // We don't want anything else but phantoms here.
12191 if (detectPhantom)
12192 {
12193 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12194 foreach (ContactResult r in objectHits)
12195 results.Add(r);
12196 }
12197 }
12198 else
11234 { 12199 {
11235 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12200 if (checkTerrain)
11236 foreach (ContactResult r in objectHits) 12201 {
11237 results.Add(r); 12202 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12203 if (groundContact != null)
12204 results.Add((ContactResult)groundContact);
12205 }
12206
12207 if (checkAgents)
12208 {
12209 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12210 foreach (ContactResult r in agentHits)
12211 results.Add(r);
12212 }
12213
12214 if (checkPhysical || checkNonPhysical || detectPhantom)
12215 {
12216 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12217 foreach (ContactResult r in objectHits)
12218 results.Add(r);
12219 }
11238 } 12220 }
11239 12221
11240 results.Sort(delegate(ContactResult a, ContactResult b) 12222 results.Sort(delegate(ContactResult a, ContactResult b)
11241 { 12223 {
11242 return a.Depth.CompareTo(b.Depth); 12224 return a.Depth.CompareTo(b.Depth);
11243 }); 12225 });
11244 12226
11245 int values = 0; 12227 int values = 0;
11246 SceneObjectGroup thisgrp = m_host.ParentGroup; 12228 SceneObjectGroup thisgrp = m_host.ParentGroup;
11247 12229
@@ -11334,7 +12316,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11334 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12316 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11335 if (!isAccount) return 0; 12317 if (!isAccount) return 0;
11336 if (estate.HasAccess(id)) return 1; 12318 if (estate.HasAccess(id)) return 1;
11337 if (estate.IsBanned(id)) 12319 if (estate.IsBanned(id, World.GetUserFlags(id)))
11338 estate.RemoveBan(id); 12320 estate.RemoveBan(id);
11339 estate.AddEstateUser(id); 12321 estate.AddEstateUser(id);
11340 break; 12322 break;
@@ -11353,14 +12335,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11353 break; 12335 break;
11354 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12336 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11355 if (!isAccount) return 0; 12337 if (!isAccount) return 0;
11356 if (estate.IsBanned(id)) return 1; 12338 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11357 EstateBan ban = new EstateBan(); 12339 EstateBan ban = new EstateBan();
11358 ban.EstateID = estate.EstateID; 12340 ban.EstateID = estate.EstateID;
11359 ban.BannedUserID = id; 12341 ban.BannedUserID = id;
11360 estate.AddBan(ban); 12342 estate.AddBan(ban);
11361 break; 12343 break;
11362 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12344 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11363 if (!isAccount || !estate.IsBanned(id)) return 0; 12345 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11364 estate.RemoveBan(id); 12346 estate.RemoveBan(id);
11365 break; 12347 break;
11366 default: return 0; 12348 default: return 0;
@@ -11389,7 +12371,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11389 return 16384; 12371 return 16384;
11390 } 12372 }
11391 12373
11392 public LSL_Integer llGetUsedMemory() 12374 public virtual LSL_Integer llGetUsedMemory()
11393 { 12375 {
11394 m_host.AddScriptLPS(1); 12376 m_host.AddScriptLPS(1);
11395 // The value returned for LSO scripts in SL 12377 // The value returned for LSO scripts in SL
@@ -11417,22 +12399,731 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11417 public void llSetSoundQueueing(int queue) 12399 public void llSetSoundQueueing(int queue)
11418 { 12400 {
11419 m_host.AddScriptLPS(1); 12401 m_host.AddScriptLPS(1);
11420 NotImplemented("llSetSoundQueueing");
11421 } 12402 }
11422 12403
11423 public void llCollisionSprite(string impact_sprite) 12404 public void llCollisionSprite(string impact_sprite)
11424 { 12405 {
11425 m_host.AddScriptLPS(1); 12406 m_host.AddScriptLPS(1);
11426 NotImplemented("llCollisionSprite"); 12407 // Viewer 2.0 broke this and it's likely LL has no intention
12408 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11427 } 12409 }
11428 12410
11429 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12411 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11430 { 12412 {
11431 m_host.AddScriptLPS(1); 12413 m_host.AddScriptLPS(1);
11432 NotImplemented("llGodLikeRezObject"); 12414
12415 if (!World.Permissions.IsGod(m_host.OwnerID))
12416 NotImplemented("llGodLikeRezObject");
12417
12418 AssetBase rezAsset = World.AssetService.Get(inventory);
12419 if (rezAsset == null)
12420 {
12421 llSay(0, "Asset not found");
12422 return;
12423 }
12424
12425 SceneObjectGroup group = null;
12426
12427 try
12428 {
12429 string xmlData = Utils.BytesToString(rezAsset.Data);
12430 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12431 }
12432 catch
12433 {
12434 llSay(0, "Asset not found");
12435 return;
12436 }
12437
12438 if (group == null)
12439 {
12440 llSay(0, "Asset not found");
12441 return;
12442 }
12443
12444 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12445 group.RootPart.AttachOffset = group.AbsolutePosition;
12446
12447 group.ResetIDs();
12448
12449 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12450 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12451 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12452 group.ScheduleGroupForFullUpdate();
12453
12454 // objects rezzed with this method are die_at_edge by default.
12455 group.RootPart.SetDieAtEdge(true);
12456
12457 group.ResumeScripts();
12458
12459 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12460 "object_rez", new Object[] {
12461 new LSL_String(
12462 group.RootPart.UUID.ToString()) },
12463 new DetectParams[0]));
12464 }
12465
12466 public LSL_String llTransferLindenDollars(string destination, int amount)
12467 {
12468 UUID txn = UUID.Random();
12469
12470 Util.FireAndForget(delegate(object x)
12471 {
12472 int replycode = 0;
12473 string replydata = destination + "," + amount.ToString();
12474
12475 try
12476 {
12477 TaskInventoryItem item = m_item;
12478 if (item == null)
12479 {
12480 replydata = "SERVICE_ERROR";
12481 return;
12482 }
12483
12484 m_host.AddScriptLPS(1);
12485
12486 if (item.PermsGranter == UUID.Zero)
12487 {
12488 replydata = "MISSING_PERMISSION_DEBIT";
12489 return;
12490 }
12491
12492 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12493 {
12494 replydata = "MISSING_PERMISSION_DEBIT";
12495 return;
12496 }
12497
12498 UUID toID = new UUID();
12499
12500 if (!UUID.TryParse(destination, out toID))
12501 {
12502 replydata = "INVALID_AGENT";
12503 return;
12504 }
12505
12506 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12507
12508 if (money == null)
12509 {
12510 replydata = "TRANSFERS_DISABLED";
12511 return;
12512 }
12513
12514 bool result = money.ObjectGiveMoney(
12515 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12516
12517 if (result)
12518 {
12519 replycode = 1;
12520 return;
12521 }
12522
12523 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12524 }
12525 finally
12526 {
12527 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12528 "transaction_result", new Object[] {
12529 new LSL_String(txn.ToString()),
12530 new LSL_Integer(replycode),
12531 new LSL_String(replydata) },
12532 new DetectParams[0]));
12533 }
12534 });
12535
12536 return txn.ToString();
11433 } 12537 }
11434 12538
11435 #endregion 12539 #endregion
12540
12541 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12542 {
12543 SceneObjectGroup group = m_host.ParentGroup;
12544
12545 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12546 return;
12547 if (group.IsAttachment)
12548 return;
12549
12550 if (frames.Data.Length > 0) // We are getting a new motion
12551 {
12552 if (group.RootPart.KeyframeMotion != null)
12553 group.RootPart.KeyframeMotion.Delete();
12554 group.RootPart.KeyframeMotion = null;
12555
12556 int idx = 0;
12557
12558 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12559 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12560
12561 while (idx < options.Data.Length)
12562 {
12563 int option = (int)options.GetLSLIntegerItem(idx++);
12564 int remain = options.Data.Length - idx;
12565
12566 switch (option)
12567 {
12568 case ScriptBaseClass.KFM_MODE:
12569 if (remain < 1)
12570 break;
12571 int modeval = (int)options.GetLSLIntegerItem(idx++);
12572 switch(modeval)
12573 {
12574 case ScriptBaseClass.KFM_FORWARD:
12575 mode = KeyframeMotion.PlayMode.Forward;
12576 break;
12577 case ScriptBaseClass.KFM_REVERSE:
12578 mode = KeyframeMotion.PlayMode.Reverse;
12579 break;
12580 case ScriptBaseClass.KFM_LOOP:
12581 mode = KeyframeMotion.PlayMode.Loop;
12582 break;
12583 case ScriptBaseClass.KFM_PING_PONG:
12584 mode = KeyframeMotion.PlayMode.PingPong;
12585 break;
12586 }
12587 break;
12588 case ScriptBaseClass.KFM_DATA:
12589 if (remain < 1)
12590 break;
12591 int dataval = (int)options.GetLSLIntegerItem(idx++);
12592 data = (KeyframeMotion.DataFormat)dataval;
12593 break;
12594 }
12595 }
12596
12597 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12598
12599 idx = 0;
12600
12601 int elemLength = 2;
12602 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12603 elemLength = 3;
12604
12605 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12606 while (idx < frames.Data.Length)
12607 {
12608 int remain = frames.Data.Length - idx;
12609
12610 if (remain < elemLength)
12611 break;
12612
12613 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12614 frame.Position = null;
12615 frame.Rotation = null;
12616
12617 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12618 {
12619 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12620 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12621 }
12622 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12623 {
12624 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12625 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12626 }
12627
12628 float tempf = (float)frames.GetLSLFloatItem(idx++);
12629 frame.TimeMS = (int)(tempf * 1000.0f);
12630
12631 keyframes.Add(frame);
12632 }
12633
12634 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12635 group.RootPart.KeyframeMotion.Start();
12636 }
12637 else
12638 {
12639 if (group.RootPart.KeyframeMotion == null)
12640 return;
12641
12642 if (options.Data.Length == 0)
12643 {
12644 group.RootPart.KeyframeMotion.Stop();
12645 return;
12646 }
12647
12648 int code = (int)options.GetLSLIntegerItem(0);
12649
12650 int idx = 0;
12651
12652 while (idx < options.Data.Length)
12653 {
12654 int option = (int)options.GetLSLIntegerItem(idx++);
12655 int remain = options.Data.Length - idx;
12656
12657 switch (option)
12658 {
12659 case ScriptBaseClass.KFM_COMMAND:
12660 int cmd = (int)options.GetLSLIntegerItem(idx++);
12661 switch (cmd)
12662 {
12663 case ScriptBaseClass.KFM_CMD_PLAY:
12664 group.RootPart.KeyframeMotion.Start();
12665 break;
12666 case ScriptBaseClass.KFM_CMD_STOP:
12667 group.RootPart.KeyframeMotion.Stop();
12668 break;
12669 case ScriptBaseClass.KFM_CMD_PAUSE:
12670 group.RootPart.KeyframeMotion.Pause();
12671 break;
12672 }
12673 break;
12674 }
12675 }
12676 }
12677 }
12678
12679 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12680 {
12681 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12682
12683 int idx = 0;
12684 int idxStart = 0;
12685
12686 bool positionChanged = false;
12687 Vector3 finalPos = Vector3.Zero;
12688
12689 try
12690 {
12691 while (idx < rules.Length)
12692 {
12693 ++rulesParsed;
12694 int code = rules.GetLSLIntegerItem(idx++);
12695
12696 int remain = rules.Length - idx;
12697 idxStart = idx;
12698
12699 switch (code)
12700 {
12701 case (int)ScriptBaseClass.PRIM_POSITION:
12702 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12703 {
12704 if (remain < 1)
12705 return null;
12706
12707 LSL_Vector v;
12708 v = rules.GetVector3Item(idx++);
12709
12710 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12711 if (part == null)
12712 break;
12713
12714 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12715 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12716 if (part.LinkNum > 1)
12717 {
12718 localRot = GetPartLocalRot(part);
12719 localPos = GetPartLocalPos(part);
12720 }
12721
12722 v -= localPos;
12723 v /= localRot;
12724
12725 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12726
12727 v = v + 2 * sitOffset;
12728
12729 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12730 av.SendAvatarDataToAllAgents();
12731
12732 }
12733 break;
12734
12735 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12736 case (int)ScriptBaseClass.PRIM_ROTATION:
12737 {
12738 if (remain < 1)
12739 return null;
12740
12741 LSL_Rotation r;
12742 r = rules.GetQuaternionItem(idx++);
12743
12744 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12745 if (part == null)
12746 break;
12747
12748 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12749 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12750
12751 if (part.LinkNum > 1)
12752 localRot = GetPartLocalRot(part);
12753
12754 r = r * llGetRootRotation() / localRot;
12755 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12756 av.SendAvatarDataToAllAgents();
12757 }
12758 break;
12759
12760 // parse rest doing nothing but number of parameters error check
12761 case (int)ScriptBaseClass.PRIM_SIZE:
12762 case (int)ScriptBaseClass.PRIM_MATERIAL:
12763 case (int)ScriptBaseClass.PRIM_PHANTOM:
12764 case (int)ScriptBaseClass.PRIM_PHYSICS:
12765 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12766 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12767 case (int)ScriptBaseClass.PRIM_NAME:
12768 case (int)ScriptBaseClass.PRIM_DESC:
12769 if (remain < 1)
12770 return null;
12771 idx++;
12772 break;
12773
12774 case (int)ScriptBaseClass.PRIM_GLOW:
12775 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12776 case (int)ScriptBaseClass.PRIM_TEXGEN:
12777 if (remain < 2)
12778 return null;
12779 idx += 2;
12780 break;
12781
12782 case (int)ScriptBaseClass.PRIM_TYPE:
12783 if (remain < 3)
12784 return null;
12785 code = (int)rules.GetLSLIntegerItem(idx++);
12786 remain = rules.Length - idx;
12787 switch (code)
12788 {
12789 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12790 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12791 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12792 if (remain < 6)
12793 return null;
12794 idx += 6;
12795 break;
12796
12797 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12798 if (remain < 5)
12799 return null;
12800 idx += 5;
12801 break;
12802
12803 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12804 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12805 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12806 if (remain < 11)
12807 return null;
12808 idx += 11;
12809 break;
12810
12811 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12812 if (remain < 2)
12813 return null;
12814 idx += 2;
12815 break;
12816 }
12817 break;
12818
12819 case (int)ScriptBaseClass.PRIM_COLOR:
12820 case (int)ScriptBaseClass.PRIM_TEXT:
12821 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12822 case (int)ScriptBaseClass.PRIM_OMEGA:
12823 if (remain < 3)
12824 return null;
12825 idx += 3;
12826 break;
12827
12828 case (int)ScriptBaseClass.PRIM_TEXTURE:
12829 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12830 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12831 if (remain < 5)
12832 return null;
12833 idx += 5;
12834 break;
12835
12836 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12837 if (remain < 7)
12838 return null;
12839
12840 idx += 7;
12841 break;
12842
12843 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12844 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12845 return null;
12846
12847 return rules.GetSublist(idx, -1);
12848 }
12849 }
12850 }
12851 catch (InvalidCastException e)
12852 {
12853 ShoutError(string.Format(
12854 "{0} error running rule #{1}: arg #{2} ",
12855 originFunc, rulesParsed, idx - idxStart) + e.Message);
12856 }
12857 finally
12858 {
12859 if (positionChanged)
12860 {
12861 av.OffsetPosition = finalPos;
12862// av.SendAvatarDataToAllAgents();
12863 av.SendTerseUpdateToAllClients();
12864 positionChanged = false;
12865 }
12866 }
12867 return null;
12868 }
12869
12870 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12871 {
12872 // avatars case
12873 // replies as SL wiki
12874
12875// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12876 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12877
12878 int idx = 0;
12879 while (idx < rules.Length)
12880 {
12881 int code = (int)rules.GetLSLIntegerItem(idx++);
12882 int remain = rules.Length - idx;
12883
12884 switch (code)
12885 {
12886 case (int)ScriptBaseClass.PRIM_MATERIAL:
12887 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12888 break;
12889
12890 case (int)ScriptBaseClass.PRIM_PHYSICS:
12891 res.Add(new LSL_Integer(0));
12892 break;
12893
12894 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12895 res.Add(new LSL_Integer(0));
12896 break;
12897
12898 case (int)ScriptBaseClass.PRIM_PHANTOM:
12899 res.Add(new LSL_Integer(0));
12900 break;
12901
12902 case (int)ScriptBaseClass.PRIM_POSITION:
12903
12904 Vector3 pos = avatar.OffsetPosition;
12905
12906 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12907 pos -= sitOffset;
12908
12909 if( sitPart != null)
12910 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12911
12912 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12913 break;
12914
12915 case (int)ScriptBaseClass.PRIM_SIZE:
12916 // as in llGetAgentSize above
12917 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12918 break;
12919
12920 case (int)ScriptBaseClass.PRIM_ROTATION:
12921 Quaternion rot = avatar.Rotation;
12922 if (sitPart != null)
12923 {
12924 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12925 }
12926
12927 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12928 break;
12929
12930 case (int)ScriptBaseClass.PRIM_TYPE:
12931 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12932 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12933 res.Add(new LSL_Vector(0f,1.0f,0f));
12934 res.Add(new LSL_Float(0.0f));
12935 res.Add(new LSL_Vector(0, 0, 0));
12936 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12937 res.Add(new LSL_Vector(0, 0, 0));
12938 break;
12939
12940 case (int)ScriptBaseClass.PRIM_TEXTURE:
12941 if (remain < 1)
12942 return null;
12943
12944 int face = (int)rules.GetLSLIntegerItem(idx++);
12945 if (face == ScriptBaseClass.ALL_SIDES)
12946 {
12947 for (face = 0; face < 21; face++)
12948 {
12949 res.Add(new LSL_String(""));
12950 res.Add(new LSL_Vector(0,0,0));
12951 res.Add(new LSL_Vector(0,0,0));
12952 res.Add(new LSL_Float(0.0));
12953 }
12954 }
12955 else
12956 {
12957 if (face >= 0 && face < 21)
12958 {
12959 res.Add(new LSL_String(""));
12960 res.Add(new LSL_Vector(0,0,0));
12961 res.Add(new LSL_Vector(0,0,0));
12962 res.Add(new LSL_Float(0.0));
12963 }
12964 }
12965 break;
12966
12967 case (int)ScriptBaseClass.PRIM_COLOR:
12968 if (remain < 1)
12969 return null;
12970
12971 face = (int)rules.GetLSLIntegerItem(idx++);
12972
12973 if (face == ScriptBaseClass.ALL_SIDES)
12974 {
12975 for (face = 0; face < 21; face++)
12976 {
12977 res.Add(new LSL_Vector(0,0,0));
12978 res.Add(new LSL_Float(0));
12979 }
12980 }
12981 else
12982 {
12983 res.Add(new LSL_Vector(0,0,0));
12984 res.Add(new LSL_Float(0));
12985 }
12986 break;
12987
12988 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12989 if (remain < 1)
12990 return null;
12991 face = (int)rules.GetLSLIntegerItem(idx++);
12992
12993 if (face == ScriptBaseClass.ALL_SIDES)
12994 {
12995 for (face = 0; face < 21; face++)
12996 {
12997 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12998 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12999 }
13000 }
13001 else
13002 {
13003 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13004 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13005 }
13006 break;
13007
13008 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13009 if (remain < 1)
13010 return null;
13011 face = (int)rules.GetLSLIntegerItem(idx++);
13012
13013 if (face == ScriptBaseClass.ALL_SIDES)
13014 {
13015 for (face = 0; face < 21; face++)
13016 {
13017 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13018 }
13019 }
13020 else
13021 {
13022 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13023 }
13024 break;
13025
13026 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13027 res.Add(new LSL_Integer(0));
13028 res.Add(new LSL_Integer(0));// softness
13029 res.Add(new LSL_Float(0.0f)); // gravity
13030 res.Add(new LSL_Float(0.0f)); // friction
13031 res.Add(new LSL_Float(0.0f)); // wind
13032 res.Add(new LSL_Float(0.0f)); // tension
13033 res.Add(new LSL_Vector(0f,0f,0f));
13034 break;
13035
13036 case (int)ScriptBaseClass.PRIM_TEXGEN:
13037 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13038 if (remain < 1)
13039 return null;
13040 face = (int)rules.GetLSLIntegerItem(idx++);
13041
13042 if (face == ScriptBaseClass.ALL_SIDES)
13043 {
13044 for (face = 0; face < 21; face++)
13045 {
13046 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13047 }
13048 }
13049 else
13050 {
13051 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13052 }
13053 break;
13054
13055 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13056 res.Add(new LSL_Integer(0));
13057 res.Add(new LSL_Vector(0f,0f,0f));
13058 res.Add(new LSL_Float(0f)); // intensity
13059 res.Add(new LSL_Float(0f)); // radius
13060 res.Add(new LSL_Float(0f)); // falloff
13061 break;
13062
13063 case (int)ScriptBaseClass.PRIM_GLOW:
13064 if (remain < 1)
13065 return null;
13066 face = (int)rules.GetLSLIntegerItem(idx++);
13067
13068 if (face == ScriptBaseClass.ALL_SIDES)
13069 {
13070 for (face = 0; face < 21; face++)
13071 {
13072 res.Add(new LSL_Float(0f));
13073 }
13074 }
13075 else
13076 {
13077 res.Add(new LSL_Float(0f));
13078 }
13079 break;
13080
13081 case (int)ScriptBaseClass.PRIM_TEXT:
13082 res.Add(new LSL_String(""));
13083 res.Add(new LSL_Vector(0f,0f,0f));
13084 res.Add(new LSL_Float(1.0f));
13085 break;
13086
13087 case (int)ScriptBaseClass.PRIM_NAME:
13088 res.Add(new LSL_String(avatar.Name));
13089 break;
13090
13091 case (int)ScriptBaseClass.PRIM_DESC:
13092 res.Add(new LSL_String(""));
13093 break;
13094
13095 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13096 Quaternion lrot = avatar.Rotation;
13097
13098 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13099 {
13100 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13101 }
13102 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13103 break;
13104
13105 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13106 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13107 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13108 lpos -= lsitOffset;
13109
13110 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13111 {
13112 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13113 }
13114 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13115 break;
13116
13117 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13118 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13119 return null;
13120
13121 return rules.GetSublist(idx, -1);
13122 }
13123 }
13124
13125 return null;
13126 }
11436 } 13127 }
11437 13128
11438 public class NotecardCache 13129 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 29bc163..17277d7 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -138,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
139 internal float m_ScriptDelayFactor = 1.0f; 139 internal float m_ScriptDelayFactor = 1.0f;
140 internal float m_ScriptDistanceFactor = 1.0f; 140 internal float m_ScriptDistanceFactor = 1.0f;
141 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 143
143 protected IUrlModule m_UrlModule = null; 144 protected IUrlModule m_UrlModule = null;
@@ -147,6 +148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
147 m_ScriptEngine = ScriptEngine; 148 m_ScriptEngine = ScriptEngine;
148 m_host = host; 149 m_host = host;
149 m_item = item; 150 m_item = item;
151 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
150 152
151 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 153 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
152 154
@@ -210,7 +212,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
210 212
211 internal void OSSLError(string msg) 213 internal void OSSLError(string msg)
212 { 214 {
213 throw new Exception("OSSL Runtime Error: " + msg); 215 if (m_debuggerSafe)
216 {
217 OSSLShoutError(msg);
218 }
219 else
220 {
221 throw new Exception("OSSL Runtime Error: " + msg);
222 }
214 } 223 }
215 224
216 /// <summary> 225 /// <summary>
@@ -918,18 +927,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
918 if (target != null) 927 if (target != null)
919 { 928 {
920 UUID animID=UUID.Zero; 929 UUID animID=UUID.Zero;
921 lock (m_host.TaskInventory) 930 m_host.TaskInventory.LockItemsForRead(true);
931 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
922 { 932 {
923 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 933 if (inv.Value.Name == animation)
924 { 934 {
925 if (inv.Value.Name == animation) 935 if (inv.Value.Type == (int)AssetType.Animation)
926 { 936 animID = inv.Value.AssetID;
927 if (inv.Value.Type == (int)AssetType.Animation) 937 continue;
928 animID = inv.Value.AssetID;
929 continue;
930 }
931 } 938 }
932 } 939 }
940 m_host.TaskInventory.LockItemsForRead(false);
933 if (animID == UUID.Zero) 941 if (animID == UUID.Zero)
934 target.Animator.AddAnimation(animation, m_host.UUID); 942 target.Animator.AddAnimation(animation, m_host.UUID);
935 else 943 else
@@ -970,6 +978,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
970 else 978 else
971 animID = UUID.Zero; 979 animID = UUID.Zero;
972 } 980 }
981 m_host.TaskInventory.LockItemsForRead(false);
973 982
974 if (animID == UUID.Zero) 983 if (animID == UUID.Zero)
975 target.Animator.RemoveAnimation(animation); 984 target.Animator.RemoveAnimation(animation);
@@ -1808,6 +1817,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1808 1817
1809 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1818 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1810 { 1819 {
1820 m_host.TaskInventory.LockItemsForRead(true);
1811 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1821 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1812 { 1822 {
1813 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1823 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1815,6 +1825,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1815 assetID = item.AssetID; 1825 assetID = item.AssetID;
1816 } 1826 }
1817 } 1827 }
1828 m_host.TaskInventory.LockItemsForRead(false);
1818 } 1829 }
1819 1830
1820 if (assetID == UUID.Zero) 1831 if (assetID == UUID.Zero)
@@ -2300,7 +2311,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2300 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2311 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2301 m_host.AddScriptLPS(1); 2312 m_host.AddScriptLPS(1);
2302 2313
2303 return NpcCreate(firstname, lastname, position, notecard, false, false); 2314 return NpcCreate(firstname, lastname, position, notecard, true, false);
2304 } 2315 }
2305 2316
2306 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2317 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2311,24 +2322,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2311 return NpcCreate( 2322 return NpcCreate(
2312 firstname, lastname, position, notecard, 2323 firstname, lastname, position, notecard,
2313 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2324 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2314 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2325 false);
2326// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2315 } 2327 }
2316 2328
2317 private LSL_Key NpcCreate( 2329 private LSL_Key NpcCreate(
2318 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2330 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2319 { 2331 {
2332 if (!owned)
2333 OSSLError("Unowned NPCs are unsupported");
2334
2335 string groupTitle = String.Empty;
2336
2337 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2338 return new LSL_Key(UUID.Zero.ToString());
2339
2340 if (firstname != String.Empty || lastname != String.Empty)
2341 {
2342 if (firstname != "Shown outfit:")
2343 groupTitle = "- NPC -";
2344 }
2345
2320 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2346 INPCModule module = World.RequestModuleInterface<INPCModule>();
2321 if (module != null) 2347 if (module != null)
2322 { 2348 {
2323 AvatarAppearance appearance = null; 2349 AvatarAppearance appearance = null;
2324 2350
2325 UUID id; 2351// UUID id;
2326 if (UUID.TryParse(notecard, out id)) 2352// if (UUID.TryParse(notecard, out id))
2327 { 2353// {
2328 ScenePresence clonePresence = World.GetScenePresence(id); 2354// ScenePresence clonePresence = World.GetScenePresence(id);
2329 if (clonePresence != null) 2355// if (clonePresence != null)
2330 appearance = clonePresence.Appearance; 2356// appearance = clonePresence.Appearance;
2331 } 2357// }
2332 2358
2333 if (appearance == null) 2359 if (appearance == null)
2334 { 2360 {
@@ -2336,9 +2362,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2336 2362
2337 if (appearanceSerialized != null) 2363 if (appearanceSerialized != null)
2338 { 2364 {
2339 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2365 try
2340 appearance = new AvatarAppearance(); 2366 {
2341 appearance.Unpack(appearanceOsd); 2367 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2368 appearance = new AvatarAppearance();
2369 appearance.Unpack(appearanceOsd);
2370 }
2371 catch
2372 {
2373 return UUID.Zero.ToString();
2374 }
2342 } 2375 }
2343 } 2376 }
2344 2377
@@ -2356,6 +2389,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2356 World, 2389 World,
2357 appearance); 2390 appearance);
2358 2391
2392 ScenePresence sp;
2393 if (World.TryGetScenePresence(x, out sp))
2394 {
2395 sp.Grouptitle = groupTitle;
2396 sp.SendAvatarDataToAllAgents();
2397 }
2359 return new LSL_Key(x.ToString()); 2398 return new LSL_Key(x.ToString());
2360 } 2399 }
2361 2400
@@ -2655,16 +2694,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2655 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2694 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2656 m_host.AddScriptLPS(1); 2695 m_host.AddScriptLPS(1);
2657 2696
2658 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2697 ManualResetEvent ev = new ManualResetEvent(false);
2659 if (module != null)
2660 {
2661 UUID npcId = new UUID(npc.m_string);
2662 2698
2663 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2699 Util.FireAndForget(delegate(object x) {
2664 return; 2700 try
2701 {
2702 INPCModule module = World.RequestModuleInterface<INPCModule>();
2703 if (module != null)
2704 {
2705 UUID npcId = new UUID(npc.m_string);
2665 2706
2666 module.DeleteNPC(npcId, World); 2707 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2667 } 2708 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2709 {
2710 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2711 return;
2712 }
2713
2714 module.DeleteNPC(npcId, World);
2715 }
2716 }
2717 finally
2718 {
2719 ev.Set();
2720 }
2721 });
2722 ev.WaitOne();
2668 } 2723 }
2669 2724
2670 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2725 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3637,4 +3692,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3637 DropAttachmentAt(false, pos, rot); 3692 DropAttachmentAt(false, pos, rot);
3638 } 3693 }
3639 } 3694 }
3640} \ No newline at end of file 3695}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 24cceea..4dd795d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -70,7 +70,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
70 private const int AGENT = 1; 70 private const int AGENT = 1;
71 private const int AGENT_BY_USERNAME = 0x10; 71 private const int AGENT_BY_USERNAME = 0x10;
72 private const int NPC = 0x20; 72 private const int NPC = 0x20;
73 private const int OS_NPC = 0x01000000;
74 private const int ACTIVE = 2; 73 private const int ACTIVE = 2;
75 private const int PASSIVE = 4; 74 private const int PASSIVE = 4;
76 private const int SCRIPTED = 8; 75 private const int SCRIPTED = 8;
@@ -235,7 +234,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
235 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 234 List<SensedEntity> sensedEntities = new List<SensedEntity>();
236 235
237 // Is the sensor type is AGENT and not SCRIPTED then include agents 236 // Is the sensor type is AGENT and not SCRIPTED then include agents
238 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 237 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
239 { 238 {
240 sensedEntities.AddRange(doAgentSensor(ts)); 239 sensedEntities.AddRange(doAgentSensor(ts));
241 } 240 }
@@ -334,7 +333,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
334 float dy; 333 float dy;
335 float dz; 334 float dz;
336 335
337 Quaternion q = SensePoint.GetWorldRotation(); 336// Quaternion q = SensePoint.RotationOffset;
337 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
338 if (SensePoint.ParentGroup.IsAttachment) 338 if (SensePoint.ParentGroup.IsAttachment)
339 { 339 {
340 // In attachments, rotate the sensor cone with the 340 // In attachments, rotate the sensor cone with the
@@ -348,7 +348,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
348 // Position of a sensor in a child prim attached to an avatar 348 // Position of a sensor in a child prim attached to an avatar
349 // will be still wrong. 349 // will be still wrong.
350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
351 q = avatar.Rotation * q; 351 fromRegionPos = avatar.AbsolutePosition;
352 q = avatar.Rotation;
352 } 353 }
353 354
354 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -475,7 +476,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
475 // Position of a sensor in a child prim attached to an avatar 476 // Position of a sensor in a child prim attached to an avatar
476 // will be still wrong. 477 // will be still wrong.
477 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 478 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
478 q = avatar.Rotation * q; 479 if (avatar == null)
480 return sensedEntities;
481 fromRegionPos = avatar.AbsolutePosition;
482 q = avatar.Rotation;
479 } 483 }
480 484
481 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 485 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -491,7 +495,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
491// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 495// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
492// presence.Name, presence.PresenceType, ts.name, ts.type); 496// presence.Name, presence.PresenceType, ts.name, ts.type);
493 497
494 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 498 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
495 { 499 {
496 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 500 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
497 if (npcData == null || !npcData.SenseAsAgent) 501 if (npcData == null || !npcData.SenseAsAgent)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index bc63030..9ee6946 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -118,25 +118,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
118 if (Timers.Count == 0) 118 if (Timers.Count == 0)
119 return; 119 return;
120 120
121 Dictionary<string, TimerClass>.ValueCollection tvals;
121 lock (TimerListLock) 122 lock (TimerListLock)
122 { 123 {
123 // Go through all timers 124 // Go through all timers
124 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 125 tvals = Timers.Values;
125 foreach (TimerClass ts in tvals) 126 }
127
128 foreach (TimerClass ts in tvals)
129 {
130 // Time has passed?
131 if (ts.next < DateTime.Now.Ticks)
126 { 132 {
127 // Time has passed? 133 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
128 if (ts.next < DateTime.Now.Ticks) 134 // Add it to queue
129 { 135 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
130 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 136 new EventParams("timer", new Object[0],
131 // Add it to queue 137 new DetectParams[0]));
132 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 138 // set next interval
133 new EventParams("timer", new Object[0], 139
134 new DetectParams[0])); 140 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 // set next interval 141 ts.next = DateTime.Now.Ticks + ts.interval;
136
137 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
138 ts.next = DateTime.Now.Ticks + ts.interval;
139 }
140 } 142 }
141 } 143 }
142 } 144 }