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.cs3191
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs116
-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, 2688 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 7620df3..49f0ef7 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;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -103,15 +107,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
103 protected int m_notecardLineReadCharsMax = 255; 107 protected int m_notecardLineReadCharsMax = 255;
104 protected int m_scriptConsoleChannel = 0; 108 protected int m_scriptConsoleChannel = 0;
105 protected bool m_scriptConsoleChannelEnabled = false; 109 protected bool m_scriptConsoleChannelEnabled = false;
110 protected bool m_debuggerSafe = false;
106 protected IUrlModule m_UrlModule = null; 111 protected IUrlModule m_UrlModule = null;
107 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 112 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
108 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 113 new Dictionary<UUID, UserInfoCacheEntry>();
114 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
115
116// protected Timer m_ShoutSayTimer;
117 protected int m_SayShoutCount = 0;
118 DateTime m_lastSayShoutCheck;
119
120 private Dictionary<string, string> MovementAnimationsForLSL =
121 new Dictionary<string, string> {
122 {"FLY", "Flying"},
123 {"FLYSLOW", "FlyingSlow"},
124 {"HOVER_UP", "Hovering Up"},
125 {"HOVER_DOWN", "Hovering Down"},
126 {"HOVER", "Hovering"},
127 {"LAND", "Landing"},
128 {"FALLDOWN", "Falling Down"},
129 {"PREJUMP", "PreJumping"},
130 {"JUMP", "Jumping"},
131 {"STANDUP", "Standing Up"},
132 {"SOFT_LAND", "Soft Landing"},
133 {"STAND", "Standing"},
134 {"CROUCHWALK", "CrouchWalking"},
135 {"RUN", "Running"},
136 {"WALK", "Walking"},
137 {"CROUCH", "Crouching"},
138 {"TURNLEFT", "Turning Left"},
139 {"TURNRIGHT", "Turning Right"}
140 };
109 141
110 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
111 { 143 {
144/*
145 m_ShoutSayTimer = new Timer(1000);
146 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
147 m_ShoutSayTimer.AutoReset = true;
148 m_ShoutSayTimer.Start();
149*/
150 m_lastSayShoutCheck = DateTime.UtcNow;
151
112 m_ScriptEngine = ScriptEngine; 152 m_ScriptEngine = ScriptEngine;
113 m_host = host; 153 m_host = host;
114 m_item = item; 154 m_item = item;
155 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
115 156
116 LoadLimits(); // read script limits from config. 157 LoadLimits(); // read script limits from config.
117 158
@@ -171,6 +212,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
171 get { return m_ScriptEngine.World; } 212 get { return m_ScriptEngine.World; }
172 } 213 }
173 214
215 [DebuggerNonUserCode]
174 public void state(string newState) 216 public void state(string newState)
175 { 217 {
176 m_ScriptEngine.SetState(m_item.ItemID, newState); 218 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -180,6 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
180 /// Reset the named script. The script must be present 222 /// Reset the named script. The script must be present
181 /// in the same prim. 223 /// in the same prim.
182 /// </summary> 224 /// </summary>
225 [DebuggerNonUserCode]
183 public void llResetScript() 226 public void llResetScript()
184 { 227 {
185 m_host.AddScriptLPS(1); 228 m_host.AddScriptLPS(1);
@@ -242,6 +285,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
242 } 285 }
243 } 286 }
244 287
288 public List<ScenePresence> GetLinkAvatars(int linkType)
289 {
290 List<ScenePresence> ret = new List<ScenePresence>();
291 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
292 return ret;
293
294 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
295
296 switch (linkType)
297 {
298 case ScriptBaseClass.LINK_SET:
299 return avs;
300
301 case ScriptBaseClass.LINK_ROOT:
302 return ret;
303
304 case ScriptBaseClass.LINK_ALL_OTHERS:
305 return avs;
306
307 case ScriptBaseClass.LINK_ALL_CHILDREN:
308 return avs;
309
310 case ScriptBaseClass.LINK_THIS:
311 return ret;
312
313 default:
314 if (linkType < 0)
315 return ret;
316
317 int partCount = m_host.ParentGroup.GetPartCount();
318
319 if (linkType <= partCount)
320 {
321 return ret;
322 }
323 else
324 {
325 linkType = linkType - partCount;
326 if (linkType > avs.Count)
327 {
328 return ret;
329 }
330 else
331 {
332 ret.Add(avs[linkType-1]);
333 return ret;
334 }
335 }
336 }
337 }
338
245 public List<SceneObjectPart> GetLinkParts(int linkType) 339 public List<SceneObjectPart> GetLinkParts(int linkType)
246 { 340 {
247 return GetLinkParts(m_host, linkType); 341 return GetLinkParts(m_host, linkType);
@@ -250,6 +344,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
250 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 344 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
251 { 345 {
252 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 346 List<SceneObjectPart> ret = new List<SceneObjectPart>();
347 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
348 return ret;
253 ret.Add(part); 349 ret.Add(part);
254 350
255 switch (linkType) 351 switch (linkType)
@@ -440,31 +536,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
440 536
441 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 537 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
442 538
443 /// <summary> 539 // Utility function for llRot2Euler
444 /// Convert an LSL rotation to a Euler vector. 540
445 /// </summary> 541 // normalize an angle between -PI and PI (-180 to +180 degrees)
446 /// <remarks> 542 protected double NormalizeAngle(double angle)
447 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
448 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
449 /// </remarks>
450 /// <param name="r"></param>
451 /// <returns></returns>
452 public LSL_Vector llRot2Euler(LSL_Rotation r)
453 { 543 {
454 m_host.AddScriptLPS(1); 544 if (angle > -Math.PI && angle < Math.PI)
545 return angle;
455 546
456 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 547 int numPis = (int)(Math.PI / angle);
457 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 548 double remainder = angle - Math.PI * numPis;
458 if (m == 0.0) return new LSL_Vector(); 549 if (numPis % 2 == 1)
459 double x = Math.Atan2(-v.y, v.z); 550 return Math.PI - angle;
460 double sin = v.x / m; 551 return remainder;
461 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 552 }
462 double y = Math.Asin(sin);
463 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
464 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)));
465 double z = Math.Atan2(v.y, v.x);
466 553
467 return new LSL_Vector(x, y, z); 554 public LSL_Vector llRot2Euler(LSL_Rotation q1)
555 {
556 m_host.AddScriptLPS(1);
557 LSL_Vector eul = new LSL_Vector();
558
559 double sqw = q1.s*q1.s;
560 double sqx = q1.x*q1.x;
561 double sqy = q1.z*q1.z;
562 double sqz = q1.y*q1.y;
563 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
564 double test = q1.x*q1.z + q1.y*q1.s;
565 if (test > 0.4999*unit) { // singularity at north pole
566 eul.z = 2 * Math.Atan2(q1.x,q1.s);
567 eul.y = Math.PI/2;
568 eul.x = 0;
569 return eul;
570 }
571 if (test < -0.4999*unit) { // singularity at south pole
572 eul.z = -2 * Math.Atan2(q1.x,q1.s);
573 eul.y = -Math.PI/2;
574 eul.x = 0;
575 return eul;
576 }
577 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
578 eul.y = Math.Asin(2*test/unit);
579 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
580 return eul;
468 } 581 }
469 582
470 /* From wiki: 583 /* From wiki:
@@ -517,18 +630,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
517 m_host.AddScriptLPS(1); 630 m_host.AddScriptLPS(1);
518 631
519 double x,y,z,s; 632 double x,y,z,s;
520 633 v.x *= 0.5;
521 double c1 = Math.Cos(v.x * 0.5); 634 v.y *= 0.5;
522 double c2 = Math.Cos(v.y * 0.5); 635 v.z *= 0.5;
523 double c3 = Math.Cos(v.z * 0.5); 636 double c1 = Math.Cos(v.x);
524 double s1 = Math.Sin(v.x * 0.5); 637 double c2 = Math.Cos(v.y);
525 double s2 = Math.Sin(v.y * 0.5); 638 double c1c2 = c1 * c2;
526 double s3 = Math.Sin(v.z * 0.5); 639 double s1 = Math.Sin(v.x);
527 640 double s2 = Math.Sin(v.y);
528 x = s1 * c2 * c3 + c1 * s2 * s3; 641 double s1s2 = s1 * s2;
529 y = c1 * s2 * c3 - s1 * c2 * s3; 642 double c1s2 = c1 * s2;
530 z = s1 * s2 * c3 + c1 * c2 * s3; 643 double s1c2 = s1 * c2;
531 s = c1 * c2 * c3 - s1 * s2 * s3; 644 double c3 = Math.Cos(v.z);
645 double s3 = Math.Sin(v.z);
646
647 x = s1c2 * c3 + c1s2 * s3;
648 y = c1s2 * c3 - s1c2 * s3;
649 z = s1s2 * c3 + c1c2 * s3;
650 s = c1c2 * c3 - s1s2 * s3;
532 651
533 return new LSL_Rotation(x, y, z, s); 652 return new LSL_Rotation(x, y, z, s);
534 } 653 }
@@ -666,77 +785,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
666 { 785 {
667 //A and B should both be normalized 786 //A and B should both be normalized
668 m_host.AddScriptLPS(1); 787 m_host.AddScriptLPS(1);
669 LSL_Rotation rotBetween; 788 /* This method is more accurate than the SL one, and thus causes problems
670 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 789 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
671 // continue calculation. 790
672 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 791 double dotProduct = LSL_Vector.Dot(a, b);
792 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
793 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
794 double angle = Math.Acos(dotProduct / magProduct);
795 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
796 double s = Math.Sin(angle / 2);
797
798 double x = axis.x * s;
799 double y = axis.y * s;
800 double z = axis.z * s;
801 double w = Math.Cos(angle / 2);
802
803 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
804 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
805
806 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
807 */
808
809 // This method mimics the 180 errors found in SL
810 // See www.euclideanspace.com... angleBetween
811 LSL_Vector vec_a = a;
812 LSL_Vector vec_b = b;
813
814 // Eliminate zero length
815 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
816 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
817 if (vec_a_mag < 0.00001 ||
818 vec_b_mag < 0.00001)
673 { 819 {
674 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 820 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
675 } 821 }
676 else 822
823 // Normalize
824 vec_a = llVecNorm(vec_a);
825 vec_b = llVecNorm(vec_b);
826
827 // Calculate axis and rotation angle
828 LSL_Vector axis = vec_a % vec_b;
829 LSL_Float cos_theta = vec_a * vec_b;
830
831 // Check if parallel
832 if (cos_theta > 0.99999)
677 { 833 {
678 a = LSL_Vector.Norm(a); 834 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
679 b = LSL_Vector.Norm(b); 835 }
680 double dotProduct = LSL_Vector.Dot(a, b); 836
681 // There are two degenerate cases possible. These are for vectors 180 or 837 // Check if anti-parallel
682 // 0 degrees apart. These have to be detected and handled individually. 838 else if (cos_theta < -0.99999)
683 // 839 {
684 // Check for vectors 180 degrees apart. 840 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
685 // A dot product of -1 would mean the angle between vectors is 180 degrees. 841 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
686 if (dotProduct < -0.9999999f) 842 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
687 { 843 }
688 // First assume X axis is orthogonal to the vectors. 844 else // other rotation
689 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 845 {
690 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 846 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
691 // Check for near zero vector. A very small non-zero number here will create 847 axis = llVecNorm(axis);
692 // a rotation in an undesired direction. 848 double x, y, z, s, t;
693 if (LSL_Vector.Mag(orthoVector) > 0.0001) 849 s = Math.Cos(theta);
694 { 850 t = Math.Sin(theta);
695 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 851 x = axis.x * t;
696 } 852 y = axis.y * t;
697 // If the magnitude of the vector was near zero, then assume the X axis is not 853 z = axis.z * t;
698 // orthogonal and use the Z axis instead. 854 return new LSL_Rotation(x,y,z,s);
699 else
700 {
701 // Set 180 z rotation.
702 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
703 }
704 }
705 // Check for parallel vectors.
706 // A dot product of 1 would mean the angle between vectors is 0 degrees.
707 else if (dotProduct > 0.9999999f)
708 {
709 // Set zero rotation.
710 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
711 }
712 else
713 {
714 // All special checks have been performed so get the axis of rotation.
715 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
716 // Quarternion s value is the length of the unit vector + dot product.
717 double qs = 1.0 + dotProduct;
718 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
719 // Normalize the rotation.
720 double mag = LSL_Rotation.Mag(rotBetween);
721 // We shouldn't have to worry about a divide by zero here. The qs value will be
722 // non-zero because we already know if we're here, then the dotProduct is not -1 so
723 // qs will not be zero. Also, we've already handled the input vectors being zero so the
724 // crossProduct vector should also not be zero.
725 rotBetween.x = rotBetween.x / mag;
726 rotBetween.y = rotBetween.y / mag;
727 rotBetween.z = rotBetween.z / mag;
728 rotBetween.s = rotBetween.s / mag;
729 // Check for undefined values and set zero rotation if any found. This code might not actually be required
730 // any longer since zero vectors are checked for at the top.
731 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
732 {
733 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
734 }
735 }
736 } 855 }
737 return rotBetween;
738 } 856 }
739 857
740 public void llWhisper(int channelID, string text) 858 public void llWhisper(int channelID, string text)
741 { 859 {
742 m_host.AddScriptLPS(1); 860 m_host.AddScriptLPS(1);
@@ -752,10 +870,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
752 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 870 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
753 } 871 }
754 872
873 private void CheckSayShoutTime()
874 {
875 DateTime now = DateTime.UtcNow;
876 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
877 {
878 m_lastSayShoutCheck = now;
879 m_SayShoutCount = 0;
880 }
881 else
882 m_SayShoutCount++;
883 }
884
755 public void llSay(int channelID, string text) 885 public void llSay(int channelID, string text)
756 { 886 {
757 m_host.AddScriptLPS(1); 887 m_host.AddScriptLPS(1);
758 888
889 if (channelID == 0)
890// m_SayShoutCount++;
891 CheckSayShoutTime();
892
893 if (m_SayShoutCount >= 11)
894 ScriptSleep(2000);
895
759 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 896 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
760 { 897 {
761 Console.WriteLine(text); 898 Console.WriteLine(text);
@@ -778,6 +915,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
778 { 915 {
779 m_host.AddScriptLPS(1); 916 m_host.AddScriptLPS(1);
780 917
918 if (channelID == 0)
919// m_SayShoutCount++;
920 CheckSayShoutTime();
921
922 if (m_SayShoutCount >= 11)
923 ScriptSleep(2000);
924
781 if (text.Length > 1023) 925 if (text.Length > 1023)
782 text = text.Substring(0, 1023); 926 text = text.Substring(0, 1023);
783 927
@@ -809,22 +953,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
809 953
810 public void llRegionSayTo(string target, int channel, string msg) 954 public void llRegionSayTo(string target, int channel, string msg)
811 { 955 {
956 string error = String.Empty;
957
812 if (msg.Length > 1023) 958 if (msg.Length > 1023)
813 msg = msg.Substring(0, 1023); 959 msg = msg.Substring(0, 1023);
814 960
815 m_host.AddScriptLPS(1); 961 m_host.AddScriptLPS(1);
816 962
817 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
818 {
819 return;
820 }
821
822 UUID TargetID; 963 UUID TargetID;
823 UUID.TryParse(target, out TargetID); 964 UUID.TryParse(target, out TargetID);
824 965
825 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 966 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
826 if (wComm != null) 967 if (wComm != null)
827 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 968 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
969 LSLError(error);
828 } 970 }
829 971
830 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 972 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1080,10 +1222,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1080 return detectedParams.TouchUV; 1222 return detectedParams.TouchUV;
1081 } 1223 }
1082 1224
1225 [DebuggerNonUserCode]
1083 public virtual void llDie() 1226 public virtual void llDie()
1084 { 1227 {
1085 m_host.AddScriptLPS(1); 1228 m_host.AddScriptLPS(1);
1086 throw new SelfDeleteException(); 1229 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1087 } 1230 }
1088 1231
1089 public LSL_Float llGround(LSL_Vector offset) 1232 public LSL_Float llGround(LSL_Vector offset)
@@ -1154,6 +1297,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1154 1297
1155 public void llSetStatus(int status, int value) 1298 public void llSetStatus(int status, int value)
1156 { 1299 {
1300 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1301 return;
1157 m_host.AddScriptLPS(1); 1302 m_host.AddScriptLPS(1);
1158 1303
1159 int statusrotationaxis = 0; 1304 int statusrotationaxis = 0;
@@ -1177,6 +1322,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 if (!allow) 1322 if (!allow)
1178 return; 1323 return;
1179 1324
1325 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1326 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1327 return;
1328
1180 m_host.ScriptSetPhysicsStatus(true); 1329 m_host.ScriptSetPhysicsStatus(true);
1181 } 1330 }
1182 else 1331 else
@@ -1376,6 +1525,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1376 { 1525 {
1377 m_host.AddScriptLPS(1); 1526 m_host.AddScriptLPS(1);
1378 1527
1528 SetColor(m_host, color, face);
1529 }
1530
1531 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1532 {
1533 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1534 return;
1535
1536 Primitive.TextureEntry tex = part.Shape.Textures;
1537 Color4 texcolor;
1538 if (face >= 0 && face < GetNumberOfSides(part))
1539 {
1540 texcolor = tex.CreateFace((uint)face).RGBA;
1541 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1542 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1543 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1544 tex.FaceTextures[face].RGBA = texcolor;
1545 part.UpdateTextureEntry(tex.GetBytes());
1546 return;
1547 }
1548 else if (face == ScriptBaseClass.ALL_SIDES)
1549 {
1550 for (uint i = 0; i < GetNumberOfSides(part); i++)
1551 {
1552 if (tex.FaceTextures[i] != null)
1553 {
1554 texcolor = tex.FaceTextures[i].RGBA;
1555 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1556 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1557 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1558 tex.FaceTextures[i].RGBA = texcolor;
1559 }
1560 texcolor = tex.DefaultTexture.RGBA;
1561 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1562 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1563 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1564 tex.DefaultTexture.RGBA = texcolor;
1565 }
1566 part.UpdateTextureEntry(tex.GetBytes());
1567 return;
1568 }
1569
1379 if (face == ScriptBaseClass.ALL_SIDES) 1570 if (face == ScriptBaseClass.ALL_SIDES)
1380 face = SceneObjectPart.ALL_SIDES; 1571 face = SceneObjectPart.ALL_SIDES;
1381 1572
@@ -1384,6 +1575,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1384 1575
1385 public void SetTexGen(SceneObjectPart part, int face,int style) 1576 public void SetTexGen(SceneObjectPart part, int face,int style)
1386 { 1577 {
1578 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1579 return;
1580
1387 Primitive.TextureEntry tex = part.Shape.Textures; 1581 Primitive.TextureEntry tex = part.Shape.Textures;
1388 MappingType textype; 1582 MappingType textype;
1389 textype = MappingType.Default; 1583 textype = MappingType.Default;
@@ -1414,6 +1608,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1414 1608
1415 public void SetGlow(SceneObjectPart part, int face, float glow) 1609 public void SetGlow(SceneObjectPart part, int face, float glow)
1416 { 1610 {
1611 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1612 return;
1613
1417 Primitive.TextureEntry tex = part.Shape.Textures; 1614 Primitive.TextureEntry tex = part.Shape.Textures;
1418 if (face >= 0 && face < GetNumberOfSides(part)) 1615 if (face >= 0 && face < GetNumberOfSides(part))
1419 { 1616 {
@@ -1439,6 +1636,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1439 1636
1440 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1637 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1441 { 1638 {
1639 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1640 return;
1442 1641
1443 Shininess sval = new Shininess(); 1642 Shininess sval = new Shininess();
1444 1643
@@ -1489,6 +1688,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1489 1688
1490 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1689 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1491 { 1690 {
1691 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1692 return;
1693
1492 Primitive.TextureEntry tex = part.Shape.Textures; 1694 Primitive.TextureEntry tex = part.Shape.Textures;
1493 if (face >= 0 && face < GetNumberOfSides(part)) 1695 if (face >= 0 && face < GetNumberOfSides(part))
1494 { 1696 {
@@ -1549,13 +1751,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1549 m_host.AddScriptLPS(1); 1751 m_host.AddScriptLPS(1);
1550 1752
1551 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1753 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1552 1754 if (parts.Count > 0)
1553 foreach (SceneObjectPart part in parts) 1755 {
1554 SetAlpha(part, alpha, face); 1756 try
1757 {
1758 foreach (SceneObjectPart part in parts)
1759 SetAlpha(part, alpha, face);
1760 }
1761 finally
1762 {
1763 }
1764 }
1555 } 1765 }
1556 1766
1557 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1767 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1558 { 1768 {
1769 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1770 return;
1771
1559 Primitive.TextureEntry tex = part.Shape.Textures; 1772 Primitive.TextureEntry tex = part.Shape.Textures;
1560 Color4 texcolor; 1773 Color4 texcolor;
1561 if (face >= 0 && face < GetNumberOfSides(part)) 1774 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1608,7 +1821,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1608 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1821 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1609 float wind, float tension, LSL_Vector Force) 1822 float wind, float tension, LSL_Vector Force)
1610 { 1823 {
1611 if (part == null) 1824 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1612 return; 1825 return;
1613 1826
1614 if (flexi) 1827 if (flexi)
@@ -1642,7 +1855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1642 /// <param name="falloff"></param> 1855 /// <param name="falloff"></param>
1643 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1856 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1644 { 1857 {
1645 if (part == null) 1858 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1646 return; 1859 return;
1647 1860
1648 if (light) 1861 if (light)
@@ -1675,11 +1888,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1675 Primitive.TextureEntry tex = part.Shape.Textures; 1888 Primitive.TextureEntry tex = part.Shape.Textures;
1676 Color4 texcolor; 1889 Color4 texcolor;
1677 LSL_Vector rgb = new LSL_Vector(); 1890 LSL_Vector rgb = new LSL_Vector();
1891 int nsides = GetNumberOfSides(part);
1892
1678 if (face == ScriptBaseClass.ALL_SIDES) 1893 if (face == ScriptBaseClass.ALL_SIDES)
1679 { 1894 {
1680 int i; 1895 int i;
1681 1896 for (i = 0; i < nsides; i++)
1682 for (i = 0 ; i < GetNumberOfSides(part); i++)
1683 { 1897 {
1684 texcolor = tex.GetFace((uint)i).RGBA; 1898 texcolor = tex.GetFace((uint)i).RGBA;
1685 rgb.x += texcolor.R; 1899 rgb.x += texcolor.R;
@@ -1687,14 +1901,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1687 rgb.z += texcolor.B; 1901 rgb.z += texcolor.B;
1688 } 1902 }
1689 1903
1690 rgb.x /= (float)GetNumberOfSides(part); 1904 float invnsides = 1.0f / (float)nsides;
1691 rgb.y /= (float)GetNumberOfSides(part); 1905
1692 rgb.z /= (float)GetNumberOfSides(part); 1906 rgb.x *= invnsides;
1907 rgb.y *= invnsides;
1908 rgb.z *= invnsides;
1693 1909
1694 return rgb; 1910 return rgb;
1695 } 1911 }
1696 1912 if (face >= 0 && face < nsides)
1697 if (face >= 0 && face < GetNumberOfSides(part))
1698 { 1913 {
1699 texcolor = tex.GetFace((uint)face).RGBA; 1914 texcolor = tex.GetFace((uint)face).RGBA;
1700 rgb.x = texcolor.R; 1915 rgb.x = texcolor.R;
@@ -1721,15 +1936,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1721 m_host.AddScriptLPS(1); 1936 m_host.AddScriptLPS(1);
1722 1937
1723 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1938 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1724 1939 if (parts.Count > 0)
1725 foreach (SceneObjectPart part in parts) 1940 {
1726 SetTexture(part, texture, face); 1941 try
1727 1942 {
1943 foreach (SceneObjectPart part in parts)
1944 SetTexture(part, texture, face);
1945 }
1946 finally
1947 {
1948 }
1949 }
1728 ScriptSleep(200); 1950 ScriptSleep(200);
1729 } 1951 }
1730 1952
1731 protected void SetTexture(SceneObjectPart part, string texture, int face) 1953 protected void SetTexture(SceneObjectPart part, string texture, int face)
1732 { 1954 {
1955 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1956 return;
1957
1733 UUID textureID = new UUID(); 1958 UUID textureID = new UUID();
1734 1959
1735 textureID = InventoryKey(texture, (int)AssetType.Texture); 1960 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1774,6 +1999,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1774 1999
1775 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2000 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1776 { 2001 {
2002 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2003 return;
2004
1777 Primitive.TextureEntry tex = part.Shape.Textures; 2005 Primitive.TextureEntry tex = part.Shape.Textures;
1778 if (face >= 0 && face < GetNumberOfSides(part)) 2006 if (face >= 0 && face < GetNumberOfSides(part))
1779 { 2007 {
@@ -1810,6 +2038,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1810 2038
1811 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2039 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1812 { 2040 {
2041 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2042 return;
2043
1813 Primitive.TextureEntry tex = part.Shape.Textures; 2044 Primitive.TextureEntry tex = part.Shape.Textures;
1814 if (face >= 0 && face < GetNumberOfSides(part)) 2045 if (face >= 0 && face < GetNumberOfSides(part))
1815 { 2046 {
@@ -1846,6 +2077,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1846 2077
1847 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2078 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1848 { 2079 {
2080 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2081 return;
2082
1849 Primitive.TextureEntry tex = part.Shape.Textures; 2083 Primitive.TextureEntry tex = part.Shape.Textures;
1850 if (face >= 0 && face < GetNumberOfSides(part)) 2084 if (face >= 0 && face < GetNumberOfSides(part))
1851 { 2085 {
@@ -2016,24 +2250,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2016 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2250 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2017 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2251 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2018 { 2252 {
2019 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2253 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2254 return;
2255
2020 LSL_Vector currentPos = GetPartLocalPos(part); 2256 LSL_Vector currentPos = GetPartLocalPos(part);
2257 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2021 2258
2022 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2023 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2024 2259
2025 if (part.ParentGroup.RootPart == part) 2260 if (part.ParentGroup.RootPart == part)
2026 { 2261 {
2027 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2028 targetPos.z = ground;
2029 SceneObjectGroup parent = part.ParentGroup; 2262 SceneObjectGroup parent = part.ParentGroup;
2030 parent.UpdateGroupPosition(!adjust ? targetPos : 2263 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2031 SetPosAdjust(currentPos, targetPos)); 2264 return;
2265 Util.FireAndForget(delegate(object x) {
2266 parent.UpdateGroupPosition((Vector3)toPos);
2267 });
2032 } 2268 }
2033 else 2269 else
2034 { 2270 {
2035 part.OffsetPosition = !adjust ? targetPos : 2271 part.OffsetPosition = (Vector3)toPos;
2036 SetPosAdjust(currentPos, targetPos);
2037 SceneObjectGroup parent = part.ParentGroup; 2272 SceneObjectGroup parent = part.ParentGroup;
2038 parent.HasGroupChanged = true; 2273 parent.HasGroupChanged = true;
2039 parent.ScheduleGroupForTerseUpdate(); 2274 parent.ScheduleGroupForTerseUpdate();
@@ -2066,13 +2301,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2066 else 2301 else
2067 { 2302 {
2068 if (part.ParentGroup.IsAttachment) 2303 if (part.ParentGroup.IsAttachment)
2069 {
2070 pos = part.AttachedPos; 2304 pos = part.AttachedPos;
2071 }
2072 else 2305 else
2073 {
2074 pos = part.AbsolutePosition; 2306 pos = part.AbsolutePosition;
2075 }
2076 } 2307 }
2077 2308
2078// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2309// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2112,25 +2343,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2112 2343
2113 protected void SetRot(SceneObjectPart part, Quaternion rot) 2344 protected void SetRot(SceneObjectPart part, Quaternion rot)
2114 { 2345 {
2115 part.UpdateRotation(rot); 2346 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2116 // Update rotation does not move the object in the physics scene if it's a linkset. 2347 return;
2117 2348
2118//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2349 bool isroot = (part == part.ParentGroup.RootPart);
2119// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2350 bool isphys;
2120 2351
2121 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2122 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2123 // It's perfectly okay when the object is not an active physical body though.
2124 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2125 // but only if the object is not physial and active. This is important for rotating doors.
2126 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2127 // scene
2128 PhysicsActor pa = part.PhysActor; 2352 PhysicsActor pa = part.PhysActor;
2129 2353
2130 if (pa != null && !pa.IsPhysical) 2354 // keep using physactor ideia of isphysical
2355 // it should be SOP ideia of that
2356 // not much of a issue with ubitODE
2357 if (pa != null && pa.IsPhysical)
2358 isphys = true;
2359 else
2360 isphys = false;
2361
2362 // SL doesn't let scripts rotate root of physical linksets
2363 if (isroot && isphys)
2364 return;
2365
2366 part.UpdateRotation(rot);
2367
2368 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2369 // so do a nasty update of parts positions if is a root part rotation
2370 if (isroot && pa != null) // with if above implies non physical root part
2131 { 2371 {
2132 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2372 part.ParentGroup.ResetChildPrimPhysicsPositions();
2133 } 2373 }
2374 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2375 {
2376 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2377 if (sittingavas.Count > 0)
2378 {
2379 foreach (ScenePresence av in sittingavas)
2380 {
2381 if (isroot || part.LocalId == av.ParentID)
2382 av.SendTerseUpdateToAllClients();
2383 }
2384 }
2385 }
2134 } 2386 }
2135 2387
2136 /// <summary> 2388 /// <summary>
@@ -2178,8 +2430,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2178 2430
2179 public LSL_Rotation llGetLocalRot() 2431 public LSL_Rotation llGetLocalRot()
2180 { 2432 {
2433 return GetPartLocalRot(m_host);
2434 }
2435
2436 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2437 {
2181 m_host.AddScriptLPS(1); 2438 m_host.AddScriptLPS(1);
2182 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2439 Quaternion rot = part.RotationOffset;
2440 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2183 } 2441 }
2184 2442
2185 public void llSetForce(LSL_Vector force, int local) 2443 public void llSetForce(LSL_Vector force, int local)
@@ -2259,16 +2517,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2259 m_host.ApplyImpulse(v, local != 0); 2517 m_host.ApplyImpulse(v, local != 0);
2260 } 2518 }
2261 2519
2520
2262 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2521 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2263 { 2522 {
2264 m_host.AddScriptLPS(1); 2523 m_host.AddScriptLPS(1);
2265 m_host.ApplyAngularImpulse(force, local != 0); 2524 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2266 } 2525 }
2267 2526
2268 public void llSetTorque(LSL_Vector torque, int local) 2527 public void llSetTorque(LSL_Vector torque, int local)
2269 { 2528 {
2270 m_host.AddScriptLPS(1); 2529 m_host.AddScriptLPS(1);
2271 m_host.SetAngularImpulse(torque, local != 0); 2530 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2272 } 2531 }
2273 2532
2274 public LSL_Vector llGetTorque() 2533 public LSL_Vector llGetTorque()
@@ -2285,20 +2544,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2285 llSetTorque(torque, local); 2544 llSetTorque(torque, local);
2286 } 2545 }
2287 2546
2547 public void llSetVelocity(LSL_Vector vel, int local)
2548 {
2549 m_host.AddScriptLPS(1);
2550 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2551 }
2552
2288 public LSL_Vector llGetVel() 2553 public LSL_Vector llGetVel()
2289 { 2554 {
2290 m_host.AddScriptLPS(1); 2555 m_host.AddScriptLPS(1);
2291 2556
2292 Vector3 vel; 2557 Vector3 vel = Vector3.Zero;
2293 2558
2294 if (m_host.ParentGroup.IsAttachment) 2559 if (m_host.ParentGroup.IsAttachment)
2295 { 2560 {
2296 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2561 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2297 vel = avatar.Velocity; 2562 if (avatar != null)
2563 vel = avatar.Velocity;
2298 } 2564 }
2299 else 2565 else
2300 { 2566 {
2301 vel = m_host.Velocity; 2567 vel = m_host.ParentGroup.RootPart.Velocity;
2302 } 2568 }
2303 2569
2304 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2570 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2310,10 +2576,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2310 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2576 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2311 } 2577 }
2312 2578
2579 public void llSetAngularVelocity(LSL_Vector avel, int local)
2580 {
2581 m_host.AddScriptLPS(1);
2582 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2583 }
2584
2313 public LSL_Vector llGetOmega() 2585 public LSL_Vector llGetOmega()
2314 { 2586 {
2315 m_host.AddScriptLPS(1); 2587 m_host.AddScriptLPS(1);
2316 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2588 Vector3 avel = m_host.AngularVelocity;
2589 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2317 } 2590 }
2318 2591
2319 public LSL_Float llGetTimeOfDay() 2592 public LSL_Float llGetTimeOfDay()
@@ -2839,16 +3112,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2839 new_group.RootPart.UUID.ToString()) }, 3112 new_group.RootPart.UUID.ToString()) },
2840 new DetectParams[0])); 3113 new DetectParams[0]));
2841 3114
2842 float groupmass = new_group.GetMass(); 3115 // do recoil
3116 SceneObjectGroup hostgrp = m_host.ParentGroup;
3117 if (hostgrp == null)
3118 return;
3119
3120 if (hostgrp.IsAttachment) // don't recoil avatars
3121 return;
2843 3122
2844 PhysicsActor pa = new_group.RootPart.PhysActor; 3123 PhysicsActor pa = new_group.RootPart.PhysActor;
2845 3124
2846 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3125 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2847 { 3126 {
2848 //Recoil. 3127 float groupmass = new_group.GetMass();
2849 llApplyImpulse(vel * groupmass, 0); 3128 vel *= -groupmass;
3129 llApplyImpulse(vel, 0);
2850 } 3130 }
2851 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3131 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3132 return;
3133
2852 }); 3134 });
2853 3135
2854 //ScriptSleep((int)((groupmass * velmag) / 10)); 3136 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2863,35 +3145,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2863 public void llLookAt(LSL_Vector target, double strength, double damping) 3145 public void llLookAt(LSL_Vector target, double strength, double damping)
2864 { 3146 {
2865 m_host.AddScriptLPS(1); 3147 m_host.AddScriptLPS(1);
2866 // Determine where we are looking from
2867 LSL_Vector from = llGetPos();
2868 3148
2869 // Work out the normalised vector from the source to the target 3149 // Get the normalized vector to the target
2870 LSL_Vector delta = llVecNorm(target - from); 3150 LSL_Vector d1 = llVecNorm(target - llGetPos());
2871 LSL_Vector angle = new LSL_Vector(0,0,0);
2872 3151
2873 // Calculate the yaw 3152 // Get the bearing (yaw)
2874 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3153 LSL_Vector a1 = new LSL_Vector(0,0,0);
2875 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3154 a1.z = llAtan2(d1.y, d1.x);
2876 3155
2877 // Calculate pitch 3156 // Get the elevation (pitch)
2878 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3157 LSL_Vector a2 = new LSL_Vector(0,0,0);
3158 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2879 3159
2880 // we need to convert from a vector describing 3160 LSL_Rotation r1 = llEuler2Rot(a1);
2881 // the angles of rotation in radians into rotation value 3161 LSL_Rotation r2 = llEuler2Rot(a2);
2882 LSL_Rotation rot = llEuler2Rot(angle); 3162 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2883
2884 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2885 // set the rotation of the object, copy that behavior
2886 PhysicsActor pa = m_host.PhysActor;
2887 3163
2888 if (strength == 0 || pa == null || !pa.IsPhysical) 3164 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2889 { 3165 {
2890 llSetRot(rot); 3166 // Do nothing if either value is 0 (this has been checked in SL)
3167 if (strength <= 0.0 || damping <= 0.0)
3168 return;
3169
3170 llSetRot(r3 * r2 * r1);
2891 } 3171 }
2892 else 3172 else
2893 { 3173 {
2894 m_host.StartLookAt(rot, (float)strength, (float)damping); 3174 if (strength == 0)
3175 {
3176 llSetRot(r3 * r2 * r1);
3177 return;
3178 }
3179
3180 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2895 } 3181 }
2896 } 3182 }
2897 3183
@@ -2937,17 +3223,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2937 } 3223 }
2938 else 3224 else
2939 { 3225 {
2940 if (m_host.IsRoot) 3226 // new SL always returns object mass
2941 { 3227// if (m_host.IsRoot)
3228// {
2942 return m_host.ParentGroup.GetMass(); 3229 return m_host.ParentGroup.GetMass();
2943 } 3230// }
2944 else 3231// else
2945 { 3232// {
2946 return m_host.GetMass(); 3233// return m_host.GetMass();
2947 } 3234// }
2948 } 3235 }
2949 } 3236 }
2950 3237
3238
3239 public LSL_Float llGetMassMKS()
3240 {
3241 return 100f * llGetMass();
3242 }
3243
2951 public void llCollisionFilter(string name, string id, int accept) 3244 public void llCollisionFilter(string name, string id, int accept)
2952 { 3245 {
2953 m_host.AddScriptLPS(1); 3246 m_host.AddScriptLPS(1);
@@ -2995,8 +3288,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2995 { 3288 {
2996 // Unregister controls from Presence 3289 // Unregister controls from Presence
2997 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3290 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2998 // Remove Take Control permission.
2999 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3000 } 3291 }
3001 } 3292 }
3002 } 3293 }
@@ -3022,7 +3313,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3022 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3313 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3023 3314
3024 if (attachmentsModule != null) 3315 if (attachmentsModule != null)
3025 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3316 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3026 else 3317 else
3027 return false; 3318 return false;
3028 } 3319 }
@@ -3052,9 +3343,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3052 { 3343 {
3053 m_host.AddScriptLPS(1); 3344 m_host.AddScriptLPS(1);
3054 3345
3055// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3056// return;
3057
3058 if (m_item.PermsGranter != m_host.OwnerID) 3346 if (m_item.PermsGranter != m_host.OwnerID)
3059 return; 3347 return;
3060 3348
@@ -3097,6 +3385,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3097 3385
3098 public void llInstantMessage(string user, string message) 3386 public void llInstantMessage(string user, string message)
3099 { 3387 {
3388 UUID result;
3389 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3390 {
3391 ShoutError("An invalid key was passed to llInstantMessage");
3392 ScriptSleep(2000);
3393 return;
3394 }
3395
3396
3100 m_host.AddScriptLPS(1); 3397 m_host.AddScriptLPS(1);
3101 3398
3102 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3399 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3111,14 +3408,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3111 UUID friendTransactionID = UUID.Random(); 3408 UUID friendTransactionID = UUID.Random();
3112 3409
3113 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3410 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3114 3411
3115 GridInstantMessage msg = new GridInstantMessage(); 3412 GridInstantMessage msg = new GridInstantMessage();
3116 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3413 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3117 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3414 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3118 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3415 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3119// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3416// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3120// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3417// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3121 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3418// DateTime dt = DateTime.UtcNow;
3419//
3420// // Ticks from UtcNow, but make it look like local. Evil, huh?
3421// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3422//
3423// try
3424// {
3425// // Convert that to the PST timezone
3426// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3427// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3428// }
3429// catch
3430// {
3431// // No logging here, as it could be VERY spammy
3432// }
3433//
3434// // And make it look local again to fool the unix time util
3435// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3436
3437 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3438
3122 //if (client != null) 3439 //if (client != null)
3123 //{ 3440 //{
3124 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3441 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3132,12 +3449,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3132 msg.message = message.Substring(0, 1024); 3449 msg.message = message.Substring(0, 1024);
3133 else 3450 else
3134 msg.message = message; 3451 msg.message = message;
3135 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3452 msg.dialog = (byte)19; // MessageFromObject
3136 msg.fromGroup = false;// fromGroup; 3453 msg.fromGroup = false;// fromGroup;
3137 msg.offline = (byte)0; //offline; 3454 msg.offline = (byte)0; //offline;
3138 msg.ParentEstateID = 0; //ParentEstateID; 3455 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3139 msg.Position = new Vector3(m_host.AbsolutePosition); 3456 msg.Position = new Vector3(m_host.AbsolutePosition);
3140 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3457 msg.RegionID = World.RegionInfo.RegionID.Guid;
3141 msg.binaryBucket 3458 msg.binaryBucket
3142 = Util.StringToBytes256( 3459 = Util.StringToBytes256(
3143 "{0}/{1}/{2}/{3}", 3460 "{0}/{1}/{2}/{3}",
@@ -3165,7 +3482,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3165 } 3482 }
3166 3483
3167 emailModule.SendEmail(m_host.UUID, address, subject, message); 3484 emailModule.SendEmail(m_host.UUID, address, subject, message);
3168 llSleep(EMAIL_PAUSE_TIME); 3485 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3169 } 3486 }
3170 3487
3171 public void llGetNextEmail(string address, string subject) 3488 public void llGetNextEmail(string address, string subject)
@@ -3411,7 +3728,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3411 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3728 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3412 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3729 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3413 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3730 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3731 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3414 ScriptBaseClass.PERMISSION_ATTACH; 3732 ScriptBaseClass.PERMISSION_ATTACH;
3733
3415 } 3734 }
3416 else 3735 else
3417 { 3736 {
@@ -3446,11 +3765,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3446 3765
3447 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3766 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3448 { 3767 {
3449 lock (m_host.TaskInventory) 3768 m_host.TaskInventory.LockItemsForWrite(true);
3450 { 3769 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3451 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3770 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3452 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3771 m_host.TaskInventory.LockItemsForWrite(false);
3453 }
3454 3772
3455 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3773 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3456 "run_time_permissions", new Object[] { 3774 "run_time_permissions", new Object[] {
@@ -3493,11 +3811,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3493 3811
3494 if (!m_waitingForScriptAnswer) 3812 if (!m_waitingForScriptAnswer)
3495 { 3813 {
3496 lock (m_host.TaskInventory) 3814 m_host.TaskInventory.LockItemsForWrite(true);
3497 { 3815 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3498 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3816 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3499 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3817 m_host.TaskInventory.LockItemsForWrite(false);
3500 }
3501 3818
3502 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3819 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3503 m_waitingForScriptAnswer=true; 3820 m_waitingForScriptAnswer=true;
@@ -3526,14 +3843,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3526 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3843 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3527 llReleaseControls(); 3844 llReleaseControls();
3528 3845
3529 lock (m_host.TaskInventory) 3846 m_host.TaskInventory.LockItemsForWrite(true);
3530 { 3847 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3531 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3848 m_host.TaskInventory.LockItemsForWrite(false);
3532 } 3849
3533 3850 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3534 m_ScriptEngine.PostScriptEvent( 3851 "run_time_permissions", new Object[] {
3535 m_item.ItemID, 3852 new LSL_Integer(answer) },
3536 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3853 new DetectParams[0]));
3537 } 3854 }
3538 3855
3539 public LSL_String llGetPermissionsKey() 3856 public LSL_String llGetPermissionsKey()
@@ -3572,14 +3889,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3572 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3889 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3573 { 3890 {
3574 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3891 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3575 3892 if (parts.Count > 0)
3576 foreach (SceneObjectPart part in parts) 3893 {
3577 part.SetFaceColorAlpha(face, color, null); 3894 try
3895 {
3896 foreach (SceneObjectPart part in parts)
3897 part.SetFaceColorAlpha(face, color, null);
3898 }
3899 finally
3900 {
3901 }
3902 }
3578 } 3903 }
3579 3904
3580 public void llCreateLink(string target, int parent) 3905 public void llCreateLink(string target, int parent)
3581 { 3906 {
3582 m_host.AddScriptLPS(1); 3907 m_host.AddScriptLPS(1);
3908
3583 UUID targetID; 3909 UUID targetID;
3584 3910
3585 if (!UUID.TryParse(target, out targetID)) 3911 if (!UUID.TryParse(target, out targetID))
@@ -3685,10 +4011,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3685 // Restructuring Multiple Prims. 4011 // Restructuring Multiple Prims.
3686 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4012 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3687 parts.Remove(parentPrim.RootPart); 4013 parts.Remove(parentPrim.RootPart);
3688 foreach (SceneObjectPart part in parts) 4014 if (parts.Count > 0)
3689 { 4015 {
3690 parentPrim.DelinkFromGroup(part.LocalId, true); 4016 try
4017 {
4018 foreach (SceneObjectPart part in parts)
4019 {
4020 parentPrim.DelinkFromGroup(part.LocalId, true);
4021 }
4022 }
4023 finally
4024 {
4025 }
3691 } 4026 }
4027
3692 parentPrim.HasGroupChanged = true; 4028 parentPrim.HasGroupChanged = true;
3693 parentPrim.ScheduleGroupForFullUpdate(); 4029 parentPrim.ScheduleGroupForFullUpdate();
3694 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4030 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3697,12 +4033,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3697 { 4033 {
3698 SceneObjectPart newRoot = parts[0]; 4034 SceneObjectPart newRoot = parts[0];
3699 parts.Remove(newRoot); 4035 parts.Remove(newRoot);
3700 foreach (SceneObjectPart part in parts) 4036
4037 try
3701 { 4038 {
3702 // Required for linking 4039 foreach (SceneObjectPart part in parts)
3703 part.ClearUpdateSchedule(); 4040 {
3704 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4041 part.ClearUpdateSchedule();
4042 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4043 }
3705 } 4044 }
4045 finally
4046 {
4047 }
4048
4049
3706 newRoot.ParentGroup.HasGroupChanged = true; 4050 newRoot.ParentGroup.HasGroupChanged = true;
3707 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4051 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3708 } 4052 }
@@ -3722,6 +4066,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3722 public void llBreakAllLinks() 4066 public void llBreakAllLinks()
3723 { 4067 {
3724 m_host.AddScriptLPS(1); 4068 m_host.AddScriptLPS(1);
4069
4070 TaskInventoryItem item = m_item;
4071
4072 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4073 && !m_automaticLinkPermission)
4074 {
4075 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4076 return;
4077 }
4078
3725 SceneObjectGroup parentPrim = m_host.ParentGroup; 4079 SceneObjectGroup parentPrim = m_host.ParentGroup;
3726 if (parentPrim.AttachmentPoint != 0) 4080 if (parentPrim.AttachmentPoint != 0)
3727 return; // Fail silently if attached 4081 return; // Fail silently if attached
@@ -3741,25 +4095,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3741 public LSL_String llGetLinkKey(int linknum) 4095 public LSL_String llGetLinkKey(int linknum)
3742 { 4096 {
3743 m_host.AddScriptLPS(1); 4097 m_host.AddScriptLPS(1);
3744 List<UUID> keytable = new List<UUID>();
3745 // parse for sitting avatare-uuids
3746 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3747 {
3748 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3749 keytable.Add(presence.UUID);
3750 });
3751
3752 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3753 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3754 {
3755 return keytable[totalprims - linknum].ToString();
3756 }
3757
3758 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3759 {
3760 return m_host.UUID.ToString();
3761 }
3762
3763 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4098 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3764 if (part != null) 4099 if (part != null)
3765 { 4100 {
@@ -3767,6 +4102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3767 } 4102 }
3768 else 4103 else
3769 { 4104 {
4105 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4106 {
4107 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4108
4109 if (linknum < 0)
4110 return UUID.Zero.ToString();
4111
4112 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4113 if (avatars.Count > linknum)
4114 {
4115 return avatars[linknum].UUID.ToString();
4116 }
4117 }
3770 return UUID.Zero.ToString(); 4118 return UUID.Zero.ToString();
3771 } 4119 }
3772 } 4120 }
@@ -3866,17 +4214,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3866 m_host.AddScriptLPS(1); 4214 m_host.AddScriptLPS(1);
3867 int count = 0; 4215 int count = 0;
3868 4216
3869 lock (m_host.TaskInventory) 4217 m_host.TaskInventory.LockItemsForRead(true);
4218 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3870 { 4219 {
3871 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4220 if (inv.Value.Type == type || type == -1)
3872 { 4221 {
3873 if (inv.Value.Type == type || type == -1) 4222 count = count + 1;
3874 {
3875 count = count + 1;
3876 }
3877 } 4223 }
3878 } 4224 }
3879 4225
4226 m_host.TaskInventory.LockItemsForRead(false);
3880 return count; 4227 return count;
3881 } 4228 }
3882 4229
@@ -3885,16 +4232,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3885 m_host.AddScriptLPS(1); 4232 m_host.AddScriptLPS(1);
3886 ArrayList keys = new ArrayList(); 4233 ArrayList keys = new ArrayList();
3887 4234
3888 lock (m_host.TaskInventory) 4235 m_host.TaskInventory.LockItemsForRead(true);
4236 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3889 { 4237 {
3890 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4238 if (inv.Value.Type == type || type == -1)
3891 { 4239 {
3892 if (inv.Value.Type == type || type == -1) 4240 keys.Add(inv.Value.Name);
3893 {
3894 keys.Add(inv.Value.Name);
3895 }
3896 } 4241 }
3897 } 4242 }
4243 m_host.TaskInventory.LockItemsForRead(false);
3898 4244
3899 if (keys.Count == 0) 4245 if (keys.Count == 0)
3900 { 4246 {
@@ -3932,7 +4278,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3932 if (item == null) 4278 if (item == null)
3933 { 4279 {
3934 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4280 llSay(0, String.Format("Could not find object '{0}'", inventory));
3935 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4281 return;
4282// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3936 } 4283 }
3937 4284
3938 UUID objId = item.ItemID; 4285 UUID objId = item.ItemID;
@@ -3960,33 +4307,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3960 return; 4307 return;
3961 } 4308 }
3962 } 4309 }
4310
3963 // destination is an avatar 4311 // destination is an avatar
3964 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4312 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3965 4313
3966 if (agentItem == null) 4314 if (agentItem == null)
3967 return; 4315 return;
3968 4316
3969 if (m_TransferModule != null) 4317 byte[] bucket = new byte[1];
3970 { 4318 bucket[0] = (byte)item.Type;
3971 byte[] bucket = new byte[] { (byte)item.Type }; 4319 //byte[] objBytes = agentItem.ID.GetBytes();
4320 //Array.Copy(objBytes, 0, bucket, 1, 16);
4321
4322 GridInstantMessage msg = new GridInstantMessage(World,
4323 m_host.OwnerID, m_host.Name, destId,
4324 (byte)InstantMessageDialog.TaskInventoryOffered,
4325 false, item.Name+". "+m_host.Name+" is located at "+
4326 World.RegionInfo.RegionName+" "+
4327 m_host.AbsolutePosition.ToString(),
4328 agentItem.ID, true, m_host.AbsolutePosition,
4329 bucket, true);
3972 4330
3973 GridInstantMessage msg = new GridInstantMessage(World, 4331 ScenePresence sp;
3974 m_host.UUID, m_host.Name + ", an object owned by " +
3975 resolveName(m_host.OwnerID) + ",", destId,
3976 (byte)InstantMessageDialog.TaskInventoryOffered,
3977 false, item.Name + "\n" + m_host.Name + " is located at " +
3978 World.RegionInfo.RegionName+" "+
3979 m_host.AbsolutePosition.ToString(),
3980 agentItem.ID, true, m_host.AbsolutePosition,
3981 bucket, true); // TODO: May actually send no timestamp
3982 4332
3983 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4333 if (World.TryGetScenePresence(destId, out sp))
4334 {
4335 sp.ControllingClient.SendInstantMessage(msg);
3984 } 4336 }
3985 4337 else
4338 {
4339 if (m_TransferModule != null)
4340 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4341 }
4342
4343 //This delay should only occur when giving inventory to avatars.
3986 ScriptSleep(3000); 4344 ScriptSleep(3000);
3987 } 4345 }
3988 } 4346 }
3989 4347
4348 [DebuggerNonUserCode]
3990 public void llRemoveInventory(string name) 4349 public void llRemoveInventory(string name)
3991 { 4350 {
3992 m_host.AddScriptLPS(1); 4351 m_host.AddScriptLPS(1);
@@ -4041,109 +4400,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4041 { 4400 {
4042 m_host.AddScriptLPS(1); 4401 m_host.AddScriptLPS(1);
4043 4402
4044 UUID uuid = (UUID)id; 4403 UUID uuid;
4045 PresenceInfo pinfo = null; 4404 if (UUID.TryParse(id, out uuid))
4046 UserAccount account;
4047
4048 UserInfoCacheEntry ce;
4049 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4050 { 4405 {
4051 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4406 PresenceInfo pinfo = null;
4052 if (account == null) 4407 UserAccount account;
4408
4409 UserInfoCacheEntry ce;
4410 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4053 { 4411 {
4054 m_userInfoCache[uuid] = null; // Cache negative 4412 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4055 return UUID.Zero.ToString(); 4413 if (account == null)
4056 } 4414 {
4415 m_userInfoCache[uuid] = null; // Cache negative
4416 return UUID.Zero.ToString();
4417 }
4057 4418
4058 4419
4059 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4420 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4060 if (pinfos != null && pinfos.Length > 0) 4421 if (pinfos != null && pinfos.Length > 0)
4061 {
4062 foreach (PresenceInfo p in pinfos)
4063 { 4422 {
4064 if (p.RegionID != UUID.Zero) 4423 foreach (PresenceInfo p in pinfos)
4065 { 4424 {
4066 pinfo = p; 4425 if (p.RegionID != UUID.Zero)
4426 {
4427 pinfo = p;
4428 }
4067 } 4429 }
4068 } 4430 }
4069 }
4070 4431
4071 ce = new UserInfoCacheEntry(); 4432 ce = new UserInfoCacheEntry();
4072 ce.time = Util.EnvironmentTickCount(); 4433 ce.time = Util.EnvironmentTickCount();
4073 ce.account = account; 4434 ce.account = account;
4074 ce.pinfo = pinfo; 4435 ce.pinfo = pinfo;
4075 } 4436 m_userInfoCache[uuid] = ce;
4076 else 4437 }
4077 { 4438 else
4078 if (ce == null) 4439 {
4079 return UUID.Zero.ToString(); 4440 if (ce == null)
4441 return UUID.Zero.ToString();
4080 4442
4081 account = ce.account; 4443 account = ce.account;
4082 pinfo = ce.pinfo; 4444 pinfo = ce.pinfo;
4083 } 4445 }
4084 4446
4085 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4447 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4086 {
4087 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4088 if (pinfos != null && pinfos.Length > 0)
4089 { 4448 {
4090 foreach (PresenceInfo p in pinfos) 4449 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4450 if (pinfos != null && pinfos.Length > 0)
4091 { 4451 {
4092 if (p.RegionID != UUID.Zero) 4452 foreach (PresenceInfo p in pinfos)
4093 { 4453 {
4094 pinfo = p; 4454 if (p.RegionID != UUID.Zero)
4455 {
4456 pinfo = p;
4457 }
4095 } 4458 }
4096 } 4459 }
4097 } 4460 else
4098 else 4461 pinfo = null;
4099 pinfo = null;
4100 4462
4101 ce.time = Util.EnvironmentTickCount(); 4463 ce.time = Util.EnvironmentTickCount();
4102 ce.pinfo = pinfo; 4464 ce.pinfo = pinfo;
4103 } 4465 }
4104 4466
4105 string reply = String.Empty; 4467 string reply = String.Empty;
4106 4468
4107 switch (data) 4469 switch (data)
4108 { 4470 {
4109 case 1: // DATA_ONLINE (0|1) 4471 case 1: // DATA_ONLINE (0|1)
4110 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4472 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4111 reply = "1"; 4473 reply = "1";
4112 else 4474 else
4113 reply = "0"; 4475 reply = "0";
4114 break; 4476 break;
4115 case 2: // DATA_NAME (First Last) 4477 case 2: // DATA_NAME (First Last)
4116 reply = account.FirstName + " " + account.LastName; 4478 reply = account.FirstName + " " + account.LastName;
4117 break; 4479 break;
4118 case 3: // DATA_BORN (YYYY-MM-DD) 4480 case 3: // DATA_BORN (YYYY-MM-DD)
4119 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4481 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4120 born = born.AddSeconds(account.Created); 4482 born = born.AddSeconds(account.Created);
4121 reply = born.ToString("yyyy-MM-dd"); 4483 reply = born.ToString("yyyy-MM-dd");
4122 break; 4484 break;
4123 case 4: // DATA_RATING (0,0,0,0,0,0) 4485 case 4: // DATA_RATING (0,0,0,0,0,0)
4124 reply = "0,0,0,0,0,0"; 4486 reply = "0,0,0,0,0,0";
4125 break; 4487 break;
4126 case 7: // DATA_USERLEVEL (integer) 4488 case 8: // DATA_PAYINFO (0|1|2|3)
4127 reply = account.UserLevel.ToString(); 4489 reply = "0";
4128 break; 4490 break;
4129 case 8: // DATA_PAYINFO (0|1|2|3) 4491 default:
4130 reply = "0"; 4492 return UUID.Zero.ToString(); // Raise no event
4131 break; 4493 }
4132 default:
4133 return UUID.Zero.ToString(); // Raise no event
4134 }
4135 4494
4136 UUID rq = UUID.Random(); 4495 UUID rq = UUID.Random();
4137 4496
4138 UUID tid = AsyncCommands. 4497 UUID tid = AsyncCommands.
4139 DataserverPlugin.RegisterRequest(m_host.LocalId, 4498 DataserverPlugin.RegisterRequest(m_host.LocalId,
4140 m_item.ItemID, rq.ToString()); 4499 m_item.ItemID, rq.ToString());
4141 4500
4142 AsyncCommands. 4501 AsyncCommands.
4143 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4502 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4144 4503
4145 ScriptSleep(100); 4504 ScriptSleep(100);
4146 return tid.ToString(); 4505 return tid.ToString();
4506 }
4507 else
4508 {
4509 ShoutError("Invalid UUID passed to llRequestAgentData.");
4510 }
4511 return "";
4147 } 4512 }
4148 4513
4149 public LSL_String llRequestInventoryData(string name) 4514 public LSL_String llRequestInventoryData(string name)
@@ -4200,13 +4565,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4200 if (UUID.TryParse(agent, out agentId)) 4565 if (UUID.TryParse(agent, out agentId))
4201 { 4566 {
4202 ScenePresence presence = World.GetScenePresence(agentId); 4567 ScenePresence presence = World.GetScenePresence(agentId);
4203 if (presence != null) 4568 if (presence != null && presence.PresenceType != PresenceType.Npc)
4204 { 4569 {
4570 // agent must not be a god
4571 if (presence.UserLevel >= 200) return;
4572
4205 // agent must be over the owners land 4573 // agent must be over the owners land
4206 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4574 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4207 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4575 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4208 { 4576 {
4209 World.TeleportClientHome(agentId, presence.ControllingClient); 4577 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4578 {
4579 // They can't be teleported home for some reason
4580 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4581 if (regionInfo != null)
4582 {
4583 World.RequestTeleportLocation(
4584 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4585 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4586 }
4587 }
4210 } 4588 }
4211 } 4589 }
4212 } 4590 }
@@ -4313,7 +4691,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4313 UUID av = new UUID(); 4691 UUID av = new UUID();
4314 if (!UUID.TryParse(agent,out av)) 4692 if (!UUID.TryParse(agent,out av))
4315 { 4693 {
4316 LSLError("First parameter to llDialog needs to be a key"); 4694 //LSLError("First parameter to llDialog needs to be a key");
4317 return; 4695 return;
4318 } 4696 }
4319 4697
@@ -4345,7 +4723,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4345 public void llCollisionSound(string impact_sound, double impact_volume) 4723 public void llCollisionSound(string impact_sound, double impact_volume)
4346 { 4724 {
4347 m_host.AddScriptLPS(1); 4725 m_host.AddScriptLPS(1);
4348 4726
4727 if(impact_sound == "")
4728 {
4729 m_host.CollisionSoundVolume = (float)impact_volume;
4730 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4731 m_host.CollisionSoundType = 0;
4732 return;
4733 }
4349 // TODO: Parameter check logic required. 4734 // TODO: Parameter check logic required.
4350 UUID soundId = UUID.Zero; 4735 UUID soundId = UUID.Zero;
4351 if (!UUID.TryParse(impact_sound, out soundId)) 4736 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4358,6 +4743,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4358 4743
4359 m_host.CollisionSound = soundId; 4744 m_host.CollisionSound = soundId;
4360 m_host.CollisionSoundVolume = (float)impact_volume; 4745 m_host.CollisionSoundVolume = (float)impact_volume;
4746 m_host.CollisionSoundType = 1;
4361 } 4747 }
4362 4748
4363 public LSL_String llGetAnimation(string id) 4749 public LSL_String llGetAnimation(string id)
@@ -4371,14 +4757,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4371 4757
4372 if (m_host.RegionHandle == presence.RegionHandle) 4758 if (m_host.RegionHandle == presence.RegionHandle)
4373 { 4759 {
4374 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4375
4376 if (presence != null) 4760 if (presence != null)
4377 { 4761 {
4378 AnimationSet currentAnims = presence.Animator.Animations; 4762 if (presence.SitGround)
4379 string currentAnimationState = String.Empty; 4763 return "Sitting on Ground";
4380 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4764 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4381 return currentAnimationState; 4765 return "Sitting";
4766
4767 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4768 string lslMovementAnimation;
4769
4770 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4771 return lslMovementAnimation;
4382 } 4772 }
4383 } 4773 }
4384 4774
@@ -4525,7 +4915,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4525 { 4915 {
4526 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4916 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4527 float distance_term = distance * distance * distance; // Script Energy 4917 float distance_term = distance * distance * distance; // Script Energy
4528 float pusher_mass = m_host.GetMass(); 4918 // use total object mass and not part
4919 float pusher_mass = m_host.ParentGroup.GetMass();
4529 4920
4530 float PUSH_ATTENUATION_DISTANCE = 17f; 4921 float PUSH_ATTENUATION_DISTANCE = 17f;
4531 float PUSH_ATTENUATION_SCALE = 5f; 4922 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4775,6 +5166,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4775 { 5166 {
4776 return item.AssetID.ToString(); 5167 return item.AssetID.ToString();
4777 } 5168 }
5169 m_host.TaskInventory.LockItemsForRead(false);
4778 5170
4779 return UUID.Zero.ToString(); 5171 return UUID.Zero.ToString();
4780 } 5172 }
@@ -4908,7 +5300,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4908 public LSL_Vector llGetCenterOfMass() 5300 public LSL_Vector llGetCenterOfMass()
4909 { 5301 {
4910 m_host.AddScriptLPS(1); 5302 m_host.AddScriptLPS(1);
4911 Vector3 center = m_host.GetGeometricCenter(); 5303 Vector3 center = m_host.GetCenterOfMass();
4912 return new LSL_Vector(center.X,center.Y,center.Z); 5304 return new LSL_Vector(center.X,center.Y,center.Z);
4913 } 5305 }
4914 5306
@@ -4927,14 +5319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4927 { 5319 {
4928 m_host.AddScriptLPS(1); 5320 m_host.AddScriptLPS(1);
4929 5321
4930 if (src == null) 5322 return src.Length;
4931 {
4932 return 0;
4933 }
4934 else
4935 {
4936 return src.Length;
4937 }
4938 } 5323 }
4939 5324
4940 public LSL_Integer llList2Integer(LSL_List src, int index) 5325 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5005,7 +5390,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5005 else if (src.Data[index] is LSL_Float) 5390 else if (src.Data[index] is LSL_Float)
5006 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5391 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5007 else if (src.Data[index] is LSL_String) 5392 else if (src.Data[index] is LSL_String)
5008 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5393 {
5394 string str = ((LSL_String) src.Data[index]).m_string;
5395 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5396 if (m != Match.Empty)
5397 {
5398 str = m.Value;
5399 double d = 0.0;
5400 if (!Double.TryParse(str, out d))
5401 return 0.0;
5402
5403 return d;
5404 }
5405 return 0.0;
5406 }
5009 return Convert.ToDouble(src.Data[index]); 5407 return Convert.ToDouble(src.Data[index]);
5010 } 5408 }
5011 catch (FormatException) 5409 catch (FormatException)
@@ -5047,7 +5445,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5047 // for completion and should LSL_Key ever be implemented 5445 // for completion and should LSL_Key ever be implemented
5048 // as it's own struct 5446 // as it's own struct
5049 else if (!(src.Data[index] is LSL_String || 5447 else if (!(src.Data[index] is LSL_String ||
5050 src.Data[index] is LSL_Key)) 5448 src.Data[index] is LSL_Key ||
5449 src.Data[index] is String))
5051 { 5450 {
5052 return ""; 5451 return "";
5053 } 5452 }
@@ -5305,7 +5704,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5305 } 5704 }
5306 } 5705 }
5307 } 5706 }
5308 else { 5707 else
5708 {
5309 object[] array = new object[src.Length]; 5709 object[] array = new object[src.Length];
5310 Array.Copy(src.Data, 0, array, 0, src.Length); 5710 Array.Copy(src.Data, 0, array, 0, src.Length);
5311 result = new LSL_List(array); 5711 result = new LSL_List(array);
@@ -5412,7 +5812,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5412 public LSL_Integer llGetRegionAgentCount() 5812 public LSL_Integer llGetRegionAgentCount()
5413 { 5813 {
5414 m_host.AddScriptLPS(1); 5814 m_host.AddScriptLPS(1);
5415 return new LSL_Integer(World.GetRootAgentCount()); 5815
5816 int count = 0;
5817 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5818 count++;
5819 });
5820
5821 return new LSL_Integer(count);
5416 } 5822 }
5417 5823
5418 public LSL_Vector llGetRegionCorner() 5824 public LSL_Vector llGetRegionCorner()
@@ -5653,6 +6059,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5653 flags |= ScriptBaseClass.AGENT_AWAY; 6059 flags |= ScriptBaseClass.AGENT_AWAY;
5654 } 6060 }
5655 6061
6062 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6063 UUID[] anims = agent.Animator.GetAnimationArray();
6064 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6065 {
6066 flags |= ScriptBaseClass.AGENT_BUSY;
6067 }
6068
5656 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6069 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5657 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6070 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5658 { 6071 {
@@ -5700,6 +6113,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5700 flags |= ScriptBaseClass.AGENT_SITTING; 6113 flags |= ScriptBaseClass.AGENT_SITTING;
5701 } 6114 }
5702 6115
6116 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6117 {
6118 flags |= ScriptBaseClass.AGENT_MALE;
6119 }
6120
5703 return flags; 6121 return flags;
5704 } 6122 }
5705 6123
@@ -5847,9 +6265,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5847 6265
5848 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6266 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5849 6267
5850 foreach (SceneObjectPart part in parts) 6268 try
6269 {
6270 foreach (SceneObjectPart part in parts)
6271 {
6272 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6273 }
6274 }
6275 finally
5851 { 6276 {
5852 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5853 } 6277 }
5854 } 6278 }
5855 6279
@@ -5901,13 +6325,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5901 6325
5902 if (m_host.OwnerID == land.LandData.OwnerID) 6326 if (m_host.OwnerID == land.LandData.OwnerID)
5903 { 6327 {
5904 World.TeleportClientHome(agentID, presence.ControllingClient); 6328 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6329 presence.TeleportWithMomentum(pos, null);
6330 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5905 } 6331 }
5906 } 6332 }
5907 } 6333 }
5908 ScriptSleep(5000); 6334 ScriptSleep(5000);
5909 } 6335 }
5910 6336
6337 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6338 {
6339 return ParseString2List(str, separators, in_spacers, false);
6340 }
6341
5911 public LSL_Integer llOverMyLand(string id) 6342 public LSL_Integer llOverMyLand(string id)
5912 { 6343 {
5913 m_host.AddScriptLPS(1); 6344 m_host.AddScriptLPS(1);
@@ -5966,20 +6397,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5966 return agentSize; 6397 return agentSize;
5967 } 6398 }
5968 6399
5969 public LSL_Integer llSameGroup(string agent) 6400 public LSL_Integer llSameGroup(string id)
5970 { 6401 {
5971 m_host.AddScriptLPS(1); 6402 m_host.AddScriptLPS(1);
5972 UUID agentId = new UUID(); 6403 UUID uuid = new UUID();
5973 if (!UUID.TryParse(agent, out agentId)) 6404 if (!UUID.TryParse(id, out uuid))
5974 return new LSL_Integer(0);
5975 ScenePresence presence = World.GetScenePresence(agentId);
5976 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5977 return new LSL_Integer(0); 6405 return new LSL_Integer(0);
5978 IClientAPI client = presence.ControllingClient; 6406
5979 if (m_host.GroupID == client.ActiveGroupId) 6407 // Check if it's a group key
6408 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5980 return new LSL_Integer(1); 6409 return new LSL_Integer(1);
5981 else 6410
6411 // We got passed a UUID.Zero
6412 if (uuid == UUID.Zero)
5982 return new LSL_Integer(0); 6413 return new LSL_Integer(0);
6414
6415 // Handle the case where id names an avatar
6416 ScenePresence presence = World.GetScenePresence(uuid);
6417 if (presence != null)
6418 {
6419 if (presence.IsChildAgent)
6420 return new LSL_Integer(0);
6421
6422 IClientAPI client = presence.ControllingClient;
6423 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6424 return new LSL_Integer(1);
6425
6426 return new LSL_Integer(0);
6427 }
6428
6429 // Handle object case
6430 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6431 if (part != null)
6432 {
6433 // This will handle both deed and non-deed and also the no
6434 // group case
6435 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6436 return new LSL_Integer(1);
6437
6438 return new LSL_Integer(0);
6439 }
6440
6441 return new LSL_Integer(0);
5983 } 6442 }
5984 6443
5985 public void llUnSit(string id) 6444 public void llUnSit(string id)
@@ -6104,7 +6563,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6104 return m_host.ParentGroup.AttachmentPoint; 6563 return m_host.ParentGroup.AttachmentPoint;
6105 } 6564 }
6106 6565
6107 public LSL_Integer llGetFreeMemory() 6566 public virtual LSL_Integer llGetFreeMemory()
6108 { 6567 {
6109 m_host.AddScriptLPS(1); 6568 m_host.AddScriptLPS(1);
6110 // Make scripts designed for LSO happy 6569 // Make scripts designed for LSO happy
@@ -6221,7 +6680,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6221 SetParticleSystem(m_host, rules); 6680 SetParticleSystem(m_host, rules);
6222 } 6681 }
6223 6682
6224 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6683 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6684 {
6225 6685
6226 6686
6227 if (rules.Length == 0) 6687 if (rules.Length == 0)
@@ -6536,6 +6996,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6536 6996
6537 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6997 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6538 { 6998 {
6999 // LSL quaternions can normalize to 0, normal Quaternions can't.
7000 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7001 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7002
6539 part.SitTargetPosition = offset; 7003 part.SitTargetPosition = offset;
6540 part.SitTargetOrientation = rot; 7004 part.SitTargetOrientation = rot;
6541 part.ParentGroup.HasGroupChanged = true; 7005 part.ParentGroup.HasGroupChanged = true;
@@ -6691,13 +7155,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6691 UUID av = new UUID(); 7155 UUID av = new UUID();
6692 if (!UUID.TryParse(avatar,out av)) 7156 if (!UUID.TryParse(avatar,out av))
6693 { 7157 {
6694 LSLError("First parameter to llDialog needs to be a key"); 7158 //LSLError("First parameter to llDialog needs to be a key");
6695 return; 7159 return;
6696 } 7160 }
6697 if (buttons.Length < 1) 7161 if (buttons.Length < 1)
6698 { 7162 {
6699 LSLError("No less than 1 button can be shown"); 7163 buttons.Add("OK");
6700 return;
6701 } 7164 }
6702 if (buttons.Length > 12) 7165 if (buttons.Length > 12)
6703 { 7166 {
@@ -6714,7 +7177,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6714 } 7177 }
6715 if (buttons.Data[i].ToString().Length > 24) 7178 if (buttons.Data[i].ToString().Length > 24)
6716 { 7179 {
6717 LSLError("button label cannot be longer than 24 characters"); 7180 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6718 return; 7181 return;
6719 } 7182 }
6720 buts[i] = buttons.Data[i].ToString(); 7183 buts[i] = buttons.Data[i].ToString();
@@ -6781,9 +7244,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6781 return; 7244 return;
6782 } 7245 }
6783 7246
6784 // the rest of the permission checks are done in RezScript, so check the pin there as well 7247 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6785 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7248 if (dest != null)
7249 {
7250 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7251 {
7252 // the rest of the permission checks are done in RezScript, so check the pin there as well
7253 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6786 7254
7255 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7256 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7257 }
7258 }
6787 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7259 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6788 ScriptSleep(3000); 7260 ScriptSleep(3000);
6789 } 7261 }
@@ -6846,19 +7318,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6846 public LSL_String llMD5String(string src, int nonce) 7318 public LSL_String llMD5String(string src, int nonce)
6847 { 7319 {
6848 m_host.AddScriptLPS(1); 7320 m_host.AddScriptLPS(1);
6849 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7321 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6850 } 7322 }
6851 7323
6852 public LSL_String llSHA1String(string src) 7324 public LSL_String llSHA1String(string src)
6853 { 7325 {
6854 m_host.AddScriptLPS(1); 7326 m_host.AddScriptLPS(1);
6855 return Util.SHA1Hash(src).ToLower(); 7327 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6856 } 7328 }
6857 7329
6858 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7330 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6859 { 7331 {
6860 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7332 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6861 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7333 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7334 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7335 return shapeBlock;
6862 7336
6863 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7337 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6864 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7338 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6963,6 +7437,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6963 // Prim type box, cylinder and prism. 7437 // Prim type box, cylinder and prism.
6964 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) 7438 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)
6965 { 7439 {
7440 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7441 return;
7442
6966 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7443 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6967 ObjectShapePacket.ObjectDataBlock shapeBlock; 7444 ObjectShapePacket.ObjectDataBlock shapeBlock;
6968 7445
@@ -7016,6 +7493,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7016 // Prim type sphere. 7493 // Prim type sphere.
7017 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7494 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7018 { 7495 {
7496 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7497 return;
7498
7019 ObjectShapePacket.ObjectDataBlock shapeBlock; 7499 ObjectShapePacket.ObjectDataBlock shapeBlock;
7020 7500
7021 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7501 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7057,6 +7537,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7057 // Prim type torus, tube and ring. 7537 // Prim type torus, tube and ring.
7058 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) 7538 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)
7059 { 7539 {
7540 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7541 return;
7542
7060 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7543 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7061 ObjectShapePacket.ObjectDataBlock shapeBlock; 7544 ObjectShapePacket.ObjectDataBlock shapeBlock;
7062 7545
@@ -7192,6 +7675,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7192 // Prim type sculpt. 7675 // Prim type sculpt.
7193 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7676 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7194 { 7677 {
7678 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7679 return;
7680
7195 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7681 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7196 UUID sculptId; 7682 UUID sculptId;
7197 7683
@@ -7216,7 +7702,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7216 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7702 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7217 { 7703 {
7218 // default 7704 // default
7219 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7705 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7220 } 7706 }
7221 7707
7222 part.Shape.SetSculptProperties((byte)type, sculptId); 7708 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7233,48 +7719,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7233 ScriptSleep(200); 7719 ScriptSleep(200);
7234 } 7720 }
7235 7721
7236 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7722 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7237 { 7723 {
7238 m_host.AddScriptLPS(1); 7724 m_host.AddScriptLPS(1);
7239 7725
7240 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7726 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7241 7727
7242 ScriptSleep(200); 7728 ScriptSleep(200);
7243 } 7729 }
7244 7730
7245 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7731 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7246 { 7732 {
7247 m_host.AddScriptLPS(1); 7733 List<object> parts = new List<object>();
7734 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7735 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7736 foreach (SceneObjectPart p in prims)
7737 parts.Add(p);
7738 foreach (ScenePresence p in avatars)
7739 parts.Add(p);
7248 7740
7249 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7741 LSL_List remaining = null;
7742 uint rulesParsed = 0;
7743
7744 if (parts.Count > 0)
7745 {
7746 foreach (object part in parts)
7747 {
7748 if (part is SceneObjectPart)
7749 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7750 else
7751 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7752 }
7753
7754 while ((object)remaining != null && remaining.Length > 2)
7755 {
7756 linknumber = remaining.GetLSLIntegerItem(0);
7757 rules = remaining.GetSublist(1, -1);
7758 parts.Clear();
7759 prims = GetLinkParts(linknumber);
7760 avatars = GetLinkAvatars(linknumber);
7761 foreach (SceneObjectPart p in prims)
7762 parts.Add(p);
7763 foreach (ScenePresence p in avatars)
7764 parts.Add(p);
7765
7766 remaining = null;
7767 foreach (object part in parts)
7768 {
7769 if (part is SceneObjectPart)
7770 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7771 else
7772 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7773 }
7774 }
7775 }
7250 } 7776 }
7251 7777
7252 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7778 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7779 float material_density, float material_friction,
7780 float material_restitution, float material_gravity_modifier)
7253 { 7781 {
7254 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7782 ExtraPhysicsData physdata = new ExtraPhysicsData();
7783 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7784 physdata.Density = part.Density;
7785 physdata.Friction = part.Friction;
7786 physdata.Bounce = part.Bounciness;
7787 physdata.GravitationModifier = part.GravityModifier;
7255 7788
7256 LSL_List remaining = null; 7789 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7257 uint rulesParsed = 0; 7790 physdata.Density = material_density;
7791 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7792 physdata.Friction = material_friction;
7793 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7794 physdata.Bounce = material_restitution;
7795 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7796 physdata.GravitationModifier = material_gravity_modifier;
7258 7797
7259 foreach (SceneObjectPart part in parts) 7798 part.UpdateExtraPhysics(physdata);
7260 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7799 }
7261 7800
7262 while (remaining != null && remaining.Length > 2) 7801 public void llSetPhysicsMaterial(int material_bits,
7263 { 7802 float material_gravity_modifier, float material_restitution,
7264 linknumber = remaining.GetLSLIntegerItem(0); 7803 float material_friction, float material_density)
7265 rules = remaining.GetSublist(1, -1); 7804 {
7266 parts = GetLinkParts(linknumber); 7805 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7806 }
7267 7807
7268 foreach (SceneObjectPart part in parts) 7808 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7269 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7809 {
7810 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7811 llSetLinkPrimitiveParamsFast(linknumber, rules);
7812 ScriptSleep(200);
7813 }
7814
7815 // vector up using libomv (c&p from sop )
7816 // vector up rotated by r
7817 private Vector3 Zrot(Quaternion r)
7818 {
7819 double x, y, z, m;
7820
7821 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7822 if (Math.Abs(1.0 - m) > 0.000001)
7823 {
7824 m = 1.0 / Math.Sqrt(m);
7825 r.X *= (float)m;
7826 r.Y *= (float)m;
7827 r.Z *= (float)m;
7828 r.W *= (float)m;
7270 } 7829 }
7830
7831 x = 2 * (r.X * r.Z + r.Y * r.W);
7832 y = 2 * (-r.X * r.W + r.Y * r.Z);
7833 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7834
7835 return new Vector3((float)x, (float)y, (float)z);
7271 } 7836 }
7272 7837
7273 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7838 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7274 { 7839 {
7840 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7841 return null;
7842
7275 int idx = 0; 7843 int idx = 0;
7276 int idxStart = 0; 7844 int idxStart = 0;
7277 7845
7846 SceneObjectGroup parentgrp = part.ParentGroup;
7847
7278 bool positionChanged = false; 7848 bool positionChanged = false;
7279 LSL_Vector currentPosition = GetPartLocalPos(part); 7849 LSL_Vector currentPosition = GetPartLocalPos(part);
7280 7850
@@ -7299,8 +7869,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7299 return null; 7869 return null;
7300 7870
7301 v=rules.GetVector3Item(idx++); 7871 v=rules.GetVector3Item(idx++);
7302 positionChanged = true;
7303 currentPosition = GetSetPosTarget(part, v, currentPosition); 7872 currentPosition = GetSetPosTarget(part, v, currentPosition);
7873 positionChanged = true;
7304 7874
7305 break; 7875 break;
7306 case (int)ScriptBaseClass.PRIM_SIZE: 7876 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7577,7 +8147,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7577 return null; 8147 return null;
7578 8148
7579 string ph = rules.Data[idx++].ToString(); 8149 string ph = rules.Data[idx++].ToString();
7580 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8150 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7581 8151
7582 break; 8152 break;
7583 8153
@@ -7595,12 +8165,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7595 part.ScriptSetPhysicsStatus(physics); 8165 part.ScriptSetPhysicsStatus(physics);
7596 break; 8166 break;
7597 8167
8168 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8169 if (remain < 1)
8170 return null;
8171
8172 int shape_type = rules.GetLSLIntegerItem(idx++);
8173
8174 ExtraPhysicsData physdata = new ExtraPhysicsData();
8175 physdata.Density = part.Density;
8176 physdata.Bounce = part.Bounciness;
8177 physdata.GravitationModifier = part.GravityModifier;
8178 physdata.PhysShapeType = (PhysShapeType)shape_type;
8179
8180 part.UpdateExtraPhysics(physdata);
8181
8182 break;
8183
8184 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8185 if (remain < 5)
8186 return null;
8187
8188 int material_bits = rules.GetLSLIntegerItem(idx++);
8189 float material_density = (float)rules.GetLSLFloatItem(idx++);
8190 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8191 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8192 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8193
8194 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8195
8196 break;
8197
7598 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8198 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7599 if (remain < 1) 8199 if (remain < 1)
7600 return null; 8200 return null;
7601 string temp = rules.Data[idx++].ToString(); 8201 string temp = rules.Data[idx++].ToString();
7602 8202
7603 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8203 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7604 8204
7605 break; 8205 break;
7606 8206
@@ -7674,7 +8274,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7674 if (part.ParentGroup.RootPart == part) 8274 if (part.ParentGroup.RootPart == part)
7675 { 8275 {
7676 SceneObjectGroup parent = part.ParentGroup; 8276 SceneObjectGroup parent = part.ParentGroup;
7677 parent.UpdateGroupPosition(currentPosition); 8277 Util.FireAndForget(delegate(object x) {
8278 parent.UpdateGroupPosition(currentPosition);
8279 });
7678 } 8280 }
7679 else 8281 else
7680 { 8282 {
@@ -7719,10 +8321,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7719 8321
7720 public LSL_String llXorBase64Strings(string str1, string str2) 8322 public LSL_String llXorBase64Strings(string str1, string str2)
7721 { 8323 {
7722 m_host.AddScriptLPS(1); 8324 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7723 Deprecated("llXorBase64Strings"); 8325
7724 ScriptSleep(300); 8326 ScriptSleep(300);
7725 return String.Empty; 8327 m_host.AddScriptLPS(1);
8328
8329 if (str1 == String.Empty)
8330 return String.Empty;
8331 if (str2 == String.Empty)
8332 return str1;
8333
8334 int len = str2.Length;
8335 if ((len % 4) != 0) // LL is EVIL!!!!
8336 {
8337 while (str2.EndsWith("="))
8338 str2 = str2.Substring(0, str2.Length - 1);
8339
8340 len = str2.Length;
8341 int mod = len % 4;
8342
8343 if (mod == 1)
8344 str2 = str2.Substring(0, str2.Length - 1);
8345 else if (mod == 2)
8346 str2 += "==";
8347 else if (mod == 3)
8348 str2 += "=";
8349 }
8350
8351 byte[] data1;
8352 byte[] data2;
8353 try
8354 {
8355 data1 = Convert.FromBase64String(str1);
8356 data2 = Convert.FromBase64String(str2);
8357 }
8358 catch (Exception)
8359 {
8360 return new LSL_String(String.Empty);
8361 }
8362
8363 // For cases where the decoded length of s2 is greater
8364 // than the decoded length of s1, simply perform a normal
8365 // decode and XOR
8366 //
8367 if (data2.Length >= data1.Length)
8368 {
8369 for (int pos = 0 ; pos < data1.Length ; pos++ )
8370 data1[pos] ^= data2[pos];
8371
8372 return Convert.ToBase64String(data1);
8373 }
8374
8375 // Remove padding
8376 while (str1.EndsWith("="))
8377 str1 = str1.Substring(0, str1.Length - 1);
8378 while (str2.EndsWith("="))
8379 str2 = str2.Substring(0, str2.Length - 1);
8380
8381 byte[] d1 = new byte[str1.Length];
8382 byte[] d2 = new byte[str2.Length];
8383
8384 for (int i = 0 ; i < str1.Length ; i++)
8385 {
8386 int idx = b64.IndexOf(str1.Substring(i, 1));
8387 if (idx == -1)
8388 idx = 0;
8389 d1[i] = (byte)idx;
8390 }
8391
8392 for (int i = 0 ; i < str2.Length ; i++)
8393 {
8394 int idx = b64.IndexOf(str2.Substring(i, 1));
8395 if (idx == -1)
8396 idx = 0;
8397 d2[i] = (byte)idx;
8398 }
8399
8400 string output = String.Empty;
8401
8402 for (int pos = 0 ; pos < d1.Length ; pos++)
8403 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8404
8405 while (output.Length % 3 > 0)
8406 output += "=";
8407
8408 return output;
7726 } 8409 }
7727 8410
7728 public void llRemoteDataSetRegion() 8411 public void llRemoteDataSetRegion()
@@ -7846,13 +8529,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7846 public LSL_Integer llGetNumberOfPrims() 8529 public LSL_Integer llGetNumberOfPrims()
7847 { 8530 {
7848 m_host.AddScriptLPS(1); 8531 m_host.AddScriptLPS(1);
7849 int avatarCount = 0; 8532 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7850 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8533
7851 {
7852 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7853 avatarCount++;
7854 });
7855
7856 return m_host.ParentGroup.PrimCount + avatarCount; 8534 return m_host.ParentGroup.PrimCount + avatarCount;
7857 } 8535 }
7858 8536
@@ -7868,55 +8546,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7868 m_host.AddScriptLPS(1); 8546 m_host.AddScriptLPS(1);
7869 UUID objID = UUID.Zero; 8547 UUID objID = UUID.Zero;
7870 LSL_List result = new LSL_List(); 8548 LSL_List result = new LSL_List();
8549
8550 // If the ID is not valid, return null result
7871 if (!UUID.TryParse(obj, out objID)) 8551 if (!UUID.TryParse(obj, out objID))
7872 { 8552 {
7873 result.Add(new LSL_Vector()); 8553 result.Add(new LSL_Vector());
7874 result.Add(new LSL_Vector()); 8554 result.Add(new LSL_Vector());
7875 return result; 8555 return result;
7876 } 8556 }
8557
8558 // Check if this is an attached prim. If so, replace
8559 // the UUID with the avatar UUID and report it's bounding box
8560 SceneObjectPart part = World.GetSceneObjectPart(objID);
8561 if (part != null && part.ParentGroup.IsAttachment)
8562 objID = part.ParentGroup.AttachedAvatar;
8563
8564 // Find out if this is an avatar ID. If so, return it's box
7877 ScenePresence presence = World.GetScenePresence(objID); 8565 ScenePresence presence = World.GetScenePresence(objID);
7878 if (presence != null) 8566 if (presence != null)
7879 { 8567 {
7880 if (presence.ParentID == 0) // not sat on an object 8568 // As per LSL Wiki, there is no difference between sitting
8569 // and standing avatar since server 1.36
8570 LSL_Vector lower;
8571 LSL_Vector upper;
8572 if (presence.Animator.Animations.DefaultAnimation.AnimID
8573 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7881 { 8574 {
7882 LSL_Vector lower; 8575 // This is for ground sitting avatars
7883 LSL_Vector upper; 8576 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7884 if (presence.Animator.Animations.DefaultAnimation.AnimID 8577 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7885 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8578 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7886 {
7887 // This is for ground sitting avatars
7888 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7889 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7890 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7891 }
7892 else
7893 {
7894 // This is for standing/flying avatars
7895 float height = presence.Appearance.AvatarHeight / 2.0f;
7896 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7897 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7898 }
7899 result.Add(lower);
7900 result.Add(upper);
7901 return result;
7902 } 8579 }
7903 else 8580 else
7904 { 8581 {
7905 // sitting on an object so we need the bounding box of that 8582 // This is for standing/flying avatars
7906 // which should include the avatar so set the UUID to the 8583 float height = presence.Appearance.AvatarHeight / 2.0f;
7907 // UUID of the object the avatar is sat on and allow it to fall through 8584 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7908 // to processing an object 8585 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7909 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7910 objID = p.UUID;
7911 } 8586 }
8587
8588 // Adjust to the documented error offsets (see LSL Wiki)
8589 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8590 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8591
8592 if (lower.x > upper.x)
8593 lower.x = upper.x;
8594 if (lower.y > upper.y)
8595 lower.y = upper.y;
8596 if (lower.z > upper.z)
8597 lower.z = upper.z;
8598
8599 result.Add(lower);
8600 result.Add(upper);
8601 return result;
7912 } 8602 }
7913 SceneObjectPart part = World.GetSceneObjectPart(objID); 8603
8604 part = World.GetSceneObjectPart(objID);
7914 // Currently only works for single prims without a sitting avatar 8605 // Currently only works for single prims without a sitting avatar
7915 if (part != null) 8606 if (part != null)
7916 { 8607 {
7917 Vector3 halfSize = part.Scale / 2.0f; 8608 float minX;
7918 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8609 float maxX;
7919 LSL_Vector upper = new LSL_Vector(halfSize); 8610 float minY;
8611 float maxY;
8612 float minZ;
8613 float maxZ;
8614
8615 // This BBox is in sim coordinates, with the offset being
8616 // a contained point.
8617 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8618 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8619
8620 minX -= offsets[0].X;
8621 maxX -= offsets[0].X;
8622 minY -= offsets[0].Y;
8623 maxY -= offsets[0].Y;
8624 minZ -= offsets[0].Z;
8625 maxZ -= offsets[0].Z;
8626
8627 LSL_Vector lower;
8628 LSL_Vector upper;
8629
8630 // Adjust to the documented error offsets (see LSL Wiki)
8631 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8632 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8633
8634 if (lower.x > upper.x)
8635 lower.x = upper.x;
8636 if (lower.y > upper.y)
8637 lower.y = upper.y;
8638 if (lower.z > upper.z)
8639 lower.z = upper.z;
8640
7920 result.Add(lower); 8641 result.Add(lower);
7921 result.Add(upper); 8642 result.Add(upper);
7922 return result; 8643 return result;
@@ -7930,7 +8651,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7930 8651
7931 public LSL_Vector llGetGeometricCenter() 8652 public LSL_Vector llGetGeometricCenter()
7932 { 8653 {
7933 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8654 Vector3 tmp = m_host.GetGeometricCenter();
8655 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7934 } 8656 }
7935 8657
7936 public LSL_List llGetPrimitiveParams(LSL_List rules) 8658 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7958,24 +8680,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7958 { 8680 {
7959 m_host.AddScriptLPS(1); 8681 m_host.AddScriptLPS(1);
7960 8682
7961 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8683 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8684 // keep other options as before
7962 8685
8686 List<SceneObjectPart> parts;
8687 List<ScenePresence> avatars;
8688
7963 LSL_List res = new LSL_List(); 8689 LSL_List res = new LSL_List();
7964 LSL_List remaining = null; 8690 LSL_List remaining = null;
7965 8691
7966 foreach (SceneObjectPart part in parts) 8692 while (rules.Length > 0)
7967 { 8693 {
7968 remaining = GetPrimParams(part, rules, ref res);
7969 }
7970
7971 while (remaining != null && remaining.Length > 2)
7972 {
7973 linknumber = remaining.GetLSLIntegerItem(0);
7974 rules = remaining.GetSublist(1, -1);
7975 parts = GetLinkParts(linknumber); 8694 parts = GetLinkParts(linknumber);
8695 avatars = GetLinkAvatars(linknumber);
7976 8696
8697 remaining = null;
7977 foreach (SceneObjectPart part in parts) 8698 foreach (SceneObjectPart part in parts)
8699 {
7978 remaining = GetPrimParams(part, rules, ref res); 8700 remaining = GetPrimParams(part, rules, ref res);
8701 }
8702 foreach (ScenePresence avatar in avatars)
8703 {
8704 remaining = GetPrimParams(avatar, rules, ref res);
8705 }
8706
8707 if (remaining != null && remaining.Length > 0)
8708 {
8709 linknumber = remaining.GetLSLIntegerItem(0);
8710 rules = remaining.GetSublist(1, -1);
8711 }
7979 } 8712 }
7980 8713
7981 return res; 8714 return res;
@@ -8020,13 +8753,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8020 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8753 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8021 part.AbsolutePosition.Y, 8754 part.AbsolutePosition.Y,
8022 part.AbsolutePosition.Z); 8755 part.AbsolutePosition.Z);
8023 // For some reason, the part.AbsolutePosition.* values do not change if the
8024 // linkset is rotated; they always reflect the child prim's world position
8025 // as though the linkset is unrotated. This is incompatible behavior with SL's
8026 // implementation, so will break scripts imported from there (not to mention it
8027 // makes it more difficult to determine a child prim's actual inworld position).
8028 if (part.ParentID != 0)
8029 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8030 res.Add(v); 8756 res.Add(v);
8031 break; 8757 break;
8032 8758
@@ -8198,30 +8924,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8198 if (remain < 1) 8924 if (remain < 1)
8199 return null; 8925 return null;
8200 8926
8201 face=(int)rules.GetLSLIntegerItem(idx++); 8927 face = (int)rules.GetLSLIntegerItem(idx++);
8202 8928
8203 tex = part.Shape.Textures; 8929 tex = part.Shape.Textures;
8930 int shiny;
8204 if (face == ScriptBaseClass.ALL_SIDES) 8931 if (face == ScriptBaseClass.ALL_SIDES)
8205 { 8932 {
8206 for (face = 0; face < GetNumberOfSides(part); face++) 8933 for (face = 0; face < GetNumberOfSides(part); face++)
8207 { 8934 {
8208 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8935 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8209 // Convert Shininess to PRIM_SHINY_* 8936 if (shinyness == Shininess.High)
8210 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8937 {
8211 // PRIM_BUMP_* 8938 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8212 res.Add(new LSL_Integer((int)texface.Bump)); 8939 }
8940 else if (shinyness == Shininess.Medium)
8941 {
8942 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8943 }
8944 else if (shinyness == Shininess.Low)
8945 {
8946 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8947 }
8948 else
8949 {
8950 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8951 }
8952 res.Add(new LSL_Integer(shiny));
8953 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8213 } 8954 }
8214 } 8955 }
8215 else 8956 else
8216 { 8957 {
8217 if (face >= 0 && face < GetNumberOfSides(part)) 8958 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8959 if (shinyness == Shininess.High)
8218 { 8960 {
8219 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8961 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8220 // Convert Shininess to PRIM_SHINY_* 8962 }
8221 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8963 else if (shinyness == Shininess.Medium)
8222 // PRIM_BUMP_* 8964 {
8223 res.Add(new LSL_Integer((int)texface.Bump)); 8965 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8966 }
8967 else if (shinyness == Shininess.Low)
8968 {
8969 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8224 } 8970 }
8971 else
8972 {
8973 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8974 }
8975 res.Add(new LSL_Integer(shiny));
8976 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8225 } 8977 }
8226 break; 8978 break;
8227 8979
@@ -8229,24 +8981,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8229 if (remain < 1) 8981 if (remain < 1)
8230 return null; 8982 return null;
8231 8983
8232 face=(int)rules.GetLSLIntegerItem(idx++); 8984 face = (int)rules.GetLSLIntegerItem(idx++);
8233 8985
8234 tex = part.Shape.Textures; 8986 tex = part.Shape.Textures;
8987 int fullbright;
8235 if (face == ScriptBaseClass.ALL_SIDES) 8988 if (face == ScriptBaseClass.ALL_SIDES)
8236 { 8989 {
8237 for (face = 0; face < GetNumberOfSides(part); face++) 8990 for (face = 0; face < GetNumberOfSides(part); face++)
8238 { 8991 {
8239 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8992 if (tex.GetFace((uint)face).Fullbright == true)
8240 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8993 {
8994 fullbright = ScriptBaseClass.TRUE;
8995 }
8996 else
8997 {
8998 fullbright = ScriptBaseClass.FALSE;
8999 }
9000 res.Add(new LSL_Integer(fullbright));
8241 } 9001 }
8242 } 9002 }
8243 else 9003 else
8244 { 9004 {
8245 if (face >= 0 && face < GetNumberOfSides(part)) 9005 if (tex.GetFace((uint)face).Fullbright == true)
8246 { 9006 {
8247 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9007 fullbright = ScriptBaseClass.TRUE;
8248 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8249 } 9008 }
9009 else
9010 {
9011 fullbright = ScriptBaseClass.FALSE;
9012 }
9013 res.Add(new LSL_Integer(fullbright));
8250 } 9014 }
8251 break; 9015 break;
8252 9016
@@ -8268,27 +9032,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8268 break; 9032 break;
8269 9033
8270 case (int)ScriptBaseClass.PRIM_TEXGEN: 9034 case (int)ScriptBaseClass.PRIM_TEXGEN:
9035 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8271 if (remain < 1) 9036 if (remain < 1)
8272 return null; 9037 return null;
8273 9038
8274 face=(int)rules.GetLSLIntegerItem(idx++); 9039 face = (int)rules.GetLSLIntegerItem(idx++);
8275 9040
8276 tex = part.Shape.Textures; 9041 tex = part.Shape.Textures;
8277 if (face == ScriptBaseClass.ALL_SIDES) 9042 if (face == ScriptBaseClass.ALL_SIDES)
8278 { 9043 {
8279 for (face = 0; face < GetNumberOfSides(part); face++) 9044 for (face = 0; face < GetNumberOfSides(part); face++)
8280 { 9045 {
8281 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9046 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8282 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9047 {
8283 res.Add(new LSL_Integer((uint)texgen >> 1)); 9048 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9049 }
9050 else
9051 {
9052 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9053 }
8284 } 9054 }
8285 } 9055 }
8286 else 9056 else
8287 { 9057 {
8288 if (face >= 0 && face < GetNumberOfSides(part)) 9058 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9059 {
9060 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9061 }
9062 else
8289 { 9063 {
8290 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9064 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8291 res.Add(new LSL_Integer((uint)texgen >> 1));
8292 } 9065 }
8293 } 9066 }
8294 break; 9067 break;
@@ -8312,24 +9085,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8312 if (remain < 1) 9085 if (remain < 1)
8313 return null; 9086 return null;
8314 9087
8315 face=(int)rules.GetLSLIntegerItem(idx++); 9088 face = (int)rules.GetLSLIntegerItem(idx++);
8316 9089
8317 tex = part.Shape.Textures; 9090 tex = part.Shape.Textures;
9091 float primglow;
8318 if (face == ScriptBaseClass.ALL_SIDES) 9092 if (face == ScriptBaseClass.ALL_SIDES)
8319 { 9093 {
8320 for (face = 0; face < GetNumberOfSides(part); face++) 9094 for (face = 0; face < GetNumberOfSides(part); face++)
8321 { 9095 {
8322 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9096 primglow = tex.GetFace((uint)face).Glow;
8323 res.Add(new LSL_Float(texface.Glow)); 9097 res.Add(new LSL_Float(primglow));
8324 } 9098 }
8325 } 9099 }
8326 else 9100 else
8327 { 9101 {
8328 if (face >= 0 && face < GetNumberOfSides(part)) 9102 primglow = tex.GetFace((uint)face).Glow;
8329 { 9103 res.Add(new LSL_Float(primglow));
8330 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8331 res.Add(new LSL_Float(texface.Glow));
8332 }
8333 } 9104 }
8334 break; 9105 break;
8335 9106
@@ -8341,15 +9112,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8341 textColor.B)); 9112 textColor.B));
8342 res.Add(new LSL_Float(textColor.A)); 9113 res.Add(new LSL_Float(textColor.A));
8343 break; 9114 break;
9115
8344 case (int)ScriptBaseClass.PRIM_NAME: 9116 case (int)ScriptBaseClass.PRIM_NAME:
8345 res.Add(new LSL_String(part.Name)); 9117 res.Add(new LSL_String(part.Name));
8346 break; 9118 break;
9119
8347 case (int)ScriptBaseClass.PRIM_DESC: 9120 case (int)ScriptBaseClass.PRIM_DESC:
8348 res.Add(new LSL_String(part.Description)); 9121 res.Add(new LSL_String(part.Description));
8349 break; 9122 break;
9123
8350 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9124 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8351 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9125 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8352 break; 9126 break;
9127
8353 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9128 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8354 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9129 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8355 break; 9130 break;
@@ -8960,8 +9735,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8960 // The function returns an ordered list 9735 // The function returns an ordered list
8961 // representing the tokens found in the supplied 9736 // representing the tokens found in the supplied
8962 // sources string. If two successive tokenizers 9737 // sources string. If two successive tokenizers
8963 // are encountered, then a NULL entry is added 9738 // are encountered, then a null-string entry is
8964 // to the list. 9739 // added to the list.
8965 // 9740 //
8966 // It is a precondition that the source and 9741 // It is a precondition that the source and
8967 // toekizer lisst are non-null. If they are null, 9742 // toekizer lisst are non-null. If they are null,
@@ -8969,7 +9744,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8969 // while their lengths are being determined. 9744 // while their lengths are being determined.
8970 // 9745 //
8971 // A small amount of working memoryis required 9746 // A small amount of working memoryis required
8972 // of approximately 8*#tokenizers. 9747 // of approximately 8*#tokenizers + 8*srcstrlen.
8973 // 9748 //
8974 // There are many ways in which this function 9749 // There are many ways in which this function
8975 // can be implemented, this implementation is 9750 // can be implemented, this implementation is
@@ -8985,155 +9760,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8985 // and eliminates redundant tokenizers as soon 9760 // and eliminates redundant tokenizers as soon
8986 // as is possible. 9761 // as is possible.
8987 // 9762 //
8988 // The implementation tries to avoid any copying 9763 // The implementation tries to minimize temporary
8989 // of arrays or other objects. 9764 // garbage generation.
8990 // </remarks> 9765 // </remarks>
8991 9766
8992 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9767 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8993 { 9768 {
8994 int beginning = 0; 9769 return ParseString2List(src, separators, spacers, true);
8995 int srclen = src.Length; 9770 }
8996 int seplen = separators.Length;
8997 object[] separray = separators.Data;
8998 int spclen = spacers.Length;
8999 object[] spcarray = spacers.Data;
9000 int mlen = seplen+spclen;
9001
9002 int[] offset = new int[mlen+1];
9003 bool[] active = new bool[mlen];
9004
9005 int best;
9006 int j;
9007
9008 // Initial capacity reduces resize cost
9009 9771
9010 LSL_List tokens = new LSL_List(); 9772 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9773 {
9774 int srclen = src.Length;
9775 int seplen = separators.Length;
9776 object[] separray = separators.Data;
9777 int spclen = spacers.Length;
9778 object[] spcarray = spacers.Data;
9779 int dellen = 0;
9780 string[] delarray = new string[seplen+spclen];
9011 9781
9012 // All entries are initially valid 9782 int outlen = 0;
9783 string[] outarray = new string[srclen*2+1];
9013 9784
9014 for (int i = 0; i < mlen; i++) 9785 int i, j;
9015 active[i] = true; 9786 string d;
9016 9787
9017 offset[mlen] = srclen; 9788 m_host.AddScriptLPS(1);
9018 9789
9019 while (beginning < srclen) 9790 /*
9791 * Convert separator and spacer lists to C# strings.
9792 * Also filter out null strings so we don't hang.
9793 */
9794 for (i = 0; i < seplen; i ++)
9020 { 9795 {
9796 d = separray[i].ToString();
9797 if (d.Length > 0)
9798 {
9799 delarray[dellen++] = d;
9800 }
9801 }
9802 seplen = dellen;
9021 9803
9022 best = mlen; // as bad as it gets 9804 for (i = 0; i < spclen; i ++)
9805 {
9806 d = spcarray[i].ToString();
9807 if (d.Length > 0)
9808 {
9809 delarray[dellen++] = d;
9810 }
9811 }
9023 9812
9024 // Scan for separators 9813 /*
9814 * Scan through source string from beginning to end.
9815 */
9816 for (i = 0;;)
9817 {
9025 9818
9026 for (j = 0; j < seplen; j++) 9819 /*
9820 * Find earliest delimeter in src starting at i (if any).
9821 */
9822 int earliestDel = -1;
9823 int earliestSrc = srclen;
9824 string earliestStr = null;
9825 for (j = 0; j < dellen; j ++)
9027 { 9826 {
9028 if (separray[j].ToString() == String.Empty) 9827 d = delarray[j];
9029 active[j] = false; 9828 if (d != null)
9030
9031 if (active[j])
9032 { 9829 {
9033 // scan all of the markers 9830 int index = src.IndexOf(d, i);
9034 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9831 if (index < 0)
9035 { 9832 {
9036 // not present at all 9833 delarray[j] = null; // delim nowhere in src, don't check it anymore
9037 active[j] = false;
9038 } 9834 }
9039 else 9835 else if (index < earliestSrc)
9040 { 9836 {
9041 // present and correct 9837 earliestSrc = index; // where delimeter starts in source string
9042 if (offset[j] < offset[best]) 9838 earliestDel = j; // where delimeter is in delarray[]
9043 { 9839 earliestStr = d; // the delimeter string from delarray[]
9044 // closest so far 9840 if (index == i) break; // can't do any better than found at beg of string
9045 best = j;
9046 if (offset[best] == beginning)
9047 break;
9048 }
9049 } 9841 }
9050 } 9842 }
9051 } 9843 }
9052 9844
9053 // Scan for spacers 9845 /*
9054 9846 * Output source string starting at i through start of earliest delimeter.
9055 if (offset[best] != beginning) 9847 */
9848 if (keepNulls || (earliestSrc > i))
9056 { 9849 {
9057 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9850 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9058 {
9059 if (spcarray[j-seplen].ToString() == String.Empty)
9060 active[j] = false;
9061
9062 if (active[j])
9063 {
9064 // scan all of the markers
9065 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9066 {
9067 // not present at all
9068 active[j] = false;
9069 }
9070 else
9071 {
9072 // present and correct
9073 if (offset[j] < offset[best])
9074 {
9075 // closest so far
9076 best = j;
9077 }
9078 }
9079 }
9080 }
9081 } 9851 }
9082 9852
9083 // This is the normal exit from the scanning loop 9853 /*
9854 * If no delimeter found at or after i, we're done scanning.
9855 */
9856 if (earliestDel < 0) break;
9084 9857
9085 if (best == mlen) 9858 /*
9859 * If delimeter was a spacer, output the spacer.
9860 */
9861 if (earliestDel >= seplen)
9086 { 9862 {
9087 // no markers were found on this pass 9863 outarray[outlen++] = earliestStr;
9088 // so we're pretty much done
9089 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9090 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9091 break;
9092 } 9864 }
9093 9865
9094 // Otherwise we just add the newly delimited token 9866 /*
9095 // and recalculate where the search should continue. 9867 * Look at rest of src string following delimeter.
9096 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9868 */
9097 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9869 i = earliestSrc + earliestStr.Length;
9098
9099 if (best < seplen)
9100 {
9101 beginning = offset[best] + (separray[best].ToString()).Length;
9102 }
9103 else
9104 {
9105 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9106 string str = spcarray[best - seplen].ToString();
9107 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9108 tokens.Add(new LSL_String(str));
9109 }
9110 } 9870 }
9111 9871
9112 // This an awkward an not very intuitive boundary case. If the 9872 /*
9113 // last substring is a tokenizer, then there is an implied trailing 9873 * Make up an exact-sized output array suitable for an LSL_List object.
9114 // null list entry. Hopefully the single comparison will not be too 9874 */
9115 // arduous. Alternatively the 'break' could be replced with a return 9875 object[] outlist = new object[outlen];
9116 // but that's shabby programming. 9876 for (i = 0; i < outlen; i ++)
9117
9118 if ((beginning == srclen) && (keepNulls))
9119 { 9877 {
9120 if (srclen != 0) 9878 outlist[i] = new LSL_String(outarray[i]);
9121 tokens.Add(new LSL_String(""));
9122 } 9879 }
9123 9880 return new LSL_List(outlist);
9124 return tokens;
9125 }
9126
9127 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9128 {
9129 m_host.AddScriptLPS(1);
9130 return this.ParseString(src, separators, spacers, false);
9131 }
9132
9133 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9134 {
9135 m_host.AddScriptLPS(1);
9136 return this.ParseString(src, separators, spacers, true);
9137 } 9881 }
9138 9882
9139 public LSL_Integer llGetObjectPermMask(int mask) 9883 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9228,6 +9972,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9228 case 4: 9972 case 4:
9229 return (int)item.NextPermissions; 9973 return (int)item.NextPermissions;
9230 } 9974 }
9975 m_host.TaskInventory.LockItemsForRead(false);
9231 9976
9232 return -1; 9977 return -1;
9233 } 9978 }
@@ -9416,31 +10161,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9416 UUID key = new UUID(); 10161 UUID key = new UUID();
9417 if (UUID.TryParse(id, out key)) 10162 if (UUID.TryParse(id, out key))
9418 { 10163 {
9419 try 10164 // return total object mass
9420 { 10165 SceneObjectPart part = World.GetSceneObjectPart(key);
9421 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10166 if (part != null)
9422 if (obj != null) 10167 return part.ParentGroup.GetMass();
9423 return (double)obj.GetMass(); 10168
9424 // the object is null so the key is for an avatar 10169 // the object is null so the key is for an avatar
9425 ScenePresence avatar = World.GetScenePresence(key); 10170 ScenePresence avatar = World.GetScenePresence(key);
9426 if (avatar != null) 10171 if (avatar != null)
9427 if (avatar.IsChildAgent)
9428 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9429 // child agents have a mass of 1.0
9430 return 1;
9431 else
9432 return (double)avatar.GetMass();
9433 }
9434 catch (KeyNotFoundException)
9435 { 10172 {
9436 return 0; // The Object/Agent not in the region so just return zero 10173 if (avatar.IsChildAgent)
10174 {
10175 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10176 // child agents have a mass of 1.0
10177 return 1;
10178 }
10179 else
10180 {
10181 return (double)avatar.GetMass();
10182 }
9437 } 10183 }
9438 } 10184 }
9439 return 0; 10185 return 0;
9440 } 10186 }
9441 10187
9442 /// <summary> 10188 /// <summary>
9443 /// illListReplaceList removes the sub-list defined by the inclusive indices 10189 /// llListReplaceList removes the sub-list defined by the inclusive indices
9444 /// start and end and inserts the src list in its place. The inclusive 10190 /// start and end and inserts the src list in its place. The inclusive
9445 /// nature of the indices means that at least one element must be deleted 10191 /// nature of the indices means that at least one element must be deleted
9446 /// if the indices are within the bounds of the existing list. I.e. 2,2 10192 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9497,16 +10243,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9497 // based upon end. Note that if end exceeds the upper 10243 // based upon end. Note that if end exceeds the upper
9498 // bound in this case, the entire destination list 10244 // bound in this case, the entire destination list
9499 // is removed. 10245 // is removed.
9500 else 10246 else if (start == 0)
9501 { 10247 {
9502 if (end + 1 < dest.Length) 10248 if (end + 1 < dest.Length)
9503 {
9504 return src + dest.GetSublist(end + 1, -1); 10249 return src + dest.GetSublist(end + 1, -1);
9505 }
9506 else 10250 else
9507 {
9508 return src; 10251 return src;
9509 } 10252 }
10253 else // Start < 0
10254 {
10255 if (end + 1 < dest.Length)
10256 return dest.GetSublist(end + 1, -1);
10257 else
10258 return new LSL_List();
9510 } 10259 }
9511 } 10260 }
9512 // Finally, if start > end, we strip away a prefix and 10261 // Finally, if start > end, we strip away a prefix and
@@ -9557,17 +10306,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9557 int width = 0; 10306 int width = 0;
9558 int height = 0; 10307 int height = 0;
9559 10308
9560 ParcelMediaCommandEnum? commandToSend = null; 10309 uint commandToSend = 0;
9561 float time = 0.0f; // default is from start 10310 float time = 0.0f; // default is from start
9562 10311
9563 ScenePresence presence = null; 10312 ScenePresence presence = null;
9564 10313
9565 for (int i = 0; i < commandList.Data.Length; i++) 10314 for (int i = 0; i < commandList.Data.Length; i++)
9566 { 10315 {
9567 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10316 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9568 switch (command) 10317 switch (command)
9569 { 10318 {
9570 case ParcelMediaCommandEnum.Agent: 10319 case (uint)ParcelMediaCommandEnum.Agent:
9571 // we send only to one agent 10320 // we send only to one agent
9572 if ((i + 1) < commandList.Length) 10321 if ((i + 1) < commandList.Length)
9573 { 10322 {
@@ -9584,25 +10333,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9584 } 10333 }
9585 break; 10334 break;
9586 10335
9587 case ParcelMediaCommandEnum.Loop: 10336 case (uint)ParcelMediaCommandEnum.Loop:
9588 loop = 1; 10337 loop = 1;
9589 commandToSend = command; 10338 commandToSend = command;
9590 update = true; //need to send the media update packet to set looping 10339 update = true; //need to send the media update packet to set looping
9591 break; 10340 break;
9592 10341
9593 case ParcelMediaCommandEnum.Play: 10342 case (uint)ParcelMediaCommandEnum.Play:
9594 loop = 0; 10343 loop = 0;
9595 commandToSend = command; 10344 commandToSend = command;
9596 update = true; //need to send the media update packet to make sure it doesn't loop 10345 update = true; //need to send the media update packet to make sure it doesn't loop
9597 break; 10346 break;
9598 10347
9599 case ParcelMediaCommandEnum.Pause: 10348 case (uint)ParcelMediaCommandEnum.Pause:
9600 case ParcelMediaCommandEnum.Stop: 10349 case (uint)ParcelMediaCommandEnum.Stop:
9601 case ParcelMediaCommandEnum.Unload: 10350 case (uint)ParcelMediaCommandEnum.Unload:
9602 commandToSend = command; 10351 commandToSend = command;
9603 break; 10352 break;
9604 10353
9605 case ParcelMediaCommandEnum.Url: 10354 case (uint)ParcelMediaCommandEnum.Url:
9606 if ((i + 1) < commandList.Length) 10355 if ((i + 1) < commandList.Length)
9607 { 10356 {
9608 if (commandList.Data[i + 1] is LSL_String) 10357 if (commandList.Data[i + 1] is LSL_String)
@@ -9615,7 +10364,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9615 } 10364 }
9616 break; 10365 break;
9617 10366
9618 case ParcelMediaCommandEnum.Texture: 10367 case (uint)ParcelMediaCommandEnum.Texture:
9619 if ((i + 1) < commandList.Length) 10368 if ((i + 1) < commandList.Length)
9620 { 10369 {
9621 if (commandList.Data[i + 1] is LSL_String) 10370 if (commandList.Data[i + 1] is LSL_String)
@@ -9628,7 +10377,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9628 } 10377 }
9629 break; 10378 break;
9630 10379
9631 case ParcelMediaCommandEnum.Time: 10380 case (uint)ParcelMediaCommandEnum.Time:
9632 if ((i + 1) < commandList.Length) 10381 if ((i + 1) < commandList.Length)
9633 { 10382 {
9634 if (commandList.Data[i + 1] is LSL_Float) 10383 if (commandList.Data[i + 1] is LSL_Float)
@@ -9640,7 +10389,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9640 } 10389 }
9641 break; 10390 break;
9642 10391
9643 case ParcelMediaCommandEnum.AutoAlign: 10392 case (uint)ParcelMediaCommandEnum.AutoAlign:
9644 if ((i + 1) < commandList.Length) 10393 if ((i + 1) < commandList.Length)
9645 { 10394 {
9646 if (commandList.Data[i + 1] is LSL_Integer) 10395 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9654,7 +10403,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9654 } 10403 }
9655 break; 10404 break;
9656 10405
9657 case ParcelMediaCommandEnum.Type: 10406 case (uint)ParcelMediaCommandEnum.Type:
9658 if ((i + 1) < commandList.Length) 10407 if ((i + 1) < commandList.Length)
9659 { 10408 {
9660 if (commandList.Data[i + 1] is LSL_String) 10409 if (commandList.Data[i + 1] is LSL_String)
@@ -9667,7 +10416,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9667 } 10416 }
9668 break; 10417 break;
9669 10418
9670 case ParcelMediaCommandEnum.Desc: 10419 case (uint)ParcelMediaCommandEnum.Desc:
9671 if ((i + 1) < commandList.Length) 10420 if ((i + 1) < commandList.Length)
9672 { 10421 {
9673 if (commandList.Data[i + 1] is LSL_String) 10422 if (commandList.Data[i + 1] is LSL_String)
@@ -9680,7 +10429,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9680 } 10429 }
9681 break; 10430 break;
9682 10431
9683 case ParcelMediaCommandEnum.Size: 10432 case (uint)ParcelMediaCommandEnum.Size:
9684 if ((i + 2) < commandList.Length) 10433 if ((i + 2) < commandList.Length)
9685 { 10434 {
9686 if (commandList.Data[i + 1] is LSL_Integer) 10435 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9750,7 +10499,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9750 } 10499 }
9751 } 10500 }
9752 10501
9753 if (commandToSend != null) 10502 if (commandToSend != 0)
9754 { 10503 {
9755 // the commandList contained a start/stop/... command, too 10504 // the commandList contained a start/stop/... command, too
9756 if (presence == null) 10505 if (presence == null)
@@ -9787,7 +10536,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9787 10536
9788 if (aList.Data[i] != null) 10537 if (aList.Data[i] != null)
9789 { 10538 {
9790 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10539 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9791 { 10540 {
9792 case ParcelMediaCommandEnum.Url: 10541 case ParcelMediaCommandEnum.Url:
9793 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10542 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9844,15 +10593,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9844 10593
9845 if (quick_pay_buttons.Data.Length < 4) 10594 if (quick_pay_buttons.Data.Length < 4)
9846 { 10595 {
9847 LSLError("List must have at least 4 elements"); 10596 int x;
9848 return; 10597 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10598 {
10599 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10600 }
9849 } 10601 }
9850 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10602 int[] nPrice = new int[5];
9851 10603 nPrice[0] = price;
9852 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10604 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9853 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10605 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9854 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10606 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9855 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10607 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10608 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9856 m_host.ParentGroup.HasGroupChanged = true; 10609 m_host.ParentGroup.HasGroupChanged = true;
9857 } 10610 }
9858 10611
@@ -9869,7 +10622,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9869 return new LSL_Vector(); 10622 return new LSL_Vector();
9870 } 10623 }
9871 10624
9872 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10625// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10626 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9873 if (presence != null) 10627 if (presence != null)
9874 { 10628 {
9875 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10629 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9891,7 +10645,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9891 return new LSL_Rotation(); 10645 return new LSL_Rotation();
9892 } 10646 }
9893 10647
9894 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10648// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10649 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9895 if (presence != null) 10650 if (presence != null)
9896 { 10651 {
9897 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10652 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9951,14 +10706,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9951 { 10706 {
9952 m_host.AddScriptLPS(1); 10707 m_host.AddScriptLPS(1);
9953 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10708 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9954 if (detectedParams == null) return; // only works on the first detected avatar 10709 if (detectedParams == null)
9955 10710 {
10711 if (m_host.ParentGroup.IsAttachment == true)
10712 {
10713 detectedParams = new DetectParams();
10714 detectedParams.Key = m_host.OwnerID;
10715 }
10716 else
10717 {
10718 return;
10719 }
10720 }
10721
9956 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10722 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9957 if (avatar != null) 10723 if (avatar != null)
9958 { 10724 {
9959 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10725 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9960 simname, pos, lookAt); 10726 simname, pos, lookAt);
9961 } 10727 }
10728
9962 ScriptSleep(1000); 10729 ScriptSleep(1000);
9963 } 10730 }
9964 10731
@@ -10082,12 +10849,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10082 10849
10083 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10850 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10084 object[] data = rules.Data; 10851 object[] data = rules.Data;
10085 for (int i = 0; i < data.Length; ++i) { 10852 for (int i = 0; i < data.Length; ++i)
10853 {
10086 int type = Convert.ToInt32(data[i++].ToString()); 10854 int type = Convert.ToInt32(data[i++].ToString());
10087 if (i >= data.Length) break; // odd number of entries => ignore the last 10855 if (i >= data.Length) break; // odd number of entries => ignore the last
10088 10856
10089 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10857 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10090 switch (type) { 10858 switch (type)
10859 {
10091 case ScriptBaseClass.CAMERA_FOCUS: 10860 case ScriptBaseClass.CAMERA_FOCUS:
10092 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10861 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10093 case ScriptBaseClass.CAMERA_POSITION: 10862 case ScriptBaseClass.CAMERA_POSITION:
@@ -10192,19 +10961,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10192 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10961 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10193 { 10962 {
10194 m_host.AddScriptLPS(1); 10963 m_host.AddScriptLPS(1);
10195 string ret = String.Empty; 10964
10196 string src1 = llBase64ToString(str1); 10965 if (str1 == String.Empty)
10197 string src2 = llBase64ToString(str2); 10966 return String.Empty;
10198 int c = 0; 10967 if (str2 == String.Empty)
10199 for (int i = 0; i < src1.Length; i++) 10968 return str1;
10969
10970 int len = str2.Length;
10971 if ((len % 4) != 0) // LL is EVIL!!!!
10200 { 10972 {
10201 ret += (char) (src1[i] ^ src2[c]); 10973 while (str2.EndsWith("="))
10974 str2 = str2.Substring(0, str2.Length - 1);
10202 10975
10203 c++; 10976 len = str2.Length;
10204 if (c >= src2.Length) 10977 int mod = len % 4;
10205 c = 0; 10978
10979 if (mod == 1)
10980 str2 = str2.Substring(0, str2.Length - 1);
10981 else if (mod == 2)
10982 str2 += "==";
10983 else if (mod == 3)
10984 str2 += "=";
10206 } 10985 }
10207 return llStringToBase64(ret); 10986
10987 byte[] data1;
10988 byte[] data2;
10989 try
10990 {
10991 data1 = Convert.FromBase64String(str1);
10992 data2 = Convert.FromBase64String(str2);
10993 }
10994 catch (Exception)
10995 {
10996 return new LSL_String(String.Empty);
10997 }
10998
10999 byte[] d2 = new Byte[data1.Length];
11000 int pos = 0;
11001
11002 if (data1.Length <= data2.Length)
11003 {
11004 Array.Copy(data2, 0, d2, 0, data1.Length);
11005 }
11006 else
11007 {
11008 while (pos < data1.Length)
11009 {
11010 len = data1.Length - pos;
11011 if (len > data2.Length)
11012 len = data2.Length;
11013
11014 Array.Copy(data2, 0, d2, pos, len);
11015 pos += len;
11016 }
11017 }
11018
11019 for (pos = 0 ; pos < data1.Length ; pos++ )
11020 data1[pos] ^= d2[pos];
11021
11022 return Convert.ToBase64String(data1);
10208 } 11023 }
10209 11024
10210 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11025 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10257,16 +11072,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10257 if (userAgent != null) 11072 if (userAgent != null)
10258 httpHeaders["User-Agent"] = userAgent; 11073 httpHeaders["User-Agent"] = userAgent;
10259 11074
11075 // See if the URL contains any header hacks
11076 string[] urlParts = url.Split(new char[] {'\n'});
11077 if (urlParts.Length > 1)
11078 {
11079 // Iterate the passed headers and parse them
11080 for (int i = 1 ; i < urlParts.Length ; i++ )
11081 {
11082 // The rest of those would be added to the body in SL.
11083 // Let's not do that.
11084 if (urlParts[i] == String.Empty)
11085 break;
11086
11087 // See if this could be a valid header
11088 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11089 if (headerParts.Length != 2)
11090 continue;
11091
11092 string headerName = headerParts[0].Trim();
11093 string headerValue = headerParts[1].Trim();
11094
11095 // Filter out headers that could be used to abuse
11096 // another system or cloak the request
11097 if (headerName.ToLower() == "x-secondlife-shard" ||
11098 headerName.ToLower() == "x-secondlife-object-name" ||
11099 headerName.ToLower() == "x-secondlife-object-key" ||
11100 headerName.ToLower() == "x-secondlife-region" ||
11101 headerName.ToLower() == "x-secondlife-local-position" ||
11102 headerName.ToLower() == "x-secondlife-local-velocity" ||
11103 headerName.ToLower() == "x-secondlife-local-rotation" ||
11104 headerName.ToLower() == "x-secondlife-owner-name" ||
11105 headerName.ToLower() == "x-secondlife-owner-key" ||
11106 headerName.ToLower() == "connection" ||
11107 headerName.ToLower() == "content-length" ||
11108 headerName.ToLower() == "from" ||
11109 headerName.ToLower() == "host" ||
11110 headerName.ToLower() == "proxy-authorization" ||
11111 headerName.ToLower() == "referer" ||
11112 headerName.ToLower() == "trailer" ||
11113 headerName.ToLower() == "transfer-encoding" ||
11114 headerName.ToLower() == "via" ||
11115 headerName.ToLower() == "authorization")
11116 continue;
11117
11118 httpHeaders[headerName] = headerValue;
11119 }
11120
11121 // Finally, strip any protocol specifier from the URL
11122 url = urlParts[0].Trim();
11123 int idx = url.IndexOf(" HTTP/");
11124 if (idx != -1)
11125 url = url.Substring(0, idx);
11126 }
11127
10260 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11128 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10261 Regex r = new Regex(authregex); 11129 Regex r = new Regex(authregex);
10262 int[] gnums = r.GetGroupNumbers(); 11130 int[] gnums = r.GetGroupNumbers();
10263 Match m = r.Match(url); 11131 Match m = r.Match(url);
10264 if (m.Success) { 11132 if (m.Success)
10265 for (int i = 1; i < gnums.Length; i++) { 11133 {
11134 for (int i = 1; i < gnums.Length; i++)
11135 {
10266 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11136 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10267 //CaptureCollection cc = g.Captures; 11137 //CaptureCollection cc = g.Captures;
10268 } 11138 }
10269 if (m.Groups.Count == 5) { 11139 if (m.Groups.Count == 5)
11140 {
10270 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11141 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10271 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11142 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10272 } 11143 }
@@ -10469,6 +11340,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10469 11340
10470 LSL_List ret = new LSL_List(); 11341 LSL_List ret = new LSL_List();
10471 UUID key = new UUID(); 11342 UUID key = new UUID();
11343
11344
10472 if (UUID.TryParse(id, out key)) 11345 if (UUID.TryParse(id, out key))
10473 { 11346 {
10474 ScenePresence av = World.GetScenePresence(key); 11347 ScenePresence av = World.GetScenePresence(key);
@@ -10486,13 +11359,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10486 ret.Add(new LSL_String("")); 11359 ret.Add(new LSL_String(""));
10487 break; 11360 break;
10488 case ScriptBaseClass.OBJECT_POS: 11361 case ScriptBaseClass.OBJECT_POS:
10489 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11362 Vector3 avpos;
11363
11364 if (av.ParentID != 0 && av.ParentPart != null)
11365 {
11366 avpos = av.OffsetPosition;
11367
11368 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11369 avpos -= sitOffset;
11370
11371 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11372 }
11373 else
11374 avpos = av.AbsolutePosition;
11375
11376 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10490 break; 11377 break;
10491 case ScriptBaseClass.OBJECT_ROT: 11378 case ScriptBaseClass.OBJECT_ROT:
10492 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11379 Quaternion avrot = av.Rotation;
11380 if (av.ParentID != 0 && av.ParentPart != null)
11381 {
11382 avrot = av.ParentPart.GetWorldRotation() * avrot;
11383 }
11384 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10493 break; 11385 break;
10494 case ScriptBaseClass.OBJECT_VELOCITY: 11386 case ScriptBaseClass.OBJECT_VELOCITY:
10495 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11387 Vector3 avvel = av.Velocity;
11388 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10496 break; 11389 break;
10497 case ScriptBaseClass.OBJECT_OWNER: 11390 case ScriptBaseClass.OBJECT_OWNER:
10498 ret.Add(new LSL_String(id)); 11391 ret.Add(new LSL_String(id));
@@ -10548,11 +11441,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10548 case ScriptBaseClass.OBJECT_NAME: 11441 case ScriptBaseClass.OBJECT_NAME:
10549 ret.Add(new LSL_String(obj.Name)); 11442 ret.Add(new LSL_String(obj.Name));
10550 break; 11443 break;
10551 case ScriptBaseClass.OBJECT_DESC: 11444 case ScriptBaseClass.OBJECT_DESC:
10552 ret.Add(new LSL_String(obj.Description)); 11445 ret.Add(new LSL_String(obj.Description));
10553 break; 11446 break;
10554 case ScriptBaseClass.OBJECT_POS: 11447 case ScriptBaseClass.OBJECT_POS:
10555 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11448 Vector3 opos = obj.AbsolutePosition;
11449 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10556 break; 11450 break;
10557 case ScriptBaseClass.OBJECT_ROT: 11451 case ScriptBaseClass.OBJECT_ROT:
10558 { 11452 {
@@ -10602,9 +11496,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10602 // The value returned in SL for normal prims is prim count 11496 // The value returned in SL for normal prims is prim count
10603 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11497 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10604 break; 11498 break;
10605 // The following 3 costs I have intentionaly coded to return zero. They are part of 11499
10606 // "Land Impact" calculations. These calculations are probably not applicable 11500 // costs below may need to be diferent for root parts, need to check
10607 // to OpenSim and are not yet complete in SL
10608 case ScriptBaseClass.OBJECT_SERVER_COST: 11501 case ScriptBaseClass.OBJECT_SERVER_COST:
10609 // The linden calculation is here 11502 // The linden calculation is here
10610 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11503 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10612,16 +11505,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10612 ret.Add(new LSL_Float(0)); 11505 ret.Add(new LSL_Float(0));
10613 break; 11506 break;
10614 case ScriptBaseClass.OBJECT_STREAMING_COST: 11507 case ScriptBaseClass.OBJECT_STREAMING_COST:
10615 // The linden calculation is here 11508 // The value returned in SL for normal prims is prim count * 0.06
10616 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11509 ret.Add(new LSL_Float(obj.StreamingCost));
10617 // The value returned in SL for normal prims looks like the prim count * 0.06
10618 ret.Add(new LSL_Float(0));
10619 break; 11510 break;
10620 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11511 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10621 // The linden calculation is here 11512 // The value returned in SL for normal prims is prim count
10622 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11513 ret.Add(new LSL_Float(obj.PhysicsCost));
10623 // The value returned in SL for normal prims looks like the prim count
10624 ret.Add(new LSL_Float(0));
10625 break; 11514 break;
10626 default: 11515 default:
10627 // Invalid or unhandled constant. 11516 // Invalid or unhandled constant.
@@ -10832,15 +11721,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10832 return result; 11721 return result;
10833 } 11722 }
10834 11723
10835 public void print(string str) 11724 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10836 { 11725 {
10837 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11726 List<SceneObjectPart> parts = GetLinkParts(link);
10838 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11727 if (parts.Count < 1)
10839 if (ossl != null) 11728 return 0;
10840 { 11729
10841 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11730 return GetNumberOfSides(parts[0]);
10842 m_log.Info("LSL print():" + str);
10843 }
10844 } 11731 }
10845 11732
10846 private string Name2Username(string name) 11733 private string Name2Username(string name)
@@ -10885,7 +11772,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10885 11772
10886 return rq.ToString(); 11773 return rq.ToString();
10887 } 11774 }
10888 11775/*
11776 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11777 {
11778 m_SayShoutCount = 0;
11779 }
11780*/
10889 private struct Tri 11781 private struct Tri
10890 { 11782 {
10891 public Vector3 p1; 11783 public Vector3 p1;
@@ -11025,9 +11917,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11025 11917
11026 ContactResult result = new ContactResult (); 11918 ContactResult result = new ContactResult ();
11027 result.ConsumerID = group.LocalId; 11919 result.ConsumerID = group.LocalId;
11028 result.Depth = intersection.distance; 11920// result.Depth = intersection.distance;
11029 result.Normal = intersection.normal; 11921 result.Normal = intersection.normal;
11030 result.Pos = intersection.ipoint; 11922 result.Pos = intersection.ipoint;
11923 result.Depth = Vector3.Mag(rayStart - result.Pos);
11031 11924
11032 contacts.Add(result); 11925 contacts.Add(result);
11033 }); 11926 });
@@ -11160,6 +12053,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11160 12053
11161 return contacts[0]; 12054 return contacts[0];
11162 } 12055 }
12056/*
12057 // not done:
12058 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12059 {
12060 ContactResult[] contacts = null;
12061 World.ForEachSOG(delegate(SceneObjectGroup group)
12062 {
12063 if (m_host.ParentGroup == group)
12064 return;
12065
12066 if (group.IsAttachment)
12067 return;
12068
12069 if(group.RootPart.PhysActor != null)
12070 return;
12071
12072 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12073 });
12074 return contacts;
12075 }
12076*/
11163 12077
11164 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12078 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11165 { 12079 {
@@ -11201,32 +12115,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11201 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12115 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11202 12116
11203 12117
11204 if (checkTerrain) 12118 if (World.SuportsRayCastFiltered())
11205 { 12119 {
11206 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12120 if (dist == 0)
11207 if (groundContact != null) 12121 return list;
11208 results.Add((ContactResult)groundContact);
11209 }
11210 12122
11211 if (checkAgents) 12123 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11212 { 12124 if (checkTerrain)
11213 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12125 rayfilter |= RayFilterFlags.land;
11214 foreach (ContactResult r in agentHits) 12126// if (checkAgents)
11215 results.Add(r); 12127// rayfilter |= RayFilterFlags.agent;
11216 } 12128 if (checkPhysical)
12129 rayfilter |= RayFilterFlags.physical;
12130 if (checkNonPhysical)
12131 rayfilter |= RayFilterFlags.nonphysical;
12132 if (detectPhantom)
12133 rayfilter |= RayFilterFlags.LSLPhanton;
12134
12135 Vector3 direction = dir * ( 1/dist);
12136
12137 if(rayfilter == 0)
12138 {
12139 list.Add(new LSL_Integer(0));
12140 return list;
12141 }
11217 12142
11218 if (checkPhysical || checkNonPhysical || detectPhantom) 12143 // get some more contacts to sort ???
12144 int physcount = 4 * count;
12145 if (physcount > 20)
12146 physcount = 20;
12147
12148 object physresults;
12149 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12150
12151 if (physresults == null)
12152 {
12153 list.Add(new LSL_Integer(-3)); // timeout error
12154 return list;
12155 }
12156
12157 results = (List<ContactResult>)physresults;
12158
12159 // for now physics doesn't detect sitted avatars so do it outside physics
12160 if (checkAgents)
12161 {
12162 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12163 foreach (ContactResult r in agentHits)
12164 results.Add(r);
12165 }
12166
12167 // TODO: Replace this with a better solution. ObjectIntersection can only
12168 // detect nonphysical phantoms. They are detected by virtue of being
12169 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12170 // physicsl phantoms as done by the physics scene
12171 // We don't want anything else but phantoms here.
12172 if (detectPhantom)
12173 {
12174 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12175 foreach (ContactResult r in objectHits)
12176 results.Add(r);
12177 }
12178 }
12179 else
11219 { 12180 {
11220 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12181 if (checkTerrain)
11221 foreach (ContactResult r in objectHits) 12182 {
11222 results.Add(r); 12183 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12184 if (groundContact != null)
12185 results.Add((ContactResult)groundContact);
12186 }
12187
12188 if (checkAgents)
12189 {
12190 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12191 foreach (ContactResult r in agentHits)
12192 results.Add(r);
12193 }
12194
12195 if (checkPhysical || checkNonPhysical || detectPhantom)
12196 {
12197 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12198 foreach (ContactResult r in objectHits)
12199 results.Add(r);
12200 }
11223 } 12201 }
11224 12202
11225 results.Sort(delegate(ContactResult a, ContactResult b) 12203 results.Sort(delegate(ContactResult a, ContactResult b)
11226 { 12204 {
11227 return a.Depth.CompareTo(b.Depth); 12205 return a.Depth.CompareTo(b.Depth);
11228 }); 12206 });
11229 12207
11230 int values = 0; 12208 int values = 0;
11231 SceneObjectGroup thisgrp = m_host.ParentGroup; 12209 SceneObjectGroup thisgrp = m_host.ParentGroup;
11232 12210
@@ -11319,7 +12297,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11319 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12297 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11320 if (!isAccount) return 0; 12298 if (!isAccount) return 0;
11321 if (estate.HasAccess(id)) return 1; 12299 if (estate.HasAccess(id)) return 1;
11322 if (estate.IsBanned(id)) 12300 if (estate.IsBanned(id, World.GetUserFlags(id)))
11323 estate.RemoveBan(id); 12301 estate.RemoveBan(id);
11324 estate.AddEstateUser(id); 12302 estate.AddEstateUser(id);
11325 break; 12303 break;
@@ -11338,14 +12316,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11338 break; 12316 break;
11339 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12317 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11340 if (!isAccount) return 0; 12318 if (!isAccount) return 0;
11341 if (estate.IsBanned(id)) return 1; 12319 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11342 EstateBan ban = new EstateBan(); 12320 EstateBan ban = new EstateBan();
11343 ban.EstateID = estate.EstateID; 12321 ban.EstateID = estate.EstateID;
11344 ban.BannedUserID = id; 12322 ban.BannedUserID = id;
11345 estate.AddBan(ban); 12323 estate.AddBan(ban);
11346 break; 12324 break;
11347 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12325 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11348 if (!isAccount || !estate.IsBanned(id)) return 0; 12326 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11349 estate.RemoveBan(id); 12327 estate.RemoveBan(id);
11350 break; 12328 break;
11351 default: return 0; 12329 default: return 0;
@@ -11374,7 +12352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11374 return 16384; 12352 return 16384;
11375 } 12353 }
11376 12354
11377 public LSL_Integer llGetUsedMemory() 12355 public virtual LSL_Integer llGetUsedMemory()
11378 { 12356 {
11379 m_host.AddScriptLPS(1); 12357 m_host.AddScriptLPS(1);
11380 // The value returned for LSO scripts in SL 12358 // The value returned for LSO scripts in SL
@@ -11402,22 +12380,731 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11402 public void llSetSoundQueueing(int queue) 12380 public void llSetSoundQueueing(int queue)
11403 { 12381 {
11404 m_host.AddScriptLPS(1); 12382 m_host.AddScriptLPS(1);
11405 NotImplemented("llSetSoundQueueing");
11406 } 12383 }
11407 12384
11408 public void llCollisionSprite(string impact_sprite) 12385 public void llCollisionSprite(string impact_sprite)
11409 { 12386 {
11410 m_host.AddScriptLPS(1); 12387 m_host.AddScriptLPS(1);
11411 NotImplemented("llCollisionSprite"); 12388 // Viewer 2.0 broke this and it's likely LL has no intention
12389 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11412 } 12390 }
11413 12391
11414 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12392 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11415 { 12393 {
11416 m_host.AddScriptLPS(1); 12394 m_host.AddScriptLPS(1);
11417 NotImplemented("llGodLikeRezObject"); 12395
12396 if (!World.Permissions.IsGod(m_host.OwnerID))
12397 NotImplemented("llGodLikeRezObject");
12398
12399 AssetBase rezAsset = World.AssetService.Get(inventory);
12400 if (rezAsset == null)
12401 {
12402 llSay(0, "Asset not found");
12403 return;
12404 }
12405
12406 SceneObjectGroup group = null;
12407
12408 try
12409 {
12410 string xmlData = Utils.BytesToString(rezAsset.Data);
12411 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12412 }
12413 catch
12414 {
12415 llSay(0, "Asset not found");
12416 return;
12417 }
12418
12419 if (group == null)
12420 {
12421 llSay(0, "Asset not found");
12422 return;
12423 }
12424
12425 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12426 group.RootPart.AttachOffset = group.AbsolutePosition;
12427
12428 group.ResetIDs();
12429
12430 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12431 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12432 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12433 group.ScheduleGroupForFullUpdate();
12434
12435 // objects rezzed with this method are die_at_edge by default.
12436 group.RootPart.SetDieAtEdge(true);
12437
12438 group.ResumeScripts();
12439
12440 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12441 "object_rez", new Object[] {
12442 new LSL_String(
12443 group.RootPart.UUID.ToString()) },
12444 new DetectParams[0]));
12445 }
12446
12447 public LSL_String llTransferLindenDollars(string destination, int amount)
12448 {
12449 UUID txn = UUID.Random();
12450
12451 Util.FireAndForget(delegate(object x)
12452 {
12453 int replycode = 0;
12454 string replydata = destination + "," + amount.ToString();
12455
12456 try
12457 {
12458 TaskInventoryItem item = m_item;
12459 if (item == null)
12460 {
12461 replydata = "SERVICE_ERROR";
12462 return;
12463 }
12464
12465 m_host.AddScriptLPS(1);
12466
12467 if (item.PermsGranter == UUID.Zero)
12468 {
12469 replydata = "MISSING_PERMISSION_DEBIT";
12470 return;
12471 }
12472
12473 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12474 {
12475 replydata = "MISSING_PERMISSION_DEBIT";
12476 return;
12477 }
12478
12479 UUID toID = new UUID();
12480
12481 if (!UUID.TryParse(destination, out toID))
12482 {
12483 replydata = "INVALID_AGENT";
12484 return;
12485 }
12486
12487 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12488
12489 if (money == null)
12490 {
12491 replydata = "TRANSFERS_DISABLED";
12492 return;
12493 }
12494
12495 bool result = money.ObjectGiveMoney(
12496 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12497
12498 if (result)
12499 {
12500 replycode = 1;
12501 return;
12502 }
12503
12504 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12505 }
12506 finally
12507 {
12508 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12509 "transaction_result", new Object[] {
12510 new LSL_String(txn.ToString()),
12511 new LSL_Integer(replycode),
12512 new LSL_String(replydata) },
12513 new DetectParams[0]));
12514 }
12515 });
12516
12517 return txn.ToString();
11418 } 12518 }
11419 12519
11420 #endregion 12520 #endregion
12521
12522 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12523 {
12524 SceneObjectGroup group = m_host.ParentGroup;
12525
12526 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12527 return;
12528 if (group.IsAttachment)
12529 return;
12530
12531 if (frames.Data.Length > 0) // We are getting a new motion
12532 {
12533 if (group.RootPart.KeyframeMotion != null)
12534 group.RootPart.KeyframeMotion.Delete();
12535 group.RootPart.KeyframeMotion = null;
12536
12537 int idx = 0;
12538
12539 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12540 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12541
12542 while (idx < options.Data.Length)
12543 {
12544 int option = (int)options.GetLSLIntegerItem(idx++);
12545 int remain = options.Data.Length - idx;
12546
12547 switch (option)
12548 {
12549 case ScriptBaseClass.KFM_MODE:
12550 if (remain < 1)
12551 break;
12552 int modeval = (int)options.GetLSLIntegerItem(idx++);
12553 switch(modeval)
12554 {
12555 case ScriptBaseClass.KFM_FORWARD:
12556 mode = KeyframeMotion.PlayMode.Forward;
12557 break;
12558 case ScriptBaseClass.KFM_REVERSE:
12559 mode = KeyframeMotion.PlayMode.Reverse;
12560 break;
12561 case ScriptBaseClass.KFM_LOOP:
12562 mode = KeyframeMotion.PlayMode.Loop;
12563 break;
12564 case ScriptBaseClass.KFM_PING_PONG:
12565 mode = KeyframeMotion.PlayMode.PingPong;
12566 break;
12567 }
12568 break;
12569 case ScriptBaseClass.KFM_DATA:
12570 if (remain < 1)
12571 break;
12572 int dataval = (int)options.GetLSLIntegerItem(idx++);
12573 data = (KeyframeMotion.DataFormat)dataval;
12574 break;
12575 }
12576 }
12577
12578 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12579
12580 idx = 0;
12581
12582 int elemLength = 2;
12583 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12584 elemLength = 3;
12585
12586 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12587 while (idx < frames.Data.Length)
12588 {
12589 int remain = frames.Data.Length - idx;
12590
12591 if (remain < elemLength)
12592 break;
12593
12594 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12595 frame.Position = null;
12596 frame.Rotation = null;
12597
12598 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12599 {
12600 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12601 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12602 }
12603 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12604 {
12605 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12606 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12607 }
12608
12609 float tempf = (float)frames.GetLSLFloatItem(idx++);
12610 frame.TimeMS = (int)(tempf * 1000.0f);
12611
12612 keyframes.Add(frame);
12613 }
12614
12615 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12616 group.RootPart.KeyframeMotion.Start();
12617 }
12618 else
12619 {
12620 if (group.RootPart.KeyframeMotion == null)
12621 return;
12622
12623 if (options.Data.Length == 0)
12624 {
12625 group.RootPart.KeyframeMotion.Stop();
12626 return;
12627 }
12628
12629 int code = (int)options.GetLSLIntegerItem(0);
12630
12631 int idx = 0;
12632
12633 while (idx < options.Data.Length)
12634 {
12635 int option = (int)options.GetLSLIntegerItem(idx++);
12636 int remain = options.Data.Length - idx;
12637
12638 switch (option)
12639 {
12640 case ScriptBaseClass.KFM_COMMAND:
12641 int cmd = (int)options.GetLSLIntegerItem(idx++);
12642 switch (cmd)
12643 {
12644 case ScriptBaseClass.KFM_CMD_PLAY:
12645 group.RootPart.KeyframeMotion.Start();
12646 break;
12647 case ScriptBaseClass.KFM_CMD_STOP:
12648 group.RootPart.KeyframeMotion.Stop();
12649 break;
12650 case ScriptBaseClass.KFM_CMD_PAUSE:
12651 group.RootPart.KeyframeMotion.Pause();
12652 break;
12653 }
12654 break;
12655 }
12656 }
12657 }
12658 }
12659
12660 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12661 {
12662 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12663
12664 int idx = 0;
12665 int idxStart = 0;
12666
12667 bool positionChanged = false;
12668 Vector3 finalPos = Vector3.Zero;
12669
12670 try
12671 {
12672 while (idx < rules.Length)
12673 {
12674 ++rulesParsed;
12675 int code = rules.GetLSLIntegerItem(idx++);
12676
12677 int remain = rules.Length - idx;
12678 idxStart = idx;
12679
12680 switch (code)
12681 {
12682 case (int)ScriptBaseClass.PRIM_POSITION:
12683 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12684 {
12685 if (remain < 1)
12686 return null;
12687
12688 LSL_Vector v;
12689 v = rules.GetVector3Item(idx++);
12690
12691 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12692 if (part == null)
12693 break;
12694
12695 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12696 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12697 if (part.LinkNum > 1)
12698 {
12699 localRot = GetPartLocalRot(part);
12700 localPos = GetPartLocalPos(part);
12701 }
12702
12703 v -= localPos;
12704 v /= localRot;
12705
12706 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12707
12708 v = v + 2 * sitOffset;
12709
12710 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12711 av.SendAvatarDataToAllAgents();
12712
12713 }
12714 break;
12715
12716 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12717 case (int)ScriptBaseClass.PRIM_ROTATION:
12718 {
12719 if (remain < 1)
12720 return null;
12721
12722 LSL_Rotation r;
12723 r = rules.GetQuaternionItem(idx++);
12724
12725 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12726 if (part == null)
12727 break;
12728
12729 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12730 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12731
12732 if (part.LinkNum > 1)
12733 localRot = GetPartLocalRot(part);
12734
12735 r = r * llGetRootRotation() / localRot;
12736 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12737 av.SendAvatarDataToAllAgents();
12738 }
12739 break;
12740
12741 // parse rest doing nothing but number of parameters error check
12742 case (int)ScriptBaseClass.PRIM_SIZE:
12743 case (int)ScriptBaseClass.PRIM_MATERIAL:
12744 case (int)ScriptBaseClass.PRIM_PHANTOM:
12745 case (int)ScriptBaseClass.PRIM_PHYSICS:
12746 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12747 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12748 case (int)ScriptBaseClass.PRIM_NAME:
12749 case (int)ScriptBaseClass.PRIM_DESC:
12750 if (remain < 1)
12751 return null;
12752 idx++;
12753 break;
12754
12755 case (int)ScriptBaseClass.PRIM_GLOW:
12756 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12757 case (int)ScriptBaseClass.PRIM_TEXGEN:
12758 if (remain < 2)
12759 return null;
12760 idx += 2;
12761 break;
12762
12763 case (int)ScriptBaseClass.PRIM_TYPE:
12764 if (remain < 3)
12765 return null;
12766 code = (int)rules.GetLSLIntegerItem(idx++);
12767 remain = rules.Length - idx;
12768 switch (code)
12769 {
12770 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12771 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12772 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12773 if (remain < 6)
12774 return null;
12775 idx += 6;
12776 break;
12777
12778 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12779 if (remain < 5)
12780 return null;
12781 idx += 5;
12782 break;
12783
12784 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12785 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12786 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12787 if (remain < 11)
12788 return null;
12789 idx += 11;
12790 break;
12791
12792 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12793 if (remain < 2)
12794 return null;
12795 idx += 2;
12796 break;
12797 }
12798 break;
12799
12800 case (int)ScriptBaseClass.PRIM_COLOR:
12801 case (int)ScriptBaseClass.PRIM_TEXT:
12802 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12803 case (int)ScriptBaseClass.PRIM_OMEGA:
12804 if (remain < 3)
12805 return null;
12806 idx += 3;
12807 break;
12808
12809 case (int)ScriptBaseClass.PRIM_TEXTURE:
12810 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12811 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12812 if (remain < 5)
12813 return null;
12814 idx += 5;
12815 break;
12816
12817 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12818 if (remain < 7)
12819 return null;
12820
12821 idx += 7;
12822 break;
12823
12824 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12825 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12826 return null;
12827
12828 return rules.GetSublist(idx, -1);
12829 }
12830 }
12831 }
12832 catch (InvalidCastException e)
12833 {
12834 ShoutError(string.Format(
12835 "{0} error running rule #{1}: arg #{2} ",
12836 originFunc, rulesParsed, idx - idxStart) + e.Message);
12837 }
12838 finally
12839 {
12840 if (positionChanged)
12841 {
12842 av.OffsetPosition = finalPos;
12843// av.SendAvatarDataToAllAgents();
12844 av.SendTerseUpdateToAllClients();
12845 positionChanged = false;
12846 }
12847 }
12848 return null;
12849 }
12850
12851 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12852 {
12853 // avatars case
12854 // replies as SL wiki
12855
12856// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12857 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12858
12859 int idx = 0;
12860 while (idx < rules.Length)
12861 {
12862 int code = (int)rules.GetLSLIntegerItem(idx++);
12863 int remain = rules.Length - idx;
12864
12865 switch (code)
12866 {
12867 case (int)ScriptBaseClass.PRIM_MATERIAL:
12868 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12869 break;
12870
12871 case (int)ScriptBaseClass.PRIM_PHYSICS:
12872 res.Add(new LSL_Integer(0));
12873 break;
12874
12875 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12876 res.Add(new LSL_Integer(0));
12877 break;
12878
12879 case (int)ScriptBaseClass.PRIM_PHANTOM:
12880 res.Add(new LSL_Integer(0));
12881 break;
12882
12883 case (int)ScriptBaseClass.PRIM_POSITION:
12884
12885 Vector3 pos = avatar.OffsetPosition;
12886
12887 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12888 pos -= sitOffset;
12889
12890 if( sitPart != null)
12891 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12892
12893 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12894 break;
12895
12896 case (int)ScriptBaseClass.PRIM_SIZE:
12897 // as in llGetAgentSize above
12898 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12899 break;
12900
12901 case (int)ScriptBaseClass.PRIM_ROTATION:
12902 Quaternion rot = avatar.Rotation;
12903 if (sitPart != null)
12904 {
12905 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12906 }
12907
12908 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12909 break;
12910
12911 case (int)ScriptBaseClass.PRIM_TYPE:
12912 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12913 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12914 res.Add(new LSL_Vector(0f,1.0f,0f));
12915 res.Add(new LSL_Float(0.0f));
12916 res.Add(new LSL_Vector(0, 0, 0));
12917 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12918 res.Add(new LSL_Vector(0, 0, 0));
12919 break;
12920
12921 case (int)ScriptBaseClass.PRIM_TEXTURE:
12922 if (remain < 1)
12923 return null;
12924
12925 int face = (int)rules.GetLSLIntegerItem(idx++);
12926 if (face == ScriptBaseClass.ALL_SIDES)
12927 {
12928 for (face = 0; face < 21; face++)
12929 {
12930 res.Add(new LSL_String(""));
12931 res.Add(new LSL_Vector(0,0,0));
12932 res.Add(new LSL_Vector(0,0,0));
12933 res.Add(new LSL_Float(0.0));
12934 }
12935 }
12936 else
12937 {
12938 if (face >= 0 && face < 21)
12939 {
12940 res.Add(new LSL_String(""));
12941 res.Add(new LSL_Vector(0,0,0));
12942 res.Add(new LSL_Vector(0,0,0));
12943 res.Add(new LSL_Float(0.0));
12944 }
12945 }
12946 break;
12947
12948 case (int)ScriptBaseClass.PRIM_COLOR:
12949 if (remain < 1)
12950 return null;
12951
12952 face = (int)rules.GetLSLIntegerItem(idx++);
12953
12954 if (face == ScriptBaseClass.ALL_SIDES)
12955 {
12956 for (face = 0; face < 21; face++)
12957 {
12958 res.Add(new LSL_Vector(0,0,0));
12959 res.Add(new LSL_Float(0));
12960 }
12961 }
12962 else
12963 {
12964 res.Add(new LSL_Vector(0,0,0));
12965 res.Add(new LSL_Float(0));
12966 }
12967 break;
12968
12969 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12970 if (remain < 1)
12971 return null;
12972 face = (int)rules.GetLSLIntegerItem(idx++);
12973
12974 if (face == ScriptBaseClass.ALL_SIDES)
12975 {
12976 for (face = 0; face < 21; face++)
12977 {
12978 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12979 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12980 }
12981 }
12982 else
12983 {
12984 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12985 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12986 }
12987 break;
12988
12989 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12990 if (remain < 1)
12991 return null;
12992 face = (int)rules.GetLSLIntegerItem(idx++);
12993
12994 if (face == ScriptBaseClass.ALL_SIDES)
12995 {
12996 for (face = 0; face < 21; face++)
12997 {
12998 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12999 }
13000 }
13001 else
13002 {
13003 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13004 }
13005 break;
13006
13007 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13008 res.Add(new LSL_Integer(0));
13009 res.Add(new LSL_Integer(0));// softness
13010 res.Add(new LSL_Float(0.0f)); // gravity
13011 res.Add(new LSL_Float(0.0f)); // friction
13012 res.Add(new LSL_Float(0.0f)); // wind
13013 res.Add(new LSL_Float(0.0f)); // tension
13014 res.Add(new LSL_Vector(0f,0f,0f));
13015 break;
13016
13017 case (int)ScriptBaseClass.PRIM_TEXGEN:
13018 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13019 if (remain < 1)
13020 return null;
13021 face = (int)rules.GetLSLIntegerItem(idx++);
13022
13023 if (face == ScriptBaseClass.ALL_SIDES)
13024 {
13025 for (face = 0; face < 21; face++)
13026 {
13027 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13028 }
13029 }
13030 else
13031 {
13032 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13033 }
13034 break;
13035
13036 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13037 res.Add(new LSL_Integer(0));
13038 res.Add(new LSL_Vector(0f,0f,0f));
13039 res.Add(new LSL_Float(0f)); // intensity
13040 res.Add(new LSL_Float(0f)); // radius
13041 res.Add(new LSL_Float(0f)); // falloff
13042 break;
13043
13044 case (int)ScriptBaseClass.PRIM_GLOW:
13045 if (remain < 1)
13046 return null;
13047 face = (int)rules.GetLSLIntegerItem(idx++);
13048
13049 if (face == ScriptBaseClass.ALL_SIDES)
13050 {
13051 for (face = 0; face < 21; face++)
13052 {
13053 res.Add(new LSL_Float(0f));
13054 }
13055 }
13056 else
13057 {
13058 res.Add(new LSL_Float(0f));
13059 }
13060 break;
13061
13062 case (int)ScriptBaseClass.PRIM_TEXT:
13063 res.Add(new LSL_String(""));
13064 res.Add(new LSL_Vector(0f,0f,0f));
13065 res.Add(new LSL_Float(1.0f));
13066 break;
13067
13068 case (int)ScriptBaseClass.PRIM_NAME:
13069 res.Add(new LSL_String(avatar.Name));
13070 break;
13071
13072 case (int)ScriptBaseClass.PRIM_DESC:
13073 res.Add(new LSL_String(""));
13074 break;
13075
13076 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13077 Quaternion lrot = avatar.Rotation;
13078
13079 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13080 {
13081 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13082 }
13083 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13084 break;
13085
13086 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13087 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13088 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13089 lpos -= lsitOffset;
13090
13091 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13092 {
13093 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13094 }
13095 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13096 break;
13097
13098 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13099 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13100 return null;
13101
13102 return rules.GetSublist(idx, -1);
13103 }
13104 }
13105
13106 return null;
13107 }
11421 } 13108 }
11422 13109
11423 public class NotecardCache 13110 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 31be450..2c682d4 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)
@@ -3549,6 +3604,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3549 if (m_UrlModule != null) 3604 if (m_UrlModule != null)
3550 m_UrlModule.HttpContentType(new UUID(id),type); 3605 m_UrlModule.HttpContentType(new UUID(id),type);
3551 } 3606 }
3607
3552 /// Shout an error if the object owner did not grant the script the specified permissions. 3608 /// Shout an error if the object owner did not grant the script the specified permissions.
3553 /// </summary> 3609 /// </summary>
3554 /// <param name="perms"></param> 3610 /// <param name="perms"></param>
@@ -3636,4 +3692,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3636 DropAttachmentAt(false, pos, rot); 3692 DropAttachmentAt(false, pos, rot);
3637 } 3693 }
3638 } 3694 }
3639} \ 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 }