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.cs23
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs117
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3146
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs155
-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, 2664 insertions, 825 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 47a9cdc..6879ebb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -305,6 +305,29 @@ 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 if (xmlrpc != null)
321 {
322 xmlrpc.DeleteChannels(itemID);
323 xmlrpc.CancelSRDRequests(itemID);
324 }
325
326 // Remove Sensors
327 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
328
329 }
330
308 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 331 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
309 { 332 {
310 List<Object> data = new List<Object>(); 333 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..fce8ff8
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,117 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Threading;
30using System.Reflection;
31using System.Collections;
32using System.Collections.Generic;
33using System.Runtime.Remoting.Lifetime;
34using OpenMetaverse;
35using Nini.Config;
36using OpenSim;
37using OpenSim.Framework;
38using OpenSim.Region.CoreModules.World.LightShare;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.ScriptEngine.Shared;
42using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
43using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
44using OpenSim.Region.ScriptEngine.Interfaces;
45using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
46using OpenSim.Services.Interfaces;
47
48using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
49using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
50using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
51using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
52using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
53using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
54using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
55
56namespace OpenSim.Region.ScriptEngine.Shared.Api
57{
58 [Serializable]
59 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
60 {
61 internal IScriptEngine m_ScriptEngine;
62 internal SceneObjectPart m_host;
63 internal TaskInventoryItem m_item;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_item = item;
71
72 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
73 m_CMFunctionsEnabled = true;
74 }
75
76 public override Object InitializeLifetimeService()
77 {
78 ILease lease = (ILease)base.InitializeLifetimeService();
79
80 if (lease.CurrentState == LeaseState.Initial)
81 {
82 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
83 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
84 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
85 }
86 return lease;
87 }
88
89 public Scene World
90 {
91 get { return m_ScriptEngine.World; }
92 }
93
94 public string cmDetectedCountry(int number)
95 {
96 m_host.AddScriptLPS(1);
97 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
98 if (detectedParams == null)
99 return String.Empty;
100 return detectedParams.Country;
101 }
102
103 public string cmGetAgentCountry(LSL_Key key)
104 {
105 if (!World.Permissions.IsGod(m_host.OwnerID))
106 return String.Empty;
107
108 UUID uuid;
109
110 if (!UUID.TryParse(key, out uuid))
111 return String.Empty;
112
113 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
114 return account.UserCountry;
115 }
116 }
117}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 001f4d9..1be2776 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,14 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -66,6 +69,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
66using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 69using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
67using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 70using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
68using System.Reflection; 71using System.Reflection;
72using Timer = System.Timers.Timer;
69 73
70namespace OpenSim.Region.ScriptEngine.Shared.Api 74namespace OpenSim.Region.ScriptEngine.Shared.Api
71{ 75{
@@ -112,17 +116,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
112 protected int m_notecardLineReadCharsMax = 255; 116 protected int m_notecardLineReadCharsMax = 255;
113 protected int m_scriptConsoleChannel = 0; 117 protected int m_scriptConsoleChannel = 0;
114 protected bool m_scriptConsoleChannelEnabled = false; 118 protected bool m_scriptConsoleChannelEnabled = false;
119 protected bool m_debuggerSafe = false;
115 protected IUrlModule m_UrlModule = null; 120 protected IUrlModule m_UrlModule = null;
116 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 121 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
117 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 122 new Dictionary<UUID, UserInfoCacheEntry>();
123 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
118 protected ISoundModule m_SoundModule = null; 124 protected ISoundModule m_SoundModule = null;
119 125
126// protected Timer m_ShoutSayTimer;
127 protected int m_SayShoutCount = 0;
128 DateTime m_lastSayShoutCheck;
129
130 private Dictionary<string, string> MovementAnimationsForLSL =
131 new Dictionary<string, string> {
132 {"FLY", "Flying"},
133 {"FLYSLOW", "FlyingSlow"},
134 {"HOVER_UP", "Hovering Up"},
135 {"HOVER_DOWN", "Hovering Down"},
136 {"HOVER", "Hovering"},
137 {"LAND", "Landing"},
138 {"FALLDOWN", "Falling Down"},
139 {"PREJUMP", "PreJumping"},
140 {"JUMP", "Jumping"},
141 {"STANDUP", "Standing Up"},
142 {"SOFT_LAND", "Soft Landing"},
143 {"STAND", "Standing"},
144 {"CROUCHWALK", "CrouchWalking"},
145 {"RUN", "Running"},
146 {"WALK", "Walking"},
147 {"CROUCH", "Crouching"},
148 {"TURNLEFT", "Turning Left"},
149 {"TURNRIGHT", "Turning Right"}
150 };
151
120 public void Initialize( 152 public void Initialize(
121 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) 153 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
122 { 154 {
155 m_lastSayShoutCheck = DateTime.UtcNow;
156
123 m_ScriptEngine = scriptEngine; 157 m_ScriptEngine = scriptEngine;
124 m_host = host; 158 m_host = host;
125 m_item = item; 159 m_item = item;
160 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
126 m_coopSleepHandle = coopSleepHandle; 161 m_coopSleepHandle = coopSleepHandle;
127 162
128 LoadConfig(); 163 LoadConfig();
@@ -211,6 +246,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
211 get { return m_ScriptEngine.World; } 246 get { return m_ScriptEngine.World; }
212 } 247 }
213 248
249 [DebuggerNonUserCode]
214 public void state(string newState) 250 public void state(string newState)
215 { 251 {
216 m_ScriptEngine.SetState(m_item.ItemID, newState); 252 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -220,6 +256,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
220 /// Reset the named script. The script must be present 256 /// Reset the named script. The script must be present
221 /// in the same prim. 257 /// in the same prim.
222 /// </summary> 258 /// </summary>
259 [DebuggerNonUserCode]
223 public void llResetScript() 260 public void llResetScript()
224 { 261 {
225 m_host.AddScriptLPS(1); 262 m_host.AddScriptLPS(1);
@@ -282,6 +319,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
282 } 319 }
283 } 320 }
284 321
322 public List<ScenePresence> GetLinkAvatars(int linkType)
323 {
324 List<ScenePresence> ret = new List<ScenePresence>();
325 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
326 return ret;
327
328 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
329
330 switch (linkType)
331 {
332 case ScriptBaseClass.LINK_SET:
333 return avs;
334
335 case ScriptBaseClass.LINK_ROOT:
336 return ret;
337
338 case ScriptBaseClass.LINK_ALL_OTHERS:
339 return avs;
340
341 case ScriptBaseClass.LINK_ALL_CHILDREN:
342 return avs;
343
344 case ScriptBaseClass.LINK_THIS:
345 return ret;
346
347 default:
348 if (linkType < 0)
349 return ret;
350
351 int partCount = m_host.ParentGroup.GetPartCount();
352
353 if (linkType <= partCount)
354 {
355 return ret;
356 }
357 else
358 {
359 linkType = linkType - partCount;
360 if (linkType > avs.Count)
361 {
362 return ret;
363 }
364 else
365 {
366 ret.Add(avs[linkType-1]);
367 return ret;
368 }
369 }
370 }
371 }
372
285 public List<SceneObjectPart> GetLinkParts(int linkType) 373 public List<SceneObjectPart> GetLinkParts(int linkType)
286 { 374 {
287 return GetLinkParts(m_host, linkType); 375 return GetLinkParts(m_host, linkType);
@@ -290,6 +378,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
290 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 378 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
291 { 379 {
292 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 380 List<SceneObjectPart> ret = new List<SceneObjectPart>();
381 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
382 return ret;
293 ret.Add(part); 383 ret.Add(part);
294 384
295 switch (linkType) 385 switch (linkType)
@@ -516,31 +606,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
516 606
517 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 607 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
518 608
519 /// <summary> 609 // Utility function for llRot2Euler
520 /// Convert an LSL rotation to a Euler vector. 610
521 /// </summary> 611 // normalize an angle between -PI and PI (-180 to +180 degrees)
522 /// <remarks> 612 protected double NormalizeAngle(double angle)
523 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
524 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
525 /// </remarks>
526 /// <param name="r"></param>
527 /// <returns></returns>
528 public LSL_Vector llRot2Euler(LSL_Rotation r)
529 { 613 {
530 m_host.AddScriptLPS(1); 614 if (angle > -Math.PI && angle < Math.PI)
615 return angle;
531 616
532 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 617 int numPis = (int)(Math.PI / angle);
533 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 618 double remainder = angle - Math.PI * numPis;
534 if (m == 0.0) return new LSL_Vector(); 619 if (numPis % 2 == 1)
535 double x = Math.Atan2(-v.y, v.z); 620 return Math.PI - angle;
536 double sin = v.x / m; 621 return remainder;
537 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 622 }
538 double y = Math.Asin(sin);
539 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
540 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)));
541 double z = Math.Atan2(v.y, v.x);
542 623
543 return new LSL_Vector(x, y, z); 624 public LSL_Vector llRot2Euler(LSL_Rotation q1)
625 {
626 m_host.AddScriptLPS(1);
627 LSL_Vector eul = new LSL_Vector();
628
629 double sqw = q1.s*q1.s;
630 double sqx = q1.x*q1.x;
631 double sqy = q1.z*q1.z;
632 double sqz = q1.y*q1.y;
633 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
634 double test = q1.x*q1.z + q1.y*q1.s;
635 if (test > 0.4999*unit) { // singularity at north pole
636 eul.z = 2 * Math.Atan2(q1.x,q1.s);
637 eul.y = Math.PI/2;
638 eul.x = 0;
639 return eul;
640 }
641 if (test < -0.4999*unit) { // singularity at south pole
642 eul.z = -2 * Math.Atan2(q1.x,q1.s);
643 eul.y = -Math.PI/2;
644 eul.x = 0;
645 return eul;
646 }
647 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
648 eul.y = Math.Asin(2*test/unit);
649 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
650 return eul;
544 } 651 }
545 652
546 /* From wiki: 653 /* From wiki:
@@ -593,18 +700,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
593 m_host.AddScriptLPS(1); 700 m_host.AddScriptLPS(1);
594 701
595 double x,y,z,s; 702 double x,y,z,s;
596 703 v.x *= 0.5;
597 double c1 = Math.Cos(v.x * 0.5); 704 v.y *= 0.5;
598 double c2 = Math.Cos(v.y * 0.5); 705 v.z *= 0.5;
599 double c3 = Math.Cos(v.z * 0.5); 706 double c1 = Math.Cos(v.x);
600 double s1 = Math.Sin(v.x * 0.5); 707 double c2 = Math.Cos(v.y);
601 double s2 = Math.Sin(v.y * 0.5); 708 double c1c2 = c1 * c2;
602 double s3 = Math.Sin(v.z * 0.5); 709 double s1 = Math.Sin(v.x);
603 710 double s2 = Math.Sin(v.y);
604 x = s1 * c2 * c3 + c1 * s2 * s3; 711 double s1s2 = s1 * s2;
605 y = c1 * s2 * c3 - s1 * c2 * s3; 712 double c1s2 = c1 * s2;
606 z = s1 * s2 * c3 + c1 * c2 * s3; 713 double s1c2 = s1 * c2;
607 s = c1 * c2 * c3 - s1 * s2 * s3; 714 double c3 = Math.Cos(v.z);
715 double s3 = Math.Sin(v.z);
716
717 x = s1c2 * c3 + c1s2 * s3;
718 y = c1s2 * c3 - s1c2 * s3;
719 z = s1s2 * c3 + c1c2 * s3;
720 s = c1c2 * c3 - s1s2 * s3;
608 721
609 return new LSL_Rotation(x, y, z, s); 722 return new LSL_Rotation(x, y, z, s);
610 } 723 }
@@ -742,77 +855,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
742 { 855 {
743 //A and B should both be normalized 856 //A and B should both be normalized
744 m_host.AddScriptLPS(1); 857 m_host.AddScriptLPS(1);
745 LSL_Rotation rotBetween; 858 /* This method is more accurate than the SL one, and thus causes problems
746 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 859 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
747 // continue calculation. 860
748 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 861 double dotProduct = LSL_Vector.Dot(a, b);
862 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
863 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
864 double angle = Math.Acos(dotProduct / magProduct);
865 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
866 double s = Math.Sin(angle / 2);
867
868 double x = axis.x * s;
869 double y = axis.y * s;
870 double z = axis.z * s;
871 double w = Math.Cos(angle / 2);
872
873 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
874 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
875
876 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
877 */
878
879 // This method mimics the 180 errors found in SL
880 // See www.euclideanspace.com... angleBetween
881 LSL_Vector vec_a = a;
882 LSL_Vector vec_b = b;
883
884 // Eliminate zero length
885 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
886 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
887 if (vec_a_mag < 0.00001 ||
888 vec_b_mag < 0.00001)
749 { 889 {
750 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 890 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
751 } 891 }
752 else 892
893 // Normalize
894 vec_a = llVecNorm(vec_a);
895 vec_b = llVecNorm(vec_b);
896
897 // Calculate axis and rotation angle
898 LSL_Vector axis = vec_a % vec_b;
899 LSL_Float cos_theta = vec_a * vec_b;
900
901 // Check if parallel
902 if (cos_theta > 0.99999)
753 { 903 {
754 a = LSL_Vector.Norm(a); 904 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
755 b = LSL_Vector.Norm(b); 905 }
756 double dotProduct = LSL_Vector.Dot(a, b); 906
757 // There are two degenerate cases possible. These are for vectors 180 or 907 // Check if anti-parallel
758 // 0 degrees apart. These have to be detected and handled individually. 908 else if (cos_theta < -0.99999)
759 // 909 {
760 // Check for vectors 180 degrees apart. 910 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
761 // A dot product of -1 would mean the angle between vectors is 180 degrees. 911 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
762 if (dotProduct < -0.9999999f) 912 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
763 { 913 }
764 // First assume X axis is orthogonal to the vectors. 914 else // other rotation
765 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 915 {
766 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 916 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
767 // Check for near zero vector. A very small non-zero number here will create 917 axis = llVecNorm(axis);
768 // a rotation in an undesired direction. 918 double x, y, z, s, t;
769 if (LSL_Vector.Mag(orthoVector) > 0.0001) 919 s = Math.Cos(theta);
770 { 920 t = Math.Sin(theta);
771 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 921 x = axis.x * t;
772 } 922 y = axis.y * t;
773 // If the magnitude of the vector was near zero, then assume the X axis is not 923 z = axis.z * t;
774 // orthogonal and use the Z axis instead. 924 return new LSL_Rotation(x,y,z,s);
775 else
776 {
777 // Set 180 z rotation.
778 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
779 }
780 }
781 // Check for parallel vectors.
782 // A dot product of 1 would mean the angle between vectors is 0 degrees.
783 else if (dotProduct > 0.9999999f)
784 {
785 // Set zero rotation.
786 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
787 }
788 else
789 {
790 // All special checks have been performed so get the axis of rotation.
791 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
792 // Quarternion s value is the length of the unit vector + dot product.
793 double qs = 1.0 + dotProduct;
794 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
795 // Normalize the rotation.
796 double mag = LSL_Rotation.Mag(rotBetween);
797 // We shouldn't have to worry about a divide by zero here. The qs value will be
798 // non-zero because we already know if we're here, then the dotProduct is not -1 so
799 // qs will not be zero. Also, we've already handled the input vectors being zero so the
800 // crossProduct vector should also not be zero.
801 rotBetween.x = rotBetween.x / mag;
802 rotBetween.y = rotBetween.y / mag;
803 rotBetween.z = rotBetween.z / mag;
804 rotBetween.s = rotBetween.s / mag;
805 // Check for undefined values and set zero rotation if any found. This code might not actually be required
806 // any longer since zero vectors are checked for at the top.
807 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
808 {
809 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
810 }
811 }
812 } 925 }
813 return rotBetween;
814 } 926 }
815 927
816 public void llWhisper(int channelID, string text) 928 public void llWhisper(int channelID, string text)
817 { 929 {
818 m_host.AddScriptLPS(1); 930 m_host.AddScriptLPS(1);
@@ -828,10 +940,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
828 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 940 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
829 } 941 }
830 942
943 private void CheckSayShoutTime()
944 {
945 DateTime now = DateTime.UtcNow;
946 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
947 {
948 m_lastSayShoutCheck = now;
949 m_SayShoutCount = 0;
950 }
951 else
952 m_SayShoutCount++;
953 }
954
831 public void llSay(int channelID, string text) 955 public void llSay(int channelID, string text)
832 { 956 {
833 m_host.AddScriptLPS(1); 957 m_host.AddScriptLPS(1);
834 958
959 if (channelID == 0)
960// m_SayShoutCount++;
961 CheckSayShoutTime();
962
963 if (m_SayShoutCount >= 11)
964 ScriptSleep(2000);
965
835 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 966 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
836 { 967 {
837 Console.WriteLine(text); 968 Console.WriteLine(text);
@@ -854,6 +985,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
854 { 985 {
855 m_host.AddScriptLPS(1); 986 m_host.AddScriptLPS(1);
856 987
988 if (channelID == 0)
989// m_SayShoutCount++;
990 CheckSayShoutTime();
991
992 if (m_SayShoutCount >= 11)
993 ScriptSleep(2000);
994
857 if (text.Length > 1023) 995 if (text.Length > 1023)
858 text = text.Substring(0, 1023); 996 text = text.Substring(0, 1023);
859 997
@@ -885,22 +1023,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
885 1023
886 public void llRegionSayTo(string target, int channel, string msg) 1024 public void llRegionSayTo(string target, int channel, string msg)
887 { 1025 {
1026 string error = String.Empty;
1027
888 if (msg.Length > 1023) 1028 if (msg.Length > 1023)
889 msg = msg.Substring(0, 1023); 1029 msg = msg.Substring(0, 1023);
890 1030
891 m_host.AddScriptLPS(1); 1031 m_host.AddScriptLPS(1);
892 1032
893 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
894 {
895 return;
896 }
897
898 UUID TargetID; 1033 UUID TargetID;
899 UUID.TryParse(target, out TargetID); 1034 UUID.TryParse(target, out TargetID);
900 1035
901 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1036 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
902 if (wComm != null) 1037 if (wComm != null)
903 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1038 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1039 LSLError(error);
904 } 1040 }
905 1041
906 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1042 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1156,10 +1292,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1156 return detectedParams.TouchUV; 1292 return detectedParams.TouchUV;
1157 } 1293 }
1158 1294
1295 [DebuggerNonUserCode]
1159 public virtual void llDie() 1296 public virtual void llDie()
1160 { 1297 {
1161 m_host.AddScriptLPS(1); 1298 m_host.AddScriptLPS(1);
1162 throw new SelfDeleteException(); 1299 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1163 } 1300 }
1164 1301
1165 public LSL_Float llGround(LSL_Vector offset) 1302 public LSL_Float llGround(LSL_Vector offset)
@@ -1230,6 +1367,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1230 1367
1231 public void llSetStatus(int status, int value) 1368 public void llSetStatus(int status, int value)
1232 { 1369 {
1370 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1371 return;
1233 m_host.AddScriptLPS(1); 1372 m_host.AddScriptLPS(1);
1234 1373
1235 int statusrotationaxis = 0; 1374 int statusrotationaxis = 0;
@@ -1253,6 +1392,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1253 if (!allow) 1392 if (!allow)
1254 return; 1393 return;
1255 1394
1395 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1396 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1397 return;
1398
1256 m_host.ScriptSetPhysicsStatus(true); 1399 m_host.ScriptSetPhysicsStatus(true);
1257 } 1400 }
1258 else 1401 else
@@ -1453,6 +1596,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1453 { 1596 {
1454 m_host.AddScriptLPS(1); 1597 m_host.AddScriptLPS(1);
1455 1598
1599 SetColor(m_host, color, face);
1600 }
1601
1602 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1603 {
1604 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1605 return;
1606
1607 Primitive.TextureEntry tex = part.Shape.Textures;
1608 Color4 texcolor;
1609 if (face >= 0 && face < GetNumberOfSides(part))
1610 {
1611 texcolor = tex.CreateFace((uint)face).RGBA;
1612 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1613 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1614 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1615 tex.FaceTextures[face].RGBA = texcolor;
1616 part.UpdateTextureEntry(tex.GetBytes());
1617 return;
1618 }
1619 else if (face == ScriptBaseClass.ALL_SIDES)
1620 {
1621 for (uint i = 0; i < GetNumberOfSides(part); i++)
1622 {
1623 if (tex.FaceTextures[i] != null)
1624 {
1625 texcolor = tex.FaceTextures[i].RGBA;
1626 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1627 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1628 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1629 tex.FaceTextures[i].RGBA = texcolor;
1630 }
1631 texcolor = tex.DefaultTexture.RGBA;
1632 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1633 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1634 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1635 tex.DefaultTexture.RGBA = texcolor;
1636 }
1637 part.UpdateTextureEntry(tex.GetBytes());
1638 return;
1639 }
1640
1456 if (face == ScriptBaseClass.ALL_SIDES) 1641 if (face == ScriptBaseClass.ALL_SIDES)
1457 face = SceneObjectPart.ALL_SIDES; 1642 face = SceneObjectPart.ALL_SIDES;
1458 1643
@@ -1461,6 +1646,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1461 1646
1462 public void SetTexGen(SceneObjectPart part, int face,int style) 1647 public void SetTexGen(SceneObjectPart part, int face,int style)
1463 { 1648 {
1649 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1650 return;
1651
1464 Primitive.TextureEntry tex = part.Shape.Textures; 1652 Primitive.TextureEntry tex = part.Shape.Textures;
1465 MappingType textype; 1653 MappingType textype;
1466 textype = MappingType.Default; 1654 textype = MappingType.Default;
@@ -1491,6 +1679,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1491 1679
1492 public void SetGlow(SceneObjectPart part, int face, float glow) 1680 public void SetGlow(SceneObjectPart part, int face, float glow)
1493 { 1681 {
1682 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1683 return;
1684
1494 Primitive.TextureEntry tex = part.Shape.Textures; 1685 Primitive.TextureEntry tex = part.Shape.Textures;
1495 if (face >= 0 && face < GetNumberOfSides(part)) 1686 if (face >= 0 && face < GetNumberOfSides(part))
1496 { 1687 {
@@ -1516,6 +1707,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1516 1707
1517 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1708 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1518 { 1709 {
1710 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1711 return;
1519 1712
1520 Shininess sval = new Shininess(); 1713 Shininess sval = new Shininess();
1521 1714
@@ -1566,6 +1759,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1566 1759
1567 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1760 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1568 { 1761 {
1762 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1763 return;
1764
1569 Primitive.TextureEntry tex = part.Shape.Textures; 1765 Primitive.TextureEntry tex = part.Shape.Textures;
1570 if (face >= 0 && face < GetNumberOfSides(part)) 1766 if (face >= 0 && face < GetNumberOfSides(part))
1571 { 1767 {
@@ -1626,13 +1822,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1626 m_host.AddScriptLPS(1); 1822 m_host.AddScriptLPS(1);
1627 1823
1628 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1824 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1629 1825 if (parts.Count > 0)
1630 foreach (SceneObjectPart part in parts) 1826 {
1631 SetAlpha(part, alpha, face); 1827 try
1828 {
1829 foreach (SceneObjectPart part in parts)
1830 SetAlpha(part, alpha, face);
1831 }
1832 finally
1833 {
1834 }
1835 }
1632 } 1836 }
1633 1837
1634 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1838 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1635 { 1839 {
1840 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1841 return;
1842
1636 Primitive.TextureEntry tex = part.Shape.Textures; 1843 Primitive.TextureEntry tex = part.Shape.Textures;
1637 Color4 texcolor; 1844 Color4 texcolor;
1638 if (face >= 0 && face < GetNumberOfSides(part)) 1845 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1685,7 +1892,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1685 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1892 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1686 float wind, float tension, LSL_Vector Force) 1893 float wind, float tension, LSL_Vector Force)
1687 { 1894 {
1688 if (part == null) 1895 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1689 return; 1896 return;
1690 1897
1691 if (flexi) 1898 if (flexi)
@@ -1719,7 +1926,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1719 /// <param name="falloff"></param> 1926 /// <param name="falloff"></param>
1720 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1927 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1721 { 1928 {
1722 if (part == null) 1929 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1723 return; 1930 return;
1724 1931
1725 if (light) 1932 if (light)
@@ -1752,11 +1959,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1752 Primitive.TextureEntry tex = part.Shape.Textures; 1959 Primitive.TextureEntry tex = part.Shape.Textures;
1753 Color4 texcolor; 1960 Color4 texcolor;
1754 LSL_Vector rgb = new LSL_Vector(); 1961 LSL_Vector rgb = new LSL_Vector();
1962 int nsides = GetNumberOfSides(part);
1963
1755 if (face == ScriptBaseClass.ALL_SIDES) 1964 if (face == ScriptBaseClass.ALL_SIDES)
1756 { 1965 {
1757 int i; 1966 int i;
1758 1967 for (i = 0; i < nsides; i++)
1759 for (i = 0 ; i < GetNumberOfSides(part); i++)
1760 { 1968 {
1761 texcolor = tex.GetFace((uint)i).RGBA; 1969 texcolor = tex.GetFace((uint)i).RGBA;
1762 rgb.x += texcolor.R; 1970 rgb.x += texcolor.R;
@@ -1764,14 +1972,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1764 rgb.z += texcolor.B; 1972 rgb.z += texcolor.B;
1765 } 1973 }
1766 1974
1767 rgb.x /= (float)GetNumberOfSides(part); 1975 float invnsides = 1.0f / (float)nsides;
1768 rgb.y /= (float)GetNumberOfSides(part); 1976
1769 rgb.z /= (float)GetNumberOfSides(part); 1977 rgb.x *= invnsides;
1978 rgb.y *= invnsides;
1979 rgb.z *= invnsides;
1770 1980
1771 return rgb; 1981 return rgb;
1772 } 1982 }
1773 1983 if (face >= 0 && face < nsides)
1774 if (face >= 0 && face < GetNumberOfSides(part))
1775 { 1984 {
1776 texcolor = tex.GetFace((uint)face).RGBA; 1985 texcolor = tex.GetFace((uint)face).RGBA;
1777 rgb.x = texcolor.R; 1986 rgb.x = texcolor.R;
@@ -1798,15 +2007,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1798 m_host.AddScriptLPS(1); 2007 m_host.AddScriptLPS(1);
1799 2008
1800 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2009 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1801 2010 if (parts.Count > 0)
1802 foreach (SceneObjectPart part in parts) 2011 {
1803 SetTexture(part, texture, face); 2012 try
1804 2013 {
2014 foreach (SceneObjectPart part in parts)
2015 SetTexture(part, texture, face);
2016 }
2017 finally
2018 {
2019 }
2020 }
1805 ScriptSleep(200); 2021 ScriptSleep(200);
1806 } 2022 }
1807 2023
1808 protected void SetTexture(SceneObjectPart part, string texture, int face) 2024 protected void SetTexture(SceneObjectPart part, string texture, int face)
1809 { 2025 {
2026 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2027 return;
2028
1810 UUID textureID = new UUID(); 2029 UUID textureID = new UUID();
1811 2030
1812 textureID = InventoryKey(texture, (int)AssetType.Texture); 2031 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1851,6 +2070,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1851 2070
1852 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2071 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1853 { 2072 {
2073 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2074 return;
2075
1854 Primitive.TextureEntry tex = part.Shape.Textures; 2076 Primitive.TextureEntry tex = part.Shape.Textures;
1855 if (face >= 0 && face < GetNumberOfSides(part)) 2077 if (face >= 0 && face < GetNumberOfSides(part))
1856 { 2078 {
@@ -1887,6 +2109,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1887 2109
1888 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2110 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1889 { 2111 {
2112 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2113 return;
2114
1890 Primitive.TextureEntry tex = part.Shape.Textures; 2115 Primitive.TextureEntry tex = part.Shape.Textures;
1891 if (face >= 0 && face < GetNumberOfSides(part)) 2116 if (face >= 0 && face < GetNumberOfSides(part))
1892 { 2117 {
@@ -1923,6 +2148,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1923 2148
1924 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2149 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1925 { 2150 {
2151 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2152 return;
2153
1926 Primitive.TextureEntry tex = part.Shape.Textures; 2154 Primitive.TextureEntry tex = part.Shape.Textures;
1927 if (face >= 0 && face < GetNumberOfSides(part)) 2155 if (face >= 0 && face < GetNumberOfSides(part))
1928 { 2156 {
@@ -2064,7 +2292,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2064 return end; 2292 return end;
2065 } 2293 }
2066 2294
2067 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2295 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2068 { 2296 {
2069 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2297 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2070 return fromPos; 2298 return fromPos;
@@ -2080,9 +2308,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2080 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2308 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2081 targetPos.z = ground; 2309 targetPos.z = ground;
2082 } 2310 }
2083 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2311 if (adjust)
2312 return SetPosAdjust(fromPos, targetPos);
2084 2313
2085 return real_vec; 2314 return targetPos;
2086 } 2315 }
2087 2316
2088 /// <summary> 2317 /// <summary>
@@ -2093,27 +2322,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2093 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2322 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2094 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2323 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2095 { 2324 {
2096 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2325 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2326 return;
2327
2097 LSL_Vector currentPos = GetPartLocalPos(part); 2328 LSL_Vector currentPos = GetPartLocalPos(part);
2329 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2098 2330
2099 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2100 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2101 2331
2102 if (part.ParentGroup.RootPart == part) 2332 if (part.ParentGroup.RootPart == part)
2103 { 2333 {
2104 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2105 targetPos.z = ground;
2106 SceneObjectGroup parent = part.ParentGroup; 2334 SceneObjectGroup parent = part.ParentGroup;
2107 parent.UpdateGroupPosition(!adjust ? targetPos : 2335 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2108 SetPosAdjust(currentPos, targetPos)); 2336 return;
2337 Util.FireAndForget(delegate(object x) {
2338 parent.UpdateGroupPosition((Vector3)toPos);
2339 });
2109 } 2340 }
2110 else 2341 else
2111 { 2342 {
2112 part.OffsetPosition = !adjust ? targetPos : 2343 part.OffsetPosition = (Vector3)toPos;
2113 SetPosAdjust(currentPos, targetPos); 2344// SceneObjectGroup parent = part.ParentGroup;
2114 SceneObjectGroup parent = part.ParentGroup; 2345// parent.HasGroupChanged = true;
2115 parent.HasGroupChanged = true; 2346// parent.ScheduleGroupForTerseUpdate();
2116 parent.ScheduleGroupForTerseUpdate(); 2347 part.ScheduleTerseUpdate();
2117 } 2348 }
2118 } 2349 }
2119 2350
@@ -2142,13 +2373,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2142 else 2373 else
2143 { 2374 {
2144 if (part.ParentGroup.IsAttachment) 2375 if (part.ParentGroup.IsAttachment)
2145 {
2146 pos = part.AttachedPos; 2376 pos = part.AttachedPos;
2147 }
2148 else 2377 else
2149 {
2150 pos = part.AbsolutePosition; 2378 pos = part.AbsolutePosition;
2151 }
2152 } 2379 }
2153 2380
2154// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2381// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2160,8 +2387,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2160 { 2387 {
2161 m_host.AddScriptLPS(1); 2388 m_host.AddScriptLPS(1);
2162 2389
2390
2391 // Teravus: if (m_host.ParentID == 0) is bug code because the ParentID for the Avatar will cause this to be nonzero for root prim attachments
2392 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2393 // to fix the scripted rotations we also have to check to see if the root part localid is the same as the host's localid.
2394 // RootPart != null should shortcircuit
2395
2163 // try to let this work as in SL... 2396 // try to let this work as in SL...
2164 if (m_host.ParentID == 0) 2397 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2165 { 2398 {
2166 // special case: If we are root, rotate complete SOG to new rotation 2399 // special case: If we are root, rotate complete SOG to new rotation
2167 SetRot(m_host, rot); 2400 SetRot(m_host, rot);
@@ -2188,25 +2421,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2188 2421
2189 protected void SetRot(SceneObjectPart part, Quaternion rot) 2422 protected void SetRot(SceneObjectPart part, Quaternion rot)
2190 { 2423 {
2191 part.UpdateRotation(rot); 2424 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2192 // Update rotation does not move the object in the physics scene if it's a linkset. 2425 return;
2193 2426
2194//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2427 bool isroot = (part == part.ParentGroup.RootPart);
2195// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2428 bool isphys;
2196 2429
2197 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2198 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2199 // It's perfectly okay when the object is not an active physical body though.
2200 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2201 // but only if the object is not physial and active. This is important for rotating doors.
2202 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2203 // scene
2204 PhysicsActor pa = part.PhysActor; 2430 PhysicsActor pa = part.PhysActor;
2205 2431
2206 if (pa != null && !pa.IsPhysical) 2432 // keep using physactor ideia of isphysical
2433 // it should be SOP ideia of that
2434 // not much of a issue with ubitODE
2435 if (pa != null && pa.IsPhysical)
2436 isphys = true;
2437 else
2438 isphys = false;
2439
2440 // SL doesn't let scripts rotate root of physical linksets
2441 if (isroot && isphys)
2442 return;
2443
2444 part.UpdateRotation(rot);
2445
2446 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2447 // so do a nasty update of parts positions if is a root part rotation
2448 if (isroot && pa != null) // with if above implies non physical root part
2207 { 2449 {
2208 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2450 part.ParentGroup.ResetChildPrimPhysicsPositions();
2209 } 2451 }
2452 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2453 {
2454 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2455 if (sittingavas.Count > 0)
2456 {
2457 foreach (ScenePresence av in sittingavas)
2458 {
2459 if (isroot || part.LocalId == av.ParentID)
2460 av.SendTerseUpdateToAllClients();
2461 }
2462 }
2463 }
2210 } 2464 }
2211 2465
2212 /// <summary> 2466 /// <summary>
@@ -2223,6 +2477,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2223 2477
2224 m_host.AddScriptLPS(1); 2478 m_host.AddScriptLPS(1);
2225 Quaternion q = m_host.GetWorldRotation(); 2479 Quaternion q = m_host.GetWorldRotation();
2480
2481 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2482 {
2483 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2484 if (avatar != null)
2485 {
2486 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2487 q = avatar.CameraRotation * q; // Mouselook
2488 else
2489 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2490 }
2491 }
2492
2226 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2493 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2227 } 2494 }
2228 2495
@@ -2248,14 +2515,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2248 q = part.ParentGroup.GroupRotation; // just the group rotation 2515 q = part.ParentGroup.GroupRotation; // just the group rotation
2249 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2516 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2250 } 2517 }
2518
2251 q = part.GetWorldRotation(); 2519 q = part.GetWorldRotation();
2520 if (part.ParentGroup.AttachmentPoint != 0)
2521 {
2522 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2523 if (avatar != null)
2524 {
2525 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2526 q = avatar.CameraRotation * q; // Mouselook
2527 else
2528 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2529 }
2530 }
2531
2252 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2532 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2253 } 2533 }
2254 2534
2255 public LSL_Rotation llGetLocalRot() 2535 public LSL_Rotation llGetLocalRot()
2256 { 2536 {
2537 return GetPartLocalRot(m_host);
2538 }
2539
2540 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2541 {
2257 m_host.AddScriptLPS(1); 2542 m_host.AddScriptLPS(1);
2258 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2543 Quaternion rot = part.RotationOffset;
2544 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2259 } 2545 }
2260 2546
2261 public void llSetForce(LSL_Vector force, int local) 2547 public void llSetForce(LSL_Vector force, int local)
@@ -2335,16 +2621,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2335 m_host.ApplyImpulse(v, local != 0); 2621 m_host.ApplyImpulse(v, local != 0);
2336 } 2622 }
2337 2623
2624
2338 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2625 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2339 { 2626 {
2340 m_host.AddScriptLPS(1); 2627 m_host.AddScriptLPS(1);
2341 m_host.ApplyAngularImpulse(force, local != 0); 2628 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2342 } 2629 }
2343 2630
2344 public void llSetTorque(LSL_Vector torque, int local) 2631 public void llSetTorque(LSL_Vector torque, int local)
2345 { 2632 {
2346 m_host.AddScriptLPS(1); 2633 m_host.AddScriptLPS(1);
2347 m_host.SetAngularImpulse(torque, local != 0); 2634 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2348 } 2635 }
2349 2636
2350 public LSL_Vector llGetTorque() 2637 public LSL_Vector llGetTorque()
@@ -2361,20 +2648,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2361 llSetTorque(torque, local); 2648 llSetTorque(torque, local);
2362 } 2649 }
2363 2650
2651 public void llSetVelocity(LSL_Vector vel, int local)
2652 {
2653 m_host.AddScriptLPS(1);
2654 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2655 }
2656
2364 public LSL_Vector llGetVel() 2657 public LSL_Vector llGetVel()
2365 { 2658 {
2366 m_host.AddScriptLPS(1); 2659 m_host.AddScriptLPS(1);
2367 2660
2368 Vector3 vel; 2661 Vector3 vel = Vector3.Zero;
2369 2662
2370 if (m_host.ParentGroup.IsAttachment) 2663 if (m_host.ParentGroup.IsAttachment)
2371 { 2664 {
2372 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2665 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2373 vel = avatar.Velocity; 2666 if (avatar != null)
2667 vel = avatar.Velocity;
2374 } 2668 }
2375 else 2669 else
2376 { 2670 {
2377 vel = m_host.Velocity; 2671 vel = m_host.ParentGroup.RootPart.Velocity;
2378 } 2672 }
2379 2673
2380 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2674 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2386,10 +2680,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2386 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2680 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2387 } 2681 }
2388 2682
2683 public void llSetAngularVelocity(LSL_Vector avel, int local)
2684 {
2685 m_host.AddScriptLPS(1);
2686 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2687 }
2688
2389 public LSL_Vector llGetOmega() 2689 public LSL_Vector llGetOmega()
2390 { 2690 {
2391 m_host.AddScriptLPS(1); 2691 m_host.AddScriptLPS(1);
2392 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2692 Vector3 avel = m_host.AngularVelocity;
2693 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2393 } 2694 }
2394 2695
2395 public LSL_Float llGetTimeOfDay() 2696 public LSL_Float llGetTimeOfDay()
@@ -2748,7 +3049,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2748 return src.ToLower(); 3049 return src.ToLower();
2749 } 3050 }
2750 3051
2751 public void llGiveMoney(string destination, int amount) 3052 public LSL_Integer llGiveMoney(string destination, int amount)
2752 { 3053 {
2753 Util.FireAndForget(x => 3054 Util.FireAndForget(x =>
2754 { 3055 {
@@ -2780,8 +3081,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2780 } 3081 }
2781 3082
2782 money.ObjectGiveMoney( 3083 money.ObjectGiveMoney(
2783 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3084 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2784 }); 3085 });
3086
3087 return 0;
2785 } 3088 }
2786 3089
2787 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3090 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -2860,13 +3163,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2860 new_group.RootPart.UUID.ToString()) }, 3163 new_group.RootPart.UUID.ToString()) },
2861 new DetectParams[0])); 3164 new DetectParams[0]));
2862 3165
2863 float groupmass = new_group.GetMass(); 3166 // do recoil
3167 SceneObjectGroup hostgrp = m_host.ParentGroup;
3168 if (hostgrp == null)
3169 return;
3170
3171 if (hostgrp.IsAttachment) // don't recoil avatars
3172 return;
2864 3173
2865 PhysicsActor pa = new_group.RootPart.PhysActor; 3174 PhysicsActor pa = new_group.RootPart.PhysActor;
2866 3175
2867 //Recoil. 3176 //Recoil.
2868 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3177 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2869 { 3178 {
3179 float groupmass = new_group.GetMass();
2870 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3180 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2871 if (recoil != Vector3.Zero) 3181 if (recoil != Vector3.Zero)
2872 { 3182 {
@@ -2874,6 +3184,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2874 } 3184 }
2875 } 3185 }
2876 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3186 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3187 return;
3188
2877 }); 3189 });
2878 3190
2879 //ScriptSleep((int)((groupmass * velmag) / 10)); 3191 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2888,35 +3200,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2888 public void llLookAt(LSL_Vector target, double strength, double damping) 3200 public void llLookAt(LSL_Vector target, double strength, double damping)
2889 { 3201 {
2890 m_host.AddScriptLPS(1); 3202 m_host.AddScriptLPS(1);
2891 // Determine where we are looking from
2892 LSL_Vector from = llGetPos();
2893 3203
2894 // Work out the normalised vector from the source to the target 3204 // Get the normalized vector to the target
2895 LSL_Vector delta = llVecNorm(target - from); 3205 LSL_Vector d1 = llVecNorm(target - llGetPos());
2896 LSL_Vector angle = new LSL_Vector(0,0,0);
2897 3206
2898 // Calculate the yaw 3207 // Get the bearing (yaw)
2899 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3208 LSL_Vector a1 = new LSL_Vector(0,0,0);
2900 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3209 a1.z = llAtan2(d1.y, d1.x);
2901 3210
2902 // Calculate pitch 3211 // Get the elevation (pitch)
2903 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3212 LSL_Vector a2 = new LSL_Vector(0,0,0);
3213 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2904 3214
2905 // we need to convert from a vector describing 3215 LSL_Rotation r1 = llEuler2Rot(a1);
2906 // the angles of rotation in radians into rotation value 3216 LSL_Rotation r2 = llEuler2Rot(a2);
2907 LSL_Rotation rot = llEuler2Rot(angle); 3217 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2908
2909 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2910 // set the rotation of the object, copy that behavior
2911 PhysicsActor pa = m_host.PhysActor;
2912 3218
2913 if (strength == 0 || pa == null || !pa.IsPhysical) 3219 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2914 { 3220 {
2915 llSetRot(rot); 3221 // Do nothing if either value is 0 (this has been checked in SL)
3222 if (strength <= 0.0 || damping <= 0.0)
3223 return;
3224
3225 llSetRot(r3 * r2 * r1);
2916 } 3226 }
2917 else 3227 else
2918 { 3228 {
2919 m_host.StartLookAt(rot, (float)strength, (float)damping); 3229 if (strength == 0)
3230 {
3231 llSetRot(r3 * r2 * r1);
3232 return;
3233 }
3234
3235 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2920 } 3236 }
2921 } 3237 }
2922 3238
@@ -2963,17 +3279,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2963 } 3279 }
2964 else 3280 else
2965 { 3281 {
2966 if (m_host.IsRoot) 3282 // new SL always returns object mass
2967 { 3283// if (m_host.IsRoot)
3284// {
2968 return m_host.ParentGroup.GetMass(); 3285 return m_host.ParentGroup.GetMass();
2969 } 3286// }
2970 else 3287// else
2971 { 3288// {
2972 return m_host.GetMass(); 3289// return m_host.GetMass();
2973 } 3290// }
2974 } 3291 }
2975 } 3292 }
2976 3293
3294
3295 public LSL_Float llGetMassMKS()
3296 {
3297 return 100f * llGetMass();
3298 }
3299
2977 public void llCollisionFilter(string name, string id, int accept) 3300 public void llCollisionFilter(string name, string id, int accept)
2978 { 3301 {
2979 m_host.AddScriptLPS(1); 3302 m_host.AddScriptLPS(1);
@@ -3021,8 +3344,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3021 { 3344 {
3022 // Unregister controls from Presence 3345 // Unregister controls from Presence
3023 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3346 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3024 // Remove Take Control permission.
3025 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3026 } 3347 }
3027 } 3348 }
3028 } 3349 }
@@ -3050,7 +3371,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3050 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3371 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3051 3372
3052 if (attachmentsModule != null) 3373 if (attachmentsModule != null)
3053 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3374 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3054 else 3375 else
3055 return false; 3376 return false;
3056 } 3377 }
@@ -3080,9 +3401,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3080 { 3401 {
3081 m_host.AddScriptLPS(1); 3402 m_host.AddScriptLPS(1);
3082 3403
3083// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3084// return;
3085
3086 if (m_item.PermsGranter != m_host.OwnerID) 3404 if (m_item.PermsGranter != m_host.OwnerID)
3087 return; 3405 return;
3088 3406
@@ -3125,6 +3443,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3125 3443
3126 public void llInstantMessage(string user, string message) 3444 public void llInstantMessage(string user, string message)
3127 { 3445 {
3446 UUID result;
3447 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3448 {
3449 ShoutError("An invalid key was passed to llInstantMessage");
3450 ScriptSleep(2000);
3451 return;
3452 }
3453
3454
3128 m_host.AddScriptLPS(1); 3455 m_host.AddScriptLPS(1);
3129 3456
3130 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3457 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3139,14 +3466,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3139 UUID friendTransactionID = UUID.Random(); 3466 UUID friendTransactionID = UUID.Random();
3140 3467
3141 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3468 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3142 3469
3143 GridInstantMessage msg = new GridInstantMessage(); 3470 GridInstantMessage msg = new GridInstantMessage();
3144 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3471 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3145 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3472 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3146 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3473 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3147// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3474// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3148// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3475// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3149 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3476// DateTime dt = DateTime.UtcNow;
3477//
3478// // Ticks from UtcNow, but make it look like local. Evil, huh?
3479// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3480//
3481// try
3482// {
3483// // Convert that to the PST timezone
3484// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3485// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3486// }
3487// catch
3488// {
3489// // No logging here, as it could be VERY spammy
3490// }
3491//
3492// // And make it look local again to fool the unix time util
3493// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3494
3495 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3496
3150 //if (client != null) 3497 //if (client != null)
3151 //{ 3498 //{
3152 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3499 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3160,12 +3507,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3160 msg.message = message.Substring(0, 1024); 3507 msg.message = message.Substring(0, 1024);
3161 else 3508 else
3162 msg.message = message; 3509 msg.message = message;
3163 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3510 msg.dialog = (byte)19; // MessageFromObject
3164 msg.fromGroup = false;// fromGroup; 3511 msg.fromGroup = false;// fromGroup;
3165 msg.offline = (byte)0; //offline; 3512 msg.offline = (byte)0; //offline;
3166 msg.ParentEstateID = 0; //ParentEstateID; 3513 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3167 msg.Position = new Vector3(m_host.AbsolutePosition); 3514 msg.Position = new Vector3(m_host.AbsolutePosition);
3168 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3515 msg.RegionID = World.RegionInfo.RegionID.Guid;
3169 msg.binaryBucket 3516 msg.binaryBucket
3170 = Util.StringToBytes256( 3517 = Util.StringToBytes256(
3171 "{0}/{1}/{2}/{3}", 3518 "{0}/{1}/{2}/{3}",
@@ -3193,7 +3540,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3193 } 3540 }
3194 3541
3195 emailModule.SendEmail(m_host.UUID, address, subject, message); 3542 emailModule.SendEmail(m_host.UUID, address, subject, message);
3196 llSleep(EMAIL_PAUSE_TIME); 3543 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3197 } 3544 }
3198 3545
3199 public void llGetNextEmail(string address, string subject) 3546 public void llGetNextEmail(string address, string subject)
@@ -3439,7 +3786,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3439 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3786 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3440 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3787 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3441 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3788 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3789 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3442 ScriptBaseClass.PERMISSION_ATTACH; 3790 ScriptBaseClass.PERMISSION_ATTACH;
3791
3443 } 3792 }
3444 else 3793 else
3445 { 3794 {
@@ -3456,15 +3805,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3456 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3805 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3457 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3806 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3458 } 3807 }
3808 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3809 {
3810 implicitPerms = perm;
3811 }
3459 } 3812 }
3460 3813
3461 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3814 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3462 { 3815 {
3463 lock (m_host.TaskInventory) 3816 m_host.TaskInventory.LockItemsForWrite(true);
3464 { 3817 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3465 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3818 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3466 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3819 m_host.TaskInventory.LockItemsForWrite(false);
3467 }
3468 3820
3469 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3821 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3470 "run_time_permissions", new Object[] { 3822 "run_time_permissions", new Object[] {
@@ -3507,11 +3859,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3507 3859
3508 if (!m_waitingForScriptAnswer) 3860 if (!m_waitingForScriptAnswer)
3509 { 3861 {
3510 lock (m_host.TaskInventory) 3862 m_host.TaskInventory.LockItemsForWrite(true);
3511 { 3863 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3512 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3864 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3513 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3865 m_host.TaskInventory.LockItemsForWrite(false);
3514 }
3515 3866
3516 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3867 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3517 m_waitingForScriptAnswer=true; 3868 m_waitingForScriptAnswer=true;
@@ -3540,14 +3891,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3540 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3891 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3541 llReleaseControls(); 3892 llReleaseControls();
3542 3893
3543 lock (m_host.TaskInventory) 3894 m_host.TaskInventory.LockItemsForWrite(true);
3544 { 3895 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3545 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3896 m_host.TaskInventory.LockItemsForWrite(false);
3546 } 3897
3547 3898 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3548 m_ScriptEngine.PostScriptEvent( 3899 "run_time_permissions", new Object[] {
3549 m_item.ItemID, 3900 new LSL_Integer(answer) },
3550 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3901 new DetectParams[0]));
3551 } 3902 }
3552 3903
3553 public LSL_String llGetPermissionsKey() 3904 public LSL_String llGetPermissionsKey()
@@ -3586,14 +3937,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3586 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3937 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3587 { 3938 {
3588 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3939 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3589 3940 if (parts.Count > 0)
3590 foreach (SceneObjectPart part in parts) 3941 {
3591 part.SetFaceColorAlpha(face, color, null); 3942 try
3943 {
3944 foreach (SceneObjectPart part in parts)
3945 part.SetFaceColorAlpha(face, color, null);
3946 }
3947 finally
3948 {
3949 }
3950 }
3592 } 3951 }
3593 3952
3594 public void llCreateLink(string target, int parent) 3953 public void llCreateLink(string target, int parent)
3595 { 3954 {
3596 m_host.AddScriptLPS(1); 3955 m_host.AddScriptLPS(1);
3956
3597 UUID targetID; 3957 UUID targetID;
3598 3958
3599 if (!UUID.TryParse(target, out targetID)) 3959 if (!UUID.TryParse(target, out targetID))
@@ -3699,10 +4059,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3699 // Restructuring Multiple Prims. 4059 // Restructuring Multiple Prims.
3700 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4060 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3701 parts.Remove(parentPrim.RootPart); 4061 parts.Remove(parentPrim.RootPart);
3702 foreach (SceneObjectPart part in parts) 4062 if (parts.Count > 0)
3703 { 4063 {
3704 parentPrim.DelinkFromGroup(part.LocalId, true); 4064 try
4065 {
4066 foreach (SceneObjectPart part in parts)
4067 {
4068 parentPrim.DelinkFromGroup(part.LocalId, true);
4069 }
4070 }
4071 finally
4072 {
4073 }
3705 } 4074 }
4075
3706 parentPrim.HasGroupChanged = true; 4076 parentPrim.HasGroupChanged = true;
3707 parentPrim.ScheduleGroupForFullUpdate(); 4077 parentPrim.ScheduleGroupForFullUpdate();
3708 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4078 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3711,12 +4081,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3711 { 4081 {
3712 SceneObjectPart newRoot = parts[0]; 4082 SceneObjectPart newRoot = parts[0];
3713 parts.Remove(newRoot); 4083 parts.Remove(newRoot);
3714 foreach (SceneObjectPart part in parts) 4084
4085 try
3715 { 4086 {
3716 // Required for linking 4087 foreach (SceneObjectPart part in parts)
3717 part.ClearUpdateSchedule(); 4088 {
3718 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4089 part.ClearUpdateSchedule();
4090 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4091 }
3719 } 4092 }
4093 finally
4094 {
4095 }
4096
4097
3720 newRoot.ParentGroup.HasGroupChanged = true; 4098 newRoot.ParentGroup.HasGroupChanged = true;
3721 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4099 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3722 } 4100 }
@@ -3736,6 +4114,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3736 public void llBreakAllLinks() 4114 public void llBreakAllLinks()
3737 { 4115 {
3738 m_host.AddScriptLPS(1); 4116 m_host.AddScriptLPS(1);
4117
4118 TaskInventoryItem item = m_item;
4119
4120 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4121 && !m_automaticLinkPermission)
4122 {
4123 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4124 return;
4125 }
4126
3739 SceneObjectGroup parentPrim = m_host.ParentGroup; 4127 SceneObjectGroup parentPrim = m_host.ParentGroup;
3740 if (parentPrim.AttachmentPoint != 0) 4128 if (parentPrim.AttachmentPoint != 0)
3741 return; // Fail silently if attached 4129 return; // Fail silently if attached
@@ -3755,47 +4143,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3755 public LSL_String llGetLinkKey(int linknum) 4143 public LSL_String llGetLinkKey(int linknum)
3756 { 4144 {
3757 m_host.AddScriptLPS(1); 4145 m_host.AddScriptLPS(1);
3758 4146 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3759 if (linknum < 0) 4147 if (part != null)
3760 {
3761 if (linknum == ScriptBaseClass.LINK_THIS)
3762 return m_host.UUID.ToString();
3763 else
3764 return ScriptBaseClass.NULL_KEY;
3765 }
3766
3767 int actualPrimCount = m_host.ParentGroup.PrimCount;
3768 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
3769 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
3770
3771 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
3772 // prim that has any avatars sat upon it (in which case the root prim is link 1).
3773 if (linknum == 0)
3774 {
3775 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
3776 return m_host.UUID.ToString();
3777
3778 return ScriptBaseClass.NULL_KEY;
3779 }
3780 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
3781 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
3782 else if (linknum == 1 && actualPrimCount == 1)
3783 {
3784 if (sittingAvatarIds.Count > 0)
3785 return m_host.ParentGroup.RootPart.UUID.ToString();
3786 else
3787 return ScriptBaseClass.NULL_KEY;
3788 }
3789 else if (linknum <= adjustedPrimCount)
3790 { 4148 {
3791 if (linknum <= actualPrimCount) 4149 return part.UUID.ToString();
3792 return m_host.ParentGroup.GetLinkNumPart(linknum).UUID.ToString();
3793 else
3794 return sittingAvatarIds[linknum - actualPrimCount - 1].ToString();
3795 } 4150 }
3796 else 4151 else
3797 { 4152 {
3798 return ScriptBaseClass.NULL_KEY; 4153 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4154 {
4155 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4156
4157 if (linknum < 0)
4158 return UUID.Zero.ToString();
4159
4160 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4161 if (avatars.Count > linknum)
4162 {
4163 return avatars[linknum].UUID.ToString();
4164 }
4165 }
4166 return UUID.Zero.ToString();
3799 } 4167 }
3800 } 4168 }
3801 4169
@@ -3898,17 +4266,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3898 m_host.AddScriptLPS(1); 4266 m_host.AddScriptLPS(1);
3899 int count = 0; 4267 int count = 0;
3900 4268
3901 lock (m_host.TaskInventory) 4269 m_host.TaskInventory.LockItemsForRead(true);
4270 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3902 { 4271 {
3903 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4272 if (inv.Value.Type == type || type == -1)
3904 { 4273 {
3905 if (inv.Value.Type == type || type == -1) 4274 count = count + 1;
3906 {
3907 count = count + 1;
3908 }
3909 } 4275 }
3910 } 4276 }
3911 4277
4278 m_host.TaskInventory.LockItemsForRead(false);
3912 return count; 4279 return count;
3913 } 4280 }
3914 4281
@@ -3917,16 +4284,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3917 m_host.AddScriptLPS(1); 4284 m_host.AddScriptLPS(1);
3918 ArrayList keys = new ArrayList(); 4285 ArrayList keys = new ArrayList();
3919 4286
3920 lock (m_host.TaskInventory) 4287 m_host.TaskInventory.LockItemsForRead(true);
4288 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3921 { 4289 {
3922 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4290 if (inv.Value.Type == type || type == -1)
3923 { 4291 {
3924 if (inv.Value.Type == type || type == -1) 4292 keys.Add(inv.Value.Name);
3925 {
3926 keys.Add(inv.Value.Name);
3927 }
3928 } 4293 }
3929 } 4294 }
4295 m_host.TaskInventory.LockItemsForRead(false);
3930 4296
3931 if (keys.Count == 0) 4297 if (keys.Count == 0)
3932 { 4298 {
@@ -3964,7 +4330,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3964 if (item == null) 4330 if (item == null)
3965 { 4331 {
3966 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4332 llSay(0, String.Format("Could not find object '{0}'", inventory));
3967 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4333 return;
4334// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3968 } 4335 }
3969 4336
3970 UUID objId = item.ItemID; 4337 UUID objId = item.ItemID;
@@ -3992,33 +4359,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3992 return; 4359 return;
3993 } 4360 }
3994 } 4361 }
4362
3995 // destination is an avatar 4363 // destination is an avatar
3996 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4364 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3997 4365
3998 if (agentItem == null) 4366 if (agentItem == null)
3999 return; 4367 return;
4000 4368
4001 if (m_TransferModule != null) 4369 byte[] bucket = new byte[1];
4002 { 4370 bucket[0] = (byte)item.Type;
4003 byte[] bucket = new byte[1]; 4371 //byte[] objBytes = agentItem.ID.GetBytes();
4004 bucket[0] = (byte)item.Type; 4372 //Array.Copy(objBytes, 0, bucket, 1, 16);
4373
4374 GridInstantMessage msg = new GridInstantMessage(World,
4375 m_host.OwnerID, m_host.Name, destId,
4376 (byte)InstantMessageDialog.TaskInventoryOffered,
4377 false, item.Name+". "+m_host.Name+" is located at "+
4378 World.RegionInfo.RegionName+" "+
4379 m_host.AbsolutePosition.ToString(),
4380 agentItem.ID, true, m_host.AbsolutePosition,
4381 bucket, true);
4005 4382
4006 GridInstantMessage msg = new GridInstantMessage(World, 4383 ScenePresence sp;
4007 m_host.OwnerID, m_host.Name, destId,
4008 (byte)InstantMessageDialog.TaskInventoryOffered,
4009 false, item.Name+". "+m_host.Name+" is located at "+
4010 World.RegionInfo.RegionName+" "+
4011 m_host.AbsolutePosition.ToString(),
4012 agentItem.ID, true, m_host.AbsolutePosition,
4013 bucket, true);
4014 4384
4015 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4385 if (World.TryGetScenePresence(destId, out sp))
4386 {
4387 sp.ControllingClient.SendInstantMessage(msg);
4016 } 4388 }
4017 4389 else
4390 {
4391 if (m_TransferModule != null)
4392 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4393 }
4394
4395 //This delay should only occur when giving inventory to avatars.
4018 ScriptSleep(3000); 4396 ScriptSleep(3000);
4019 } 4397 }
4020 } 4398 }
4021 4399
4400 [DebuggerNonUserCode]
4022 public void llRemoveInventory(string name) 4401 public void llRemoveInventory(string name)
4023 { 4402 {
4024 m_host.AddScriptLPS(1); 4403 m_host.AddScriptLPS(1);
@@ -4073,109 +4452,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4073 { 4452 {
4074 m_host.AddScriptLPS(1); 4453 m_host.AddScriptLPS(1);
4075 4454
4076 UUID uuid = (UUID)id; 4455 UUID uuid;
4077 PresenceInfo pinfo = null; 4456 if (UUID.TryParse(id, out uuid))
4078 UserAccount account;
4079
4080 UserInfoCacheEntry ce;
4081 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4082 { 4457 {
4083 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4458 PresenceInfo pinfo = null;
4084 if (account == null) 4459 UserAccount account;
4460
4461 UserInfoCacheEntry ce;
4462 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4085 { 4463 {
4086 m_userInfoCache[uuid] = null; // Cache negative 4464 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4087 return UUID.Zero.ToString(); 4465 if (account == null)
4088 } 4466 {
4467 m_userInfoCache[uuid] = null; // Cache negative
4468 return UUID.Zero.ToString();
4469 }
4089 4470
4090 4471
4091 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4472 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4092 if (pinfos != null && pinfos.Length > 0) 4473 if (pinfos != null && pinfos.Length > 0)
4093 {
4094 foreach (PresenceInfo p in pinfos)
4095 { 4474 {
4096 if (p.RegionID != UUID.Zero) 4475 foreach (PresenceInfo p in pinfos)
4097 { 4476 {
4098 pinfo = p; 4477 if (p.RegionID != UUID.Zero)
4478 {
4479 pinfo = p;
4480 }
4099 } 4481 }
4100 } 4482 }
4101 }
4102 4483
4103 ce = new UserInfoCacheEntry(); 4484 ce = new UserInfoCacheEntry();
4104 ce.time = Util.EnvironmentTickCount(); 4485 ce.time = Util.EnvironmentTickCount();
4105 ce.account = account; 4486 ce.account = account;
4106 ce.pinfo = pinfo; 4487 ce.pinfo = pinfo;
4107 } 4488 m_userInfoCache[uuid] = ce;
4108 else 4489 }
4109 { 4490 else
4110 if (ce == null) 4491 {
4111 return UUID.Zero.ToString(); 4492 if (ce == null)
4493 return UUID.Zero.ToString();
4112 4494
4113 account = ce.account; 4495 account = ce.account;
4114 pinfo = ce.pinfo; 4496 pinfo = ce.pinfo;
4115 } 4497 }
4116 4498
4117 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4499 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4118 {
4119 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4120 if (pinfos != null && pinfos.Length > 0)
4121 { 4500 {
4122 foreach (PresenceInfo p in pinfos) 4501 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4502 if (pinfos != null && pinfos.Length > 0)
4123 { 4503 {
4124 if (p.RegionID != UUID.Zero) 4504 foreach (PresenceInfo p in pinfos)
4125 { 4505 {
4126 pinfo = p; 4506 if (p.RegionID != UUID.Zero)
4507 {
4508 pinfo = p;
4509 }
4127 } 4510 }
4128 } 4511 }
4129 } 4512 else
4130 else 4513 pinfo = null;
4131 pinfo = null;
4132 4514
4133 ce.time = Util.EnvironmentTickCount(); 4515 ce.time = Util.EnvironmentTickCount();
4134 ce.pinfo = pinfo; 4516 ce.pinfo = pinfo;
4135 } 4517 }
4136 4518
4137 string reply = String.Empty; 4519 string reply = String.Empty;
4138 4520
4139 switch (data) 4521 switch (data)
4140 { 4522 {
4141 case 1: // DATA_ONLINE (0|1) 4523 case 1: // DATA_ONLINE (0|1)
4142 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4524 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4143 reply = "1"; 4525 reply = "1";
4144 else 4526 else
4145 reply = "0"; 4527 reply = "0";
4146 break; 4528 break;
4147 case 2: // DATA_NAME (First Last) 4529 case 2: // DATA_NAME (First Last)
4148 reply = account.FirstName + " " + account.LastName; 4530 reply = account.FirstName + " " + account.LastName;
4149 break; 4531 break;
4150 case 3: // DATA_BORN (YYYY-MM-DD) 4532 case 3: // DATA_BORN (YYYY-MM-DD)
4151 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4533 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4152 born = born.AddSeconds(account.Created); 4534 born = born.AddSeconds(account.Created);
4153 reply = born.ToString("yyyy-MM-dd"); 4535 reply = born.ToString("yyyy-MM-dd");
4154 break; 4536 break;
4155 case 4: // DATA_RATING (0,0,0,0,0,0) 4537 case 4: // DATA_RATING (0,0,0,0,0,0)
4156 reply = "0,0,0,0,0,0"; 4538 reply = "0,0,0,0,0,0";
4157 break; 4539 break;
4158 case 7: // DATA_USERLEVEL (integer) 4540 case 8: // DATA_PAYINFO (0|1|2|3)
4159 reply = account.UserLevel.ToString(); 4541 reply = "0";
4160 break; 4542 break;
4161 case 8: // DATA_PAYINFO (0|1|2|3) 4543 default:
4162 reply = "0"; 4544 return UUID.Zero.ToString(); // Raise no event
4163 break; 4545 }
4164 default:
4165 return UUID.Zero.ToString(); // Raise no event
4166 }
4167 4546
4168 UUID rq = UUID.Random(); 4547 UUID rq = UUID.Random();
4169 4548
4170 UUID tid = AsyncCommands. 4549 UUID tid = AsyncCommands.
4171 DataserverPlugin.RegisterRequest(m_host.LocalId, 4550 DataserverPlugin.RegisterRequest(m_host.LocalId,
4172 m_item.ItemID, rq.ToString()); 4551 m_item.ItemID, rq.ToString());
4173 4552
4174 AsyncCommands. 4553 AsyncCommands.
4175 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4554 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4176 4555
4177 ScriptSleep(100); 4556 ScriptSleep(100);
4178 return tid.ToString(); 4557 return tid.ToString();
4558 }
4559 else
4560 {
4561 ShoutError("Invalid UUID passed to llRequestAgentData.");
4562 }
4563 return "";
4179 } 4564 }
4180 4565
4181 public LSL_String llRequestInventoryData(string name) 4566 public LSL_String llRequestInventoryData(string name)
@@ -4232,13 +4617,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4232 if (UUID.TryParse(agent, out agentId)) 4617 if (UUID.TryParse(agent, out agentId))
4233 { 4618 {
4234 ScenePresence presence = World.GetScenePresence(agentId); 4619 ScenePresence presence = World.GetScenePresence(agentId);
4235 if (presence != null) 4620 if (presence != null && presence.PresenceType != PresenceType.Npc)
4236 { 4621 {
4622 // agent must not be a god
4623 if (presence.UserLevel >= 200) return;
4624
4237 // agent must be over the owners land 4625 // agent must be over the owners land
4238 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4626 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4239 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4627 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4240 { 4628 {
4241 World.TeleportClientHome(agentId, presence.ControllingClient); 4629 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4630 {
4631 // They can't be teleported home for some reason
4632 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4633 if (regionInfo != null)
4634 {
4635 World.RequestTeleportLocation(
4636 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4637 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4638 }
4639 }
4242 } 4640 }
4243 } 4641 }
4244 } 4642 }
@@ -4345,7 +4743,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4345 UUID av = new UUID(); 4743 UUID av = new UUID();
4346 if (!UUID.TryParse(agent,out av)) 4744 if (!UUID.TryParse(agent,out av))
4347 { 4745 {
4348 LSLError("First parameter to llDialog needs to be a key"); 4746 //LSLError("First parameter to llDialog needs to be a key");
4349 return; 4747 return;
4350 } 4748 }
4351 4749
@@ -4377,10 +4775,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4377 public void llCollisionSound(string impact_sound, double impact_volume) 4775 public void llCollisionSound(string impact_sound, double impact_volume)
4378 { 4776 {
4379 m_host.AddScriptLPS(1); 4777 m_host.AddScriptLPS(1);
4380 4778
4779 if(impact_sound == "")
4780 {
4781 m_host.CollisionSoundVolume = (float)impact_volume;
4782 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4783 m_host.CollisionSoundType = 0;
4784 return;
4785 }
4381 // TODO: Parameter check logic required. 4786 // TODO: Parameter check logic required.
4382 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4787 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound);
4383 m_host.CollisionSoundVolume = (float)impact_volume; 4788 m_host.CollisionSoundVolume = (float)impact_volume;
4789 m_host.CollisionSoundType = 1;
4384 } 4790 }
4385 4791
4386 public LSL_String llGetAnimation(string id) 4792 public LSL_String llGetAnimation(string id)
@@ -4394,14 +4800,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4394 4800
4395 if (m_host.RegionHandle == presence.RegionHandle) 4801 if (m_host.RegionHandle == presence.RegionHandle)
4396 { 4802 {
4397 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4398
4399 if (presence != null) 4803 if (presence != null)
4400 { 4804 {
4401 AnimationSet currentAnims = presence.Animator.Animations; 4805 if (presence.SitGround)
4402 string currentAnimationState = String.Empty; 4806 return "Sitting on Ground";
4403 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4807 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4404 return currentAnimationState; 4808 return "Sitting";
4809
4810 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4811 string lslMovementAnimation;
4812
4813 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4814 return lslMovementAnimation;
4405 } 4815 }
4406 } 4816 }
4407 4817
@@ -4548,7 +4958,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4548 { 4958 {
4549 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4959 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4550 float distance_term = distance * distance * distance; // Script Energy 4960 float distance_term = distance * distance * distance; // Script Energy
4551 float pusher_mass = m_host.GetMass(); 4961 // use total object mass and not part
4962 float pusher_mass = m_host.ParentGroup.GetMass();
4552 4963
4553 float PUSH_ATTENUATION_DISTANCE = 17f; 4964 float PUSH_ATTENUATION_DISTANCE = 17f;
4554 float PUSH_ATTENUATION_SCALE = 5f; 4965 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4798,6 +5209,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4798 { 5209 {
4799 return item.AssetID.ToString(); 5210 return item.AssetID.ToString();
4800 } 5211 }
5212 m_host.TaskInventory.LockItemsForRead(false);
4801 5213
4802 return UUID.Zero.ToString(); 5214 return UUID.Zero.ToString();
4803 } 5215 }
@@ -4950,14 +5362,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4950 { 5362 {
4951 m_host.AddScriptLPS(1); 5363 m_host.AddScriptLPS(1);
4952 5364
4953 if (src == null) 5365 return src.Length;
4954 {
4955 return 0;
4956 }
4957 else
4958 {
4959 return src.Length;
4960 }
4961 } 5366 }
4962 5367
4963 public LSL_Integer llList2Integer(LSL_List src, int index) 5368 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5028,7 +5433,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5028 else if (src.Data[index] is LSL_Float) 5433 else if (src.Data[index] is LSL_Float)
5029 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5434 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5030 else if (src.Data[index] is LSL_String) 5435 else if (src.Data[index] is LSL_String)
5031 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5436 {
5437 string str = ((LSL_String) src.Data[index]).m_string;
5438 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5439 if (m != Match.Empty)
5440 {
5441 str = m.Value;
5442 double d = 0.0;
5443 if (!Double.TryParse(str, out d))
5444 return 0.0;
5445
5446 return d;
5447 }
5448 return 0.0;
5449 }
5032 return Convert.ToDouble(src.Data[index]); 5450 return Convert.ToDouble(src.Data[index]);
5033 } 5451 }
5034 catch (FormatException) 5452 catch (FormatException)
@@ -5070,7 +5488,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5070 // for completion and should LSL_Key ever be implemented 5488 // for completion and should LSL_Key ever be implemented
5071 // as it's own struct 5489 // as it's own struct
5072 else if (!(src.Data[index] is LSL_String || 5490 else if (!(src.Data[index] is LSL_String ||
5073 src.Data[index] is LSL_Key)) 5491 src.Data[index] is LSL_Key ||
5492 src.Data[index] is String))
5074 { 5493 {
5075 return ""; 5494 return "";
5076 } 5495 }
@@ -5328,7 +5747,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5328 } 5747 }
5329 } 5748 }
5330 } 5749 }
5331 else { 5750 else
5751 {
5332 object[] array = new object[src.Length]; 5752 object[] array = new object[src.Length];
5333 Array.Copy(src.Data, 0, array, 0, src.Length); 5753 Array.Copy(src.Data, 0, array, 0, src.Length);
5334 result = new LSL_List(array); 5754 result = new LSL_List(array);
@@ -5435,7 +5855,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5435 public LSL_Integer llGetRegionAgentCount() 5855 public LSL_Integer llGetRegionAgentCount()
5436 { 5856 {
5437 m_host.AddScriptLPS(1); 5857 m_host.AddScriptLPS(1);
5438 return new LSL_Integer(World.GetRootAgentCount()); 5858
5859 int count = 0;
5860 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5861 count++;
5862 });
5863
5864 return new LSL_Integer(count);
5439 } 5865 }
5440 5866
5441 public LSL_Vector llGetRegionCorner() 5867 public LSL_Vector llGetRegionCorner()
@@ -5676,6 +6102,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5676 flags |= ScriptBaseClass.AGENT_AWAY; 6102 flags |= ScriptBaseClass.AGENT_AWAY;
5677 } 6103 }
5678 6104
6105 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6106 UUID[] anims = agent.Animator.GetAnimationArray();
6107 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6108 {
6109 flags |= ScriptBaseClass.AGENT_BUSY;
6110 }
6111
5679 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6112 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5680 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6113 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5681 { 6114 {
@@ -5723,6 +6156,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5723 flags |= ScriptBaseClass.AGENT_SITTING; 6156 flags |= ScriptBaseClass.AGENT_SITTING;
5724 } 6157 }
5725 6158
6159 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6160 {
6161 flags |= ScriptBaseClass.AGENT_MALE;
6162 }
6163
5726 return flags; 6164 return flags;
5727 } 6165 }
5728 6166
@@ -5870,9 +6308,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5870 6308
5871 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6309 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5872 6310
5873 foreach (SceneObjectPart part in parts) 6311 try
6312 {
6313 foreach (SceneObjectPart part in parts)
6314 {
6315 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6316 }
6317 }
6318 finally
5874 { 6319 {
5875 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5876 } 6320 }
5877 } 6321 }
5878 6322
@@ -5926,13 +6370,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5926 6370
5927 if (m_host.OwnerID == land.LandData.OwnerID) 6371 if (m_host.OwnerID == land.LandData.OwnerID)
5928 { 6372 {
5929 World.TeleportClientHome(agentID, presence.ControllingClient); 6373 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6374 presence.TeleportWithMomentum(pos, null);
6375 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5930 } 6376 }
5931 } 6377 }
5932 } 6378 }
5933 ScriptSleep(5000); 6379 ScriptSleep(5000);
5934 } 6380 }
5935 6381
6382 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6383 {
6384 return ParseString2List(str, separators, in_spacers, false);
6385 }
6386
5936 public LSL_Integer llOverMyLand(string id) 6387 public LSL_Integer llOverMyLand(string id)
5937 { 6388 {
5938 m_host.AddScriptLPS(1); 6389 m_host.AddScriptLPS(1);
@@ -5986,25 +6437,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5986 } 6437 }
5987 else 6438 else
5988 { 6439 {
5989 agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); 6440// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6441 Vector3 s = avatar.Appearance.AvatarSize;
6442 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5990 } 6443 }
5991 return agentSize; 6444 return agentSize;
5992 } 6445 }
5993 6446
5994 public LSL_Integer llSameGroup(string agent) 6447 public LSL_Integer llSameGroup(string id)
5995 { 6448 {
5996 m_host.AddScriptLPS(1); 6449 m_host.AddScriptLPS(1);
5997 UUID agentId = new UUID(); 6450 UUID uuid = new UUID();
5998 if (!UUID.TryParse(agent, out agentId)) 6451 if (!UUID.TryParse(id, out uuid))
5999 return new LSL_Integer(0);
6000 ScenePresence presence = World.GetScenePresence(agentId);
6001 if (presence == null || presence.IsChildAgent) // Return flase for child agents
6002 return new LSL_Integer(0); 6452 return new LSL_Integer(0);
6003 IClientAPI client = presence.ControllingClient; 6453
6004 if (m_host.GroupID == client.ActiveGroupId) 6454 // Check if it's a group key
6455 if (uuid == m_host.ParentGroup.RootPart.GroupID)
6005 return new LSL_Integer(1); 6456 return new LSL_Integer(1);
6006 else 6457
6458 // We got passed a UUID.Zero
6459 if (uuid == UUID.Zero)
6460 return new LSL_Integer(0);
6461
6462 // Handle the case where id names an avatar
6463 ScenePresence presence = World.GetScenePresence(uuid);
6464 if (presence != null)
6465 {
6466 if (presence.IsChildAgent)
6467 return new LSL_Integer(0);
6468
6469 IClientAPI client = presence.ControllingClient;
6470 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6471 return new LSL_Integer(1);
6472
6473 return new LSL_Integer(0);
6474 }
6475
6476 // Handle object case
6477 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6478 if (part != null)
6479 {
6480 // This will handle both deed and non-deed and also the no
6481 // group case
6482 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6483 return new LSL_Integer(1);
6484
6007 return new LSL_Integer(0); 6485 return new LSL_Integer(0);
6486 }
6487
6488 return new LSL_Integer(0);
6008 } 6489 }
6009 6490
6010 public void llUnSit(string id) 6491 public void llUnSit(string id)
@@ -6129,7 +6610,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6129 return m_host.ParentGroup.AttachmentPoint; 6610 return m_host.ParentGroup.AttachmentPoint;
6130 } 6611 }
6131 6612
6132 public LSL_Integer llGetFreeMemory() 6613 public virtual LSL_Integer llGetFreeMemory()
6133 { 6614 {
6134 m_host.AddScriptLPS(1); 6615 m_host.AddScriptLPS(1);
6135 // Make scripts designed for LSO happy 6616 // Make scripts designed for LSO happy
@@ -6561,6 +7042,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6561 7042
6562 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7043 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6563 { 7044 {
7045 // LSL quaternions can normalize to 0, normal Quaternions can't.
7046 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7047 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7048
6564 part.SitTargetPosition = offset; 7049 part.SitTargetPosition = offset;
6565 part.SitTargetOrientation = rot; 7050 part.SitTargetOrientation = rot;
6566 part.ParentGroup.HasGroupChanged = true; 7051 part.ParentGroup.HasGroupChanged = true;
@@ -6746,13 +7231,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6746 UUID av = new UUID(); 7231 UUID av = new UUID();
6747 if (!UUID.TryParse(avatar,out av)) 7232 if (!UUID.TryParse(avatar,out av))
6748 { 7233 {
6749 LSLError("First parameter to llDialog needs to be a key"); 7234 //LSLError("First parameter to llDialog needs to be a key");
6750 return; 7235 return;
6751 } 7236 }
6752 if (buttons.Length < 1) 7237 if (buttons.Length < 1)
6753 { 7238 {
6754 LSLError("No less than 1 button can be shown"); 7239 buttons.Add("OK");
6755 return;
6756 } 7240 }
6757 if (buttons.Length > 12) 7241 if (buttons.Length > 12)
6758 { 7242 {
@@ -6769,7 +7253,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6769 } 7253 }
6770 if (buttons.Data[i].ToString().Length > 24) 7254 if (buttons.Data[i].ToString().Length > 24)
6771 { 7255 {
6772 LSLError("button label cannot be longer than 24 characters"); 7256 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6773 return; 7257 return;
6774 } 7258 }
6775 buts[i] = buttons.Data[i].ToString(); 7259 buts[i] = buttons.Data[i].ToString();
@@ -6836,9 +7320,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6836 return; 7320 return;
6837 } 7321 }
6838 7322
6839 // the rest of the permission checks are done in RezScript, so check the pin there as well 7323 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6840 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7324 if (dest != null)
7325 {
7326 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7327 {
7328 // the rest of the permission checks are done in RezScript, so check the pin there as well
7329 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6841 7330
7331 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7332 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7333 }
7334 }
6842 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7335 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6843 ScriptSleep(3000); 7336 ScriptSleep(3000);
6844 } 7337 }
@@ -6912,19 +7405,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6912 public LSL_String llMD5String(string src, int nonce) 7405 public LSL_String llMD5String(string src, int nonce)
6913 { 7406 {
6914 m_host.AddScriptLPS(1); 7407 m_host.AddScriptLPS(1);
6915 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7408 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6916 } 7409 }
6917 7410
6918 public LSL_String llSHA1String(string src) 7411 public LSL_String llSHA1String(string src)
6919 { 7412 {
6920 m_host.AddScriptLPS(1); 7413 m_host.AddScriptLPS(1);
6921 return Util.SHA1Hash(src).ToLower(); 7414 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6922 } 7415 }
6923 7416
6924 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7417 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6925 { 7418 {
6926 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7419 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6927 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7420 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7421 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7422 return shapeBlock;
6928 7423
6929 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7424 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6930 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7425 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -7029,6 +7524,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7029 // Prim type box, cylinder and prism. 7524 // Prim type box, cylinder and prism.
7030 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) 7525 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)
7031 { 7526 {
7527 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7528 return;
7529
7032 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7530 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7033 ObjectShapePacket.ObjectDataBlock shapeBlock; 7531 ObjectShapePacket.ObjectDataBlock shapeBlock;
7034 7532
@@ -7082,6 +7580,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7082 // Prim type sphere. 7580 // Prim type sphere.
7083 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7581 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7084 { 7582 {
7583 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7584 return;
7585
7085 ObjectShapePacket.ObjectDataBlock shapeBlock; 7586 ObjectShapePacket.ObjectDataBlock shapeBlock;
7086 7587
7087 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7588 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7123,6 +7624,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7123 // Prim type torus, tube and ring. 7624 // Prim type torus, tube and ring.
7124 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) 7625 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)
7125 { 7626 {
7627 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7628 return;
7629
7126 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7630 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7127 ObjectShapePacket.ObjectDataBlock shapeBlock; 7631 ObjectShapePacket.ObjectDataBlock shapeBlock;
7128 7632
@@ -7258,6 +7762,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7258 // Prim type sculpt. 7762 // Prim type sculpt.
7259 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7763 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7260 { 7764 {
7765 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7766 return;
7767
7261 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7768 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7262 UUID sculptId; 7769 UUID sculptId;
7263 7770
@@ -7282,7 +7789,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7282 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7789 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7283 { 7790 {
7284 // default 7791 // default
7285 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7792 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7286 } 7793 }
7287 7794
7288 part.Shape.SetSculptProperties((byte)type, sculptId); 7795 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7299,48 +7806,130 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7299 ScriptSleep(200); 7806 ScriptSleep(200);
7300 } 7807 }
7301 7808
7302 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7809 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7303 { 7810 {
7304 m_host.AddScriptLPS(1); 7811 m_host.AddScriptLPS(1);
7305 7812
7306 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7813 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7814 }
7307 7815
7308 ScriptSleep(200); 7816 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7817 {
7818 List<object> parts = new List<object>();
7819 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7820 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7821 foreach (SceneObjectPart p in prims)
7822 parts.Add(p);
7823 foreach (ScenePresence p in avatars)
7824 parts.Add(p);
7825
7826 LSL_List remaining = null;
7827 uint rulesParsed = 0;
7828
7829 if (parts.Count > 0)
7830 {
7831 foreach (object part in parts)
7832 {
7833 if (part is SceneObjectPart)
7834 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7835 else
7836 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7837 }
7838
7839 while ((object)remaining != null && remaining.Length > 2)
7840 {
7841 linknumber = remaining.GetLSLIntegerItem(0);
7842 rules = remaining.GetSublist(1, -1);
7843 parts.Clear();
7844 prims = GetLinkParts(linknumber);
7845 avatars = GetLinkAvatars(linknumber);
7846 foreach (SceneObjectPart p in prims)
7847 parts.Add(p);
7848 foreach (ScenePresence p in avatars)
7849 parts.Add(p);
7850
7851 remaining = null;
7852 foreach (object part in parts)
7853 {
7854 if (part is SceneObjectPart)
7855 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7856 else
7857 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7858 }
7859 }
7860 }
7309 } 7861 }
7310 7862
7311 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7863 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7864 float material_density, float material_friction,
7865 float material_restitution, float material_gravity_modifier)
7312 { 7866 {
7313 m_host.AddScriptLPS(1); 7867 ExtraPhysicsData physdata = new ExtraPhysicsData();
7868 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7869 physdata.Density = part.Density;
7870 physdata.Friction = part.Friction;
7871 physdata.Bounce = part.Bounciness;
7872 physdata.GravitationModifier = part.GravityModifier;
7314 7873
7315 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7874 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7875 physdata.Density = material_density;
7876 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7877 physdata.Friction = material_friction;
7878 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7879 physdata.Bounce = material_restitution;
7880 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7881 physdata.GravitationModifier = material_gravity_modifier;
7882
7883 part.UpdateExtraPhysics(physdata);
7316 } 7884 }
7317 7885
7318 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7886 public void llSetPhysicsMaterial(int material_bits,
7887 float material_gravity_modifier, float material_restitution,
7888 float material_friction, float material_density)
7319 { 7889 {
7320 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7890 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7891 }
7321 7892
7322 LSL_List remaining = null; 7893 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7323 uint rulesParsed = 0; 7894 {
7895 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7896 llSetLinkPrimitiveParamsFast(linknumber, rules);
7897 ScriptSleep(200);
7898 }
7324 7899
7325 foreach (SceneObjectPart part in parts) 7900 // vector up using libomv (c&p from sop )
7326 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7901 // vector up rotated by r
7902 private Vector3 Zrot(Quaternion r)
7903 {
7904 double x, y, z, m;
7327 7905
7328 while (remaining != null && remaining.Length > 2) 7906 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7907 if (Math.Abs(1.0 - m) > 0.000001)
7329 { 7908 {
7330 linknumber = remaining.GetLSLIntegerItem(0); 7909 m = 1.0 / Math.Sqrt(m);
7331 rules = remaining.GetSublist(1, -1); 7910 r.X *= (float)m;
7332 parts = GetLinkParts(linknumber); 7911 r.Y *= (float)m;
7333 7912 r.Z *= (float)m;
7334 foreach (SceneObjectPart part in parts) 7913 r.W *= (float)m;
7335 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7336 } 7914 }
7915
7916 x = 2 * (r.X * r.Z + r.Y * r.W);
7917 y = 2 * (-r.X * r.W + r.Y * r.Z);
7918 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7919
7920 return new Vector3((float)x, (float)y, (float)z);
7337 } 7921 }
7338 7922
7339 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7923 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7340 { 7924 {
7925 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7926 return null;
7927
7341 int idx = 0; 7928 int idx = 0;
7342 int idxStart = 0; 7929 int idxStart = 0;
7343 7930
7931 SceneObjectGroup parentgrp = part.ParentGroup;
7932
7344 bool positionChanged = false; 7933 bool positionChanged = false;
7345 LSL_Vector currentPosition = GetPartLocalPos(part); 7934 LSL_Vector currentPosition = GetPartLocalPos(part);
7346 7935
@@ -7365,8 +7954,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7365 return null; 7954 return null;
7366 7955
7367 v=rules.GetVector3Item(idx++); 7956 v=rules.GetVector3Item(idx++);
7957 if (part.IsRoot && !part.ParentGroup.IsAttachment)
7958 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
7959 else
7960 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7368 positionChanged = true; 7961 positionChanged = true;
7369 currentPosition = GetSetPosTarget(part, v, currentPosition);
7370 7962
7371 break; 7963 break;
7372 case (int)ScriptBaseClass.PRIM_SIZE: 7964 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7383,7 +7975,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7383 7975
7384 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7976 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7385 // try to let this work as in SL... 7977 // try to let this work as in SL...
7386 if (part.ParentID == 0) 7978 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7387 { 7979 {
7388 // special case: If we are root, rotate complete SOG to new rotation 7980 // special case: If we are root, rotate complete SOG to new rotation
7389 SetRot(part, q); 7981 SetRot(part, q);
@@ -7643,7 +8235,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7643 return null; 8235 return null;
7644 8236
7645 string ph = rules.Data[idx++].ToString(); 8237 string ph = rules.Data[idx++].ToString();
7646 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8238 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7647 8239
7648 break; 8240 break;
7649 8241
@@ -7661,12 +8253,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7661 part.ScriptSetPhysicsStatus(physics); 8253 part.ScriptSetPhysicsStatus(physics);
7662 break; 8254 break;
7663 8255
8256 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8257 if (remain < 1)
8258 return null;
8259
8260 int shape_type = rules.GetLSLIntegerItem(idx++);
8261
8262 ExtraPhysicsData physdata = new ExtraPhysicsData();
8263 physdata.Density = part.Density;
8264 physdata.Bounce = part.Bounciness;
8265 physdata.GravitationModifier = part.GravityModifier;
8266 physdata.PhysShapeType = (PhysShapeType)shape_type;
8267
8268 part.UpdateExtraPhysics(physdata);
8269
8270 break;
8271
8272 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8273 if (remain < 5)
8274 return null;
8275
8276 int material_bits = rules.GetLSLIntegerItem(idx++);
8277 float material_density = (float)rules.GetLSLFloatItem(idx++);
8278 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8279 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8280 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8281
8282 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8283
8284 break;
8285
7664 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8286 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7665 if (remain < 1) 8287 if (remain < 1)
7666 return null; 8288 return null;
7667 string temp = rules.Data[idx++].ToString(); 8289 string temp = rules.Data[idx++].ToString();
7668 8290
7669 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8291 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7670 8292
7671 break; 8293 break;
7672 8294
@@ -7740,14 +8362,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7740 if (part.ParentGroup.RootPart == part) 8362 if (part.ParentGroup.RootPart == part)
7741 { 8363 {
7742 SceneObjectGroup parent = part.ParentGroup; 8364 SceneObjectGroup parent = part.ParentGroup;
7743 parent.UpdateGroupPosition(currentPosition); 8365 Util.FireAndForget(delegate(object x) {
8366 parent.UpdateGroupPosition(currentPosition);
8367 });
7744 } 8368 }
7745 else 8369 else
7746 { 8370 {
7747 part.OffsetPosition = currentPosition; 8371 part.OffsetPosition = currentPosition;
7748 SceneObjectGroup parent = part.ParentGroup; 8372// SceneObjectGroup parent = part.ParentGroup;
7749 parent.HasGroupChanged = true; 8373// parent.HasGroupChanged = true;
7750 parent.ScheduleGroupForTerseUpdate(); 8374// parent.ScheduleGroupForTerseUpdate();
8375 part.ScheduleTerseUpdate();
7751 } 8376 }
7752 } 8377 }
7753 } 8378 }
@@ -7785,10 +8410,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7785 8410
7786 public LSL_String llXorBase64Strings(string str1, string str2) 8411 public LSL_String llXorBase64Strings(string str1, string str2)
7787 { 8412 {
7788 m_host.AddScriptLPS(1); 8413 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7789 Deprecated("llXorBase64Strings"); 8414
7790 ScriptSleep(300); 8415 ScriptSleep(300);
7791 return String.Empty; 8416 m_host.AddScriptLPS(1);
8417
8418 if (str1 == String.Empty)
8419 return String.Empty;
8420 if (str2 == String.Empty)
8421 return str1;
8422
8423 int len = str2.Length;
8424 if ((len % 4) != 0) // LL is EVIL!!!!
8425 {
8426 while (str2.EndsWith("="))
8427 str2 = str2.Substring(0, str2.Length - 1);
8428
8429 len = str2.Length;
8430 int mod = len % 4;
8431
8432 if (mod == 1)
8433 str2 = str2.Substring(0, str2.Length - 1);
8434 else if (mod == 2)
8435 str2 += "==";
8436 else if (mod == 3)
8437 str2 += "=";
8438 }
8439
8440 byte[] data1;
8441 byte[] data2;
8442 try
8443 {
8444 data1 = Convert.FromBase64String(str1);
8445 data2 = Convert.FromBase64String(str2);
8446 }
8447 catch (Exception)
8448 {
8449 return new LSL_String(String.Empty);
8450 }
8451
8452 // For cases where the decoded length of s2 is greater
8453 // than the decoded length of s1, simply perform a normal
8454 // decode and XOR
8455 //
8456 if (data2.Length >= data1.Length)
8457 {
8458 for (int pos = 0 ; pos < data1.Length ; pos++ )
8459 data1[pos] ^= data2[pos];
8460
8461 return Convert.ToBase64String(data1);
8462 }
8463
8464 // Remove padding
8465 while (str1.EndsWith("="))
8466 str1 = str1.Substring(0, str1.Length - 1);
8467 while (str2.EndsWith("="))
8468 str2 = str2.Substring(0, str2.Length - 1);
8469
8470 byte[] d1 = new byte[str1.Length];
8471 byte[] d2 = new byte[str2.Length];
8472
8473 for (int i = 0 ; i < str1.Length ; i++)
8474 {
8475 int idx = b64.IndexOf(str1.Substring(i, 1));
8476 if (idx == -1)
8477 idx = 0;
8478 d1[i] = (byte)idx;
8479 }
8480
8481 for (int i = 0 ; i < str2.Length ; i++)
8482 {
8483 int idx = b64.IndexOf(str2.Substring(i, 1));
8484 if (idx == -1)
8485 idx = 0;
8486 d2[i] = (byte)idx;
8487 }
8488
8489 string output = String.Empty;
8490
8491 for (int pos = 0 ; pos < d1.Length ; pos++)
8492 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8493
8494 while (output.Length % 3 > 0)
8495 output += "=";
8496
8497 return output;
7792 } 8498 }
7793 8499
7794 public void llRemoteDataSetRegion() 8500 public void llRemoteDataSetRegion()
@@ -7912,8 +8618,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7912 public LSL_Integer llGetNumberOfPrims() 8618 public LSL_Integer llGetNumberOfPrims()
7913 { 8619 {
7914 m_host.AddScriptLPS(1); 8620 m_host.AddScriptLPS(1);
7915 8621 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7916 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8622
8623 return m_host.ParentGroup.PrimCount + avatarCount;
7917 } 8624 }
7918 8625
7919 /// <summary> 8626 /// <summary>
@@ -7928,55 +8635,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7928 m_host.AddScriptLPS(1); 8635 m_host.AddScriptLPS(1);
7929 UUID objID = UUID.Zero; 8636 UUID objID = UUID.Zero;
7930 LSL_List result = new LSL_List(); 8637 LSL_List result = new LSL_List();
8638
8639 // If the ID is not valid, return null result
7931 if (!UUID.TryParse(obj, out objID)) 8640 if (!UUID.TryParse(obj, out objID))
7932 { 8641 {
7933 result.Add(new LSL_Vector()); 8642 result.Add(new LSL_Vector());
7934 result.Add(new LSL_Vector()); 8643 result.Add(new LSL_Vector());
7935 return result; 8644 return result;
7936 } 8645 }
8646
8647 // Check if this is an attached prim. If so, replace
8648 // the UUID with the avatar UUID and report it's bounding box
8649 SceneObjectPart part = World.GetSceneObjectPart(objID);
8650 if (part != null && part.ParentGroup.IsAttachment)
8651 objID = part.ParentGroup.AttachedAvatar;
8652
8653 // Find out if this is an avatar ID. If so, return it's box
7937 ScenePresence presence = World.GetScenePresence(objID); 8654 ScenePresence presence = World.GetScenePresence(objID);
7938 if (presence != null) 8655 if (presence != null)
7939 { 8656 {
7940 if (presence.ParentID == 0) // not sat on an object 8657 // As per LSL Wiki, there is no difference between sitting
8658 // and standing avatar since server 1.36
8659 LSL_Vector lower;
8660 LSL_Vector upper;
8661
8662 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8663
8664 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8665 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8666/*
7941 { 8667 {
7942 LSL_Vector lower; 8668 // This is for ground sitting avatars
7943 LSL_Vector upper; 8669 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7944 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8670 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7945 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8671 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7946 { 8672 }
7947 // This is for ground sitting avatars 8673 else
7948 float height = presence.Appearance.AvatarHeight / 2.66666667f; 8674 {
7949 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); 8675 // This is for standing/flying avatars
7950 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); 8676 float height = presence.Appearance.AvatarHeight / 2.0f;
7951 } 8677 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7952 else 8678 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7953 { 8679 }
7954 // This is for standing/flying avatars 8680
7955 float height = presence.Appearance.AvatarHeight / 2.0f; 8681 // Adjust to the documented error offsets (see LSL Wiki)
7956 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); 8682 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7957 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); 8683 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7958 } 8684*/
7959 result.Add(lower); 8685 {
7960 result.Add(upper); 8686 // This is for ground sitting avatars TODO!
7961 return result; 8687 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8688 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
7962 } 8689 }
7963 else 8690 else
7964 { 8691 {
7965 // sitting on an object so we need the bounding box of that 8692 // This is for standing/flying avatars
7966 // which should include the avatar so set the UUID to the 8693 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
7967 // UUID of the object the avatar is sat on and allow it to fall through 8694 upper = new LSL_Vector(box.X, box.Y, box.Z);
7968 // to processing an object
7969 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7970 objID = p.UUID;
7971 } 8695 }
8696
8697 if (lower.x > upper.x)
8698 lower.x = upper.x;
8699 if (lower.y > upper.y)
8700 lower.y = upper.y;
8701 if (lower.z > upper.z)
8702 lower.z = upper.z;
8703
8704 result.Add(lower);
8705 result.Add(upper);
8706 return result;
7972 } 8707 }
7973 SceneObjectPart part = World.GetSceneObjectPart(objID); 8708
8709 part = World.GetSceneObjectPart(objID);
7974 // Currently only works for single prims without a sitting avatar 8710 // Currently only works for single prims without a sitting avatar
7975 if (part != null) 8711 if (part != null)
7976 { 8712 {
7977 Vector3 halfSize = part.Scale / 2.0f; 8713 float minX;
7978 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8714 float maxX;
7979 LSL_Vector upper = new LSL_Vector(halfSize); 8715 float minY;
8716 float maxY;
8717 float minZ;
8718 float maxZ;
8719
8720 // This BBox is in sim coordinates, with the offset being
8721 // a contained point.
8722 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8723 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8724
8725 minX -= offsets[0].X;
8726 maxX -= offsets[0].X;
8727 minY -= offsets[0].Y;
8728 maxY -= offsets[0].Y;
8729 minZ -= offsets[0].Z;
8730 maxZ -= offsets[0].Z;
8731
8732 LSL_Vector lower;
8733 LSL_Vector upper;
8734
8735 // Adjust to the documented error offsets (see LSL Wiki)
8736 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8737 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8738
8739 if (lower.x > upper.x)
8740 lower.x = upper.x;
8741 if (lower.y > upper.y)
8742 lower.y = upper.y;
8743 if (lower.z > upper.z)
8744 lower.z = upper.z;
8745
7980 result.Add(lower); 8746 result.Add(lower);
7981 result.Add(upper); 8747 result.Add(upper);
7982 return result; 8748 return result;
@@ -7990,7 +8756,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7990 8756
7991 public LSL_Vector llGetGeometricCenter() 8757 public LSL_Vector llGetGeometricCenter()
7992 { 8758 {
7993 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8759 Vector3 tmp = m_host.GetGeometricCenter();
8760 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7994 } 8761 }
7995 8762
7996 public LSL_List llGetPrimitiveParams(LSL_List rules) 8763 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -8001,7 +8768,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8001 8768
8002 LSL_List remaining = GetPrimParams(m_host, rules, ref result); 8769 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
8003 8770
8004 while (remaining != null && remaining.Length > 2) 8771 while ((object)remaining != null && remaining.Length > 2)
8005 { 8772 {
8006 int linknumber = remaining.GetLSLIntegerItem(0); 8773 int linknumber = remaining.GetLSLIntegerItem(0);
8007 rules = remaining.GetSublist(1, -1); 8774 rules = remaining.GetSublist(1, -1);
@@ -8018,24 +8785,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8018 { 8785 {
8019 m_host.AddScriptLPS(1); 8786 m_host.AddScriptLPS(1);
8020 8787
8021 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8788 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8789 // keep other options as before
8022 8790
8791 List<SceneObjectPart> parts;
8792 List<ScenePresence> avatars;
8793
8023 LSL_List res = new LSL_List(); 8794 LSL_List res = new LSL_List();
8024 LSL_List remaining = null; 8795 LSL_List remaining = null;
8025 8796
8026 foreach (SceneObjectPart part in parts) 8797 while (rules.Length > 0)
8027 {
8028 remaining = GetPrimParams(part, rules, ref res);
8029 }
8030
8031 while (remaining != null && remaining.Length > 2)
8032 { 8798 {
8033 linknumber = remaining.GetLSLIntegerItem(0);
8034 rules = remaining.GetSublist(1, -1);
8035 parts = GetLinkParts(linknumber); 8799 parts = GetLinkParts(linknumber);
8800 avatars = GetLinkAvatars(linknumber);
8036 8801
8802 remaining = null;
8037 foreach (SceneObjectPart part in parts) 8803 foreach (SceneObjectPart part in parts)
8804 {
8038 remaining = GetPrimParams(part, rules, ref res); 8805 remaining = GetPrimParams(part, rules, ref res);
8806 }
8807 foreach (ScenePresence avatar in avatars)
8808 {
8809 remaining = GetPrimParams(avatar, rules, ref res);
8810 }
8811
8812 if ((object)remaining != null && remaining.Length > 0)
8813 {
8814 linknumber = remaining.GetLSLIntegerItem(0);
8815 rules = remaining.GetSublist(1, -1);
8816 }
8817 else
8818 break;
8039 } 8819 }
8040 8820
8041 return res; 8821 return res;
@@ -8080,13 +8860,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8080 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8860 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8081 part.AbsolutePosition.Y, 8861 part.AbsolutePosition.Y,
8082 part.AbsolutePosition.Z); 8862 part.AbsolutePosition.Z);
8083 // For some reason, the part.AbsolutePosition.* values do not change if the
8084 // linkset is rotated; they always reflect the child prim's world position
8085 // as though the linkset is unrotated. This is incompatible behavior with SL's
8086 // implementation, so will break scripts imported from there (not to mention it
8087 // makes it more difficult to determine a child prim's actual inworld position).
8088 if (part.ParentID != 0)
8089 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8090 res.Add(v); 8863 res.Add(v);
8091 break; 8864 break;
8092 8865
@@ -8258,30 +9031,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8258 if (remain < 1) 9031 if (remain < 1)
8259 return null; 9032 return null;
8260 9033
8261 face=(int)rules.GetLSLIntegerItem(idx++); 9034 face = (int)rules.GetLSLIntegerItem(idx++);
8262 9035
8263 tex = part.Shape.Textures; 9036 tex = part.Shape.Textures;
9037 int shiny;
8264 if (face == ScriptBaseClass.ALL_SIDES) 9038 if (face == ScriptBaseClass.ALL_SIDES)
8265 { 9039 {
8266 for (face = 0; face < GetNumberOfSides(part); face++) 9040 for (face = 0; face < GetNumberOfSides(part); face++)
8267 { 9041 {
8268 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9042 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8269 // Convert Shininess to PRIM_SHINY_* 9043 if (shinyness == Shininess.High)
8270 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9044 {
8271 // PRIM_BUMP_* 9045 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8272 res.Add(new LSL_Integer((int)texface.Bump)); 9046 }
9047 else if (shinyness == Shininess.Medium)
9048 {
9049 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9050 }
9051 else if (shinyness == Shininess.Low)
9052 {
9053 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9054 }
9055 else
9056 {
9057 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9058 }
9059 res.Add(new LSL_Integer(shiny));
9060 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8273 } 9061 }
8274 } 9062 }
8275 else 9063 else
8276 { 9064 {
8277 if (face >= 0 && face < GetNumberOfSides(part)) 9065 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9066 if (shinyness == Shininess.High)
8278 { 9067 {
8279 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9068 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8280 // Convert Shininess to PRIM_SHINY_*
8281 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8282 // PRIM_BUMP_*
8283 res.Add(new LSL_Integer((int)texface.Bump));
8284 } 9069 }
9070 else if (shinyness == Shininess.Medium)
9071 {
9072 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9073 }
9074 else if (shinyness == Shininess.Low)
9075 {
9076 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9077 }
9078 else
9079 {
9080 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9081 }
9082 res.Add(new LSL_Integer(shiny));
9083 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8285 } 9084 }
8286 break; 9085 break;
8287 9086
@@ -8289,24 +9088,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8289 if (remain < 1) 9088 if (remain < 1)
8290 return null; 9089 return null;
8291 9090
8292 face=(int)rules.GetLSLIntegerItem(idx++); 9091 face = (int)rules.GetLSLIntegerItem(idx++);
8293 9092
8294 tex = part.Shape.Textures; 9093 tex = part.Shape.Textures;
9094 int fullbright;
8295 if (face == ScriptBaseClass.ALL_SIDES) 9095 if (face == ScriptBaseClass.ALL_SIDES)
8296 { 9096 {
8297 for (face = 0; face < GetNumberOfSides(part); face++) 9097 for (face = 0; face < GetNumberOfSides(part); face++)
8298 { 9098 {
8299 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9099 if (tex.GetFace((uint)face).Fullbright == true)
8300 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9100 {
9101 fullbright = ScriptBaseClass.TRUE;
9102 }
9103 else
9104 {
9105 fullbright = ScriptBaseClass.FALSE;
9106 }
9107 res.Add(new LSL_Integer(fullbright));
8301 } 9108 }
8302 } 9109 }
8303 else 9110 else
8304 { 9111 {
8305 if (face >= 0 && face < GetNumberOfSides(part)) 9112 if (tex.GetFace((uint)face).Fullbright == true)
8306 { 9113 {
8307 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9114 fullbright = ScriptBaseClass.TRUE;
8308 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9115 }
9116 else
9117 {
9118 fullbright = ScriptBaseClass.FALSE;
8309 } 9119 }
9120 res.Add(new LSL_Integer(fullbright));
8310 } 9121 }
8311 break; 9122 break;
8312 9123
@@ -8328,27 +9139,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8328 break; 9139 break;
8329 9140
8330 case (int)ScriptBaseClass.PRIM_TEXGEN: 9141 case (int)ScriptBaseClass.PRIM_TEXGEN:
9142 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8331 if (remain < 1) 9143 if (remain < 1)
8332 return null; 9144 return null;
8333 9145
8334 face=(int)rules.GetLSLIntegerItem(idx++); 9146 face = (int)rules.GetLSLIntegerItem(idx++);
8335 9147
8336 tex = part.Shape.Textures; 9148 tex = part.Shape.Textures;
8337 if (face == ScriptBaseClass.ALL_SIDES) 9149 if (face == ScriptBaseClass.ALL_SIDES)
8338 { 9150 {
8339 for (face = 0; face < GetNumberOfSides(part); face++) 9151 for (face = 0; face < GetNumberOfSides(part); face++)
8340 { 9152 {
8341 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9153 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8342 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9154 {
8343 res.Add(new LSL_Integer((uint)texgen >> 1)); 9155 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9156 }
9157 else
9158 {
9159 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9160 }
8344 } 9161 }
8345 } 9162 }
8346 else 9163 else
8347 { 9164 {
8348 if (face >= 0 && face < GetNumberOfSides(part)) 9165 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9166 {
9167 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9168 }
9169 else
8349 { 9170 {
8350 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9171 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8351 res.Add(new LSL_Integer((uint)texgen >> 1));
8352 } 9172 }
8353 } 9173 }
8354 break; 9174 break;
@@ -8372,24 +9192,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8372 if (remain < 1) 9192 if (remain < 1)
8373 return null; 9193 return null;
8374 9194
8375 face=(int)rules.GetLSLIntegerItem(idx++); 9195 face = (int)rules.GetLSLIntegerItem(idx++);
8376 9196
8377 tex = part.Shape.Textures; 9197 tex = part.Shape.Textures;
9198 float primglow;
8378 if (face == ScriptBaseClass.ALL_SIDES) 9199 if (face == ScriptBaseClass.ALL_SIDES)
8379 { 9200 {
8380 for (face = 0; face < GetNumberOfSides(part); face++) 9201 for (face = 0; face < GetNumberOfSides(part); face++)
8381 { 9202 {
8382 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9203 primglow = tex.GetFace((uint)face).Glow;
8383 res.Add(new LSL_Float(texface.Glow)); 9204 res.Add(new LSL_Float(primglow));
8384 } 9205 }
8385 } 9206 }
8386 else 9207 else
8387 { 9208 {
8388 if (face >= 0 && face < GetNumberOfSides(part)) 9209 primglow = tex.GetFace((uint)face).Glow;
8389 { 9210 res.Add(new LSL_Float(primglow));
8390 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8391 res.Add(new LSL_Float(texface.Glow));
8392 }
8393 } 9211 }
8394 break; 9212 break;
8395 9213
@@ -8401,15 +9219,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8401 textColor.B)); 9219 textColor.B));
8402 res.Add(new LSL_Float(textColor.A)); 9220 res.Add(new LSL_Float(textColor.A));
8403 break; 9221 break;
9222
8404 case (int)ScriptBaseClass.PRIM_NAME: 9223 case (int)ScriptBaseClass.PRIM_NAME:
8405 res.Add(new LSL_String(part.Name)); 9224 res.Add(new LSL_String(part.Name));
8406 break; 9225 break;
9226
8407 case (int)ScriptBaseClass.PRIM_DESC: 9227 case (int)ScriptBaseClass.PRIM_DESC:
8408 res.Add(new LSL_String(part.Description)); 9228 res.Add(new LSL_String(part.Description));
8409 break; 9229 break;
9230
8410 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9231 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8411 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9232 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8412 break; 9233 break;
9234
8413 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9235 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8414 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9236 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8415 break; 9237 break;
@@ -9020,8 +9842,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9020 // The function returns an ordered list 9842 // The function returns an ordered list
9021 // representing the tokens found in the supplied 9843 // representing the tokens found in the supplied
9022 // sources string. If two successive tokenizers 9844 // sources string. If two successive tokenizers
9023 // are encountered, then a NULL entry is added 9845 // are encountered, then a null-string entry is
9024 // to the list. 9846 // added to the list.
9025 // 9847 //
9026 // It is a precondition that the source and 9848 // It is a precondition that the source and
9027 // toekizer lisst are non-null. If they are null, 9849 // toekizer lisst are non-null. If they are null,
@@ -9029,7 +9851,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9029 // while their lengths are being determined. 9851 // while their lengths are being determined.
9030 // 9852 //
9031 // A small amount of working memoryis required 9853 // A small amount of working memoryis required
9032 // of approximately 8*#tokenizers. 9854 // of approximately 8*#tokenizers + 8*srcstrlen.
9033 // 9855 //
9034 // There are many ways in which this function 9856 // There are many ways in which this function
9035 // can be implemented, this implementation is 9857 // can be implemented, this implementation is
@@ -9045,155 +9867,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9045 // and eliminates redundant tokenizers as soon 9867 // and eliminates redundant tokenizers as soon
9046 // as is possible. 9868 // as is possible.
9047 // 9869 //
9048 // The implementation tries to avoid any copying 9870 // The implementation tries to minimize temporary
9049 // of arrays or other objects. 9871 // garbage generation.
9050 // </remarks> 9872 // </remarks>
9051 9873
9052 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9874 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9053 { 9875 {
9054 int beginning = 0; 9876 return ParseString2List(src, separators, spacers, true);
9055 int srclen = src.Length; 9877 }
9056 int seplen = separators.Length;
9057 object[] separray = separators.Data;
9058 int spclen = spacers.Length;
9059 object[] spcarray = spacers.Data;
9060 int mlen = seplen+spclen;
9061
9062 int[] offset = new int[mlen+1];
9063 bool[] active = new bool[mlen];
9064
9065 int best;
9066 int j;
9067
9068 // Initial capacity reduces resize cost
9069 9878
9070 LSL_List tokens = new LSL_List(); 9879 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9880 {
9881 int srclen = src.Length;
9882 int seplen = separators.Length;
9883 object[] separray = separators.Data;
9884 int spclen = spacers.Length;
9885 object[] spcarray = spacers.Data;
9886 int dellen = 0;
9887 string[] delarray = new string[seplen+spclen];
9071 9888
9072 // All entries are initially valid 9889 int outlen = 0;
9890 string[] outarray = new string[srclen*2+1];
9073 9891
9074 for (int i = 0; i < mlen; i++) 9892 int i, j;
9075 active[i] = true; 9893 string d;
9076 9894
9077 offset[mlen] = srclen; 9895 m_host.AddScriptLPS(1);
9078 9896
9079 while (beginning < srclen) 9897 /*
9898 * Convert separator and spacer lists to C# strings.
9899 * Also filter out null strings so we don't hang.
9900 */
9901 for (i = 0; i < seplen; i ++)
9080 { 9902 {
9903 d = separray[i].ToString();
9904 if (d.Length > 0)
9905 {
9906 delarray[dellen++] = d;
9907 }
9908 }
9909 seplen = dellen;
9081 9910
9082 best = mlen; // as bad as it gets 9911 for (i = 0; i < spclen; i ++)
9912 {
9913 d = spcarray[i].ToString();
9914 if (d.Length > 0)
9915 {
9916 delarray[dellen++] = d;
9917 }
9918 }
9083 9919
9084 // Scan for separators 9920 /*
9921 * Scan through source string from beginning to end.
9922 */
9923 for (i = 0;;)
9924 {
9085 9925
9086 for (j = 0; j < seplen; j++) 9926 /*
9927 * Find earliest delimeter in src starting at i (if any).
9928 */
9929 int earliestDel = -1;
9930 int earliestSrc = srclen;
9931 string earliestStr = null;
9932 for (j = 0; j < dellen; j ++)
9087 { 9933 {
9088 if (separray[j].ToString() == String.Empty) 9934 d = delarray[j];
9089 active[j] = false; 9935 if (d != null)
9090
9091 if (active[j])
9092 { 9936 {
9093 // scan all of the markers 9937 int index = src.IndexOf(d, i);
9094 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9938 if (index < 0)
9095 { 9939 {
9096 // not present at all 9940 delarray[j] = null; // delim nowhere in src, don't check it anymore
9097 active[j] = false;
9098 } 9941 }
9099 else 9942 else if (index < earliestSrc)
9100 { 9943 {
9101 // present and correct 9944 earliestSrc = index; // where delimeter starts in source string
9102 if (offset[j] < offset[best]) 9945 earliestDel = j; // where delimeter is in delarray[]
9103 { 9946 earliestStr = d; // the delimeter string from delarray[]
9104 // closest so far 9947 if (index == i) break; // can't do any better than found at beg of string
9105 best = j;
9106 if (offset[best] == beginning)
9107 break;
9108 }
9109 } 9948 }
9110 } 9949 }
9111 } 9950 }
9112 9951
9113 // Scan for spacers 9952 /*
9114 9953 * Output source string starting at i through start of earliest delimeter.
9115 if (offset[best] != beginning) 9954 */
9955 if (keepNulls || (earliestSrc > i))
9116 { 9956 {
9117 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9957 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9118 {
9119 if (spcarray[j-seplen].ToString() == String.Empty)
9120 active[j] = false;
9121
9122 if (active[j])
9123 {
9124 // scan all of the markers
9125 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9126 {
9127 // not present at all
9128 active[j] = false;
9129 }
9130 else
9131 {
9132 // present and correct
9133 if (offset[j] < offset[best])
9134 {
9135 // closest so far
9136 best = j;
9137 }
9138 }
9139 }
9140 }
9141 } 9958 }
9142 9959
9143 // This is the normal exit from the scanning loop 9960 /*
9961 * If no delimeter found at or after i, we're done scanning.
9962 */
9963 if (earliestDel < 0) break;
9144 9964
9145 if (best == mlen) 9965 /*
9966 * If delimeter was a spacer, output the spacer.
9967 */
9968 if (earliestDel >= seplen)
9146 { 9969 {
9147 // no markers were found on this pass 9970 outarray[outlen++] = earliestStr;
9148 // so we're pretty much done
9149 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9150 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9151 break;
9152 } 9971 }
9153 9972
9154 // Otherwise we just add the newly delimited token 9973 /*
9155 // and recalculate where the search should continue. 9974 * Look at rest of src string following delimeter.
9156 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9975 */
9157 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9976 i = earliestSrc + earliestStr.Length;
9158
9159 if (best < seplen)
9160 {
9161 beginning = offset[best] + (separray[best].ToString()).Length;
9162 }
9163 else
9164 {
9165 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9166 string str = spcarray[best - seplen].ToString();
9167 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9168 tokens.Add(new LSL_String(str));
9169 }
9170 } 9977 }
9171 9978
9172 // This an awkward an not very intuitive boundary case. If the 9979 /*
9173 // last substring is a tokenizer, then there is an implied trailing 9980 * Make up an exact-sized output array suitable for an LSL_List object.
9174 // null list entry. Hopefully the single comparison will not be too 9981 */
9175 // arduous. Alternatively the 'break' could be replced with a return 9982 object[] outlist = new object[outlen];
9176 // but that's shabby programming. 9983 for (i = 0; i < outlen; i ++)
9177
9178 if ((beginning == srclen) && (keepNulls))
9179 { 9984 {
9180 if (srclen != 0) 9985 outlist[i] = new LSL_String(outarray[i]);
9181 tokens.Add(new LSL_String(""));
9182 } 9986 }
9183 9987 return new LSL_List(outlist);
9184 return tokens;
9185 }
9186
9187 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9188 {
9189 m_host.AddScriptLPS(1);
9190 return this.ParseString(src, separators, spacers, false);
9191 }
9192
9193 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9194 {
9195 m_host.AddScriptLPS(1);
9196 return this.ParseString(src, separators, spacers, true);
9197 } 9988 }
9198 9989
9199 public LSL_Integer llGetObjectPermMask(int mask) 9990 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9288,6 +10079,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9288 case 4: 10079 case 4:
9289 return (int)item.NextPermissions; 10080 return (int)item.NextPermissions;
9290 } 10081 }
10082 m_host.TaskInventory.LockItemsForRead(false);
9291 10083
9292 return -1; 10084 return -1;
9293 } 10085 }
@@ -9490,31 +10282,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9490 UUID key = new UUID(); 10282 UUID key = new UUID();
9491 if (UUID.TryParse(id, out key)) 10283 if (UUID.TryParse(id, out key))
9492 { 10284 {
9493 try 10285 // return total object mass
9494 { 10286 SceneObjectPart part = World.GetSceneObjectPart(key);
9495 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10287 if (part != null)
9496 if (obj != null) 10288 return part.ParentGroup.GetMass();
9497 return (double)obj.GetMass(); 10289
9498 // the object is null so the key is for an avatar 10290 // the object is null so the key is for an avatar
9499 ScenePresence avatar = World.GetScenePresence(key); 10291 ScenePresence avatar = World.GetScenePresence(key);
9500 if (avatar != null) 10292 if (avatar != null)
9501 if (avatar.IsChildAgent)
9502 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9503 // child agents have a mass of 1.0
9504 return 1;
9505 else
9506 return (double)avatar.GetMass();
9507 }
9508 catch (KeyNotFoundException)
9509 { 10293 {
9510 return 0; // The Object/Agent not in the region so just return zero 10294 if (avatar.IsChildAgent)
10295 {
10296 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10297 // child agents have a mass of 1.0
10298 return 1;
10299 }
10300 else
10301 {
10302 return (double)avatar.GetMass();
10303 }
9511 } 10304 }
9512 } 10305 }
9513 return 0; 10306 return 0;
9514 } 10307 }
9515 10308
9516 /// <summary> 10309 /// <summary>
9517 /// illListReplaceList removes the sub-list defined by the inclusive indices 10310 /// llListReplaceList removes the sub-list defined by the inclusive indices
9518 /// start and end and inserts the src list in its place. The inclusive 10311 /// start and end and inserts the src list in its place. The inclusive
9519 /// nature of the indices means that at least one element must be deleted 10312 /// nature of the indices means that at least one element must be deleted
9520 /// if the indices are within the bounds of the existing list. I.e. 2,2 10313 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9571,16 +10364,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9571 // based upon end. Note that if end exceeds the upper 10364 // based upon end. Note that if end exceeds the upper
9572 // bound in this case, the entire destination list 10365 // bound in this case, the entire destination list
9573 // is removed. 10366 // is removed.
9574 else 10367 else if (start == 0)
9575 { 10368 {
9576 if (end + 1 < dest.Length) 10369 if (end + 1 < dest.Length)
9577 {
9578 return src + dest.GetSublist(end + 1, -1); 10370 return src + dest.GetSublist(end + 1, -1);
9579 }
9580 else 10371 else
9581 {
9582 return src; 10372 return src;
9583 } 10373 }
10374 else // Start < 0
10375 {
10376 if (end + 1 < dest.Length)
10377 return dest.GetSublist(end + 1, -1);
10378 else
10379 return new LSL_List();
9584 } 10380 }
9585 } 10381 }
9586 // Finally, if start > end, we strip away a prefix and 10382 // Finally, if start > end, we strip away a prefix and
@@ -9631,17 +10427,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9631 int width = 0; 10427 int width = 0;
9632 int height = 0; 10428 int height = 0;
9633 10429
9634 ParcelMediaCommandEnum? commandToSend = null; 10430 uint commandToSend = 0;
9635 float time = 0.0f; // default is from start 10431 float time = 0.0f; // default is from start
9636 10432
9637 ScenePresence presence = null; 10433 ScenePresence presence = null;
9638 10434
9639 for (int i = 0; i < commandList.Data.Length; i++) 10435 for (int i = 0; i < commandList.Data.Length; i++)
9640 { 10436 {
9641 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10437 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9642 switch (command) 10438 switch (command)
9643 { 10439 {
9644 case ParcelMediaCommandEnum.Agent: 10440 case (uint)ParcelMediaCommandEnum.Agent:
9645 // we send only to one agent 10441 // we send only to one agent
9646 if ((i + 1) < commandList.Length) 10442 if ((i + 1) < commandList.Length)
9647 { 10443 {
@@ -9658,25 +10454,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9658 } 10454 }
9659 break; 10455 break;
9660 10456
9661 case ParcelMediaCommandEnum.Loop: 10457 case (uint)ParcelMediaCommandEnum.Loop:
9662 loop = 1; 10458 loop = 1;
9663 commandToSend = command; 10459 commandToSend = command;
9664 update = true; //need to send the media update packet to set looping 10460 update = true; //need to send the media update packet to set looping
9665 break; 10461 break;
9666 10462
9667 case ParcelMediaCommandEnum.Play: 10463 case (uint)ParcelMediaCommandEnum.Play:
9668 loop = 0; 10464 loop = 0;
9669 commandToSend = command; 10465 commandToSend = command;
9670 update = true; //need to send the media update packet to make sure it doesn't loop 10466 update = true; //need to send the media update packet to make sure it doesn't loop
9671 break; 10467 break;
9672 10468
9673 case ParcelMediaCommandEnum.Pause: 10469 case (uint)ParcelMediaCommandEnum.Pause:
9674 case ParcelMediaCommandEnum.Stop: 10470 case (uint)ParcelMediaCommandEnum.Stop:
9675 case ParcelMediaCommandEnum.Unload: 10471 case (uint)ParcelMediaCommandEnum.Unload:
9676 commandToSend = command; 10472 commandToSend = command;
9677 break; 10473 break;
9678 10474
9679 case ParcelMediaCommandEnum.Url: 10475 case (uint)ParcelMediaCommandEnum.Url:
9680 if ((i + 1) < commandList.Length) 10476 if ((i + 1) < commandList.Length)
9681 { 10477 {
9682 if (commandList.Data[i + 1] is LSL_String) 10478 if (commandList.Data[i + 1] is LSL_String)
@@ -9689,7 +10485,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9689 } 10485 }
9690 break; 10486 break;
9691 10487
9692 case ParcelMediaCommandEnum.Texture: 10488 case (uint)ParcelMediaCommandEnum.Texture:
9693 if ((i + 1) < commandList.Length) 10489 if ((i + 1) < commandList.Length)
9694 { 10490 {
9695 if (commandList.Data[i + 1] is LSL_String) 10491 if (commandList.Data[i + 1] is LSL_String)
@@ -9702,7 +10498,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9702 } 10498 }
9703 break; 10499 break;
9704 10500
9705 case ParcelMediaCommandEnum.Time: 10501 case (uint)ParcelMediaCommandEnum.Time:
9706 if ((i + 1) < commandList.Length) 10502 if ((i + 1) < commandList.Length)
9707 { 10503 {
9708 if (commandList.Data[i + 1] is LSL_Float) 10504 if (commandList.Data[i + 1] is LSL_Float)
@@ -9714,7 +10510,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9714 } 10510 }
9715 break; 10511 break;
9716 10512
9717 case ParcelMediaCommandEnum.AutoAlign: 10513 case (uint)ParcelMediaCommandEnum.AutoAlign:
9718 if ((i + 1) < commandList.Length) 10514 if ((i + 1) < commandList.Length)
9719 { 10515 {
9720 if (commandList.Data[i + 1] is LSL_Integer) 10516 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9728,7 +10524,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9728 } 10524 }
9729 break; 10525 break;
9730 10526
9731 case ParcelMediaCommandEnum.Type: 10527 case (uint)ParcelMediaCommandEnum.Type:
9732 if ((i + 1) < commandList.Length) 10528 if ((i + 1) < commandList.Length)
9733 { 10529 {
9734 if (commandList.Data[i + 1] is LSL_String) 10530 if (commandList.Data[i + 1] is LSL_String)
@@ -9741,7 +10537,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9741 } 10537 }
9742 break; 10538 break;
9743 10539
9744 case ParcelMediaCommandEnum.Desc: 10540 case (uint)ParcelMediaCommandEnum.Desc:
9745 if ((i + 1) < commandList.Length) 10541 if ((i + 1) < commandList.Length)
9746 { 10542 {
9747 if (commandList.Data[i + 1] is LSL_String) 10543 if (commandList.Data[i + 1] is LSL_String)
@@ -9754,7 +10550,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9754 } 10550 }
9755 break; 10551 break;
9756 10552
9757 case ParcelMediaCommandEnum.Size: 10553 case (uint)ParcelMediaCommandEnum.Size:
9758 if ((i + 2) < commandList.Length) 10554 if ((i + 2) < commandList.Length)
9759 { 10555 {
9760 if (commandList.Data[i + 1] is LSL_Integer) 10556 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9824,7 +10620,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9824 } 10620 }
9825 } 10621 }
9826 10622
9827 if (commandToSend != null) 10623 if (commandToSend != 0)
9828 { 10624 {
9829 // the commandList contained a start/stop/... command, too 10625 // the commandList contained a start/stop/... command, too
9830 if (presence == null) 10626 if (presence == null)
@@ -9861,7 +10657,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9861 10657
9862 if (aList.Data[i] != null) 10658 if (aList.Data[i] != null)
9863 { 10659 {
9864 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10660 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9865 { 10661 {
9866 case ParcelMediaCommandEnum.Url: 10662 case ParcelMediaCommandEnum.Url:
9867 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10663 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9918,15 +10714,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9918 10714
9919 if (quick_pay_buttons.Data.Length < 4) 10715 if (quick_pay_buttons.Data.Length < 4)
9920 { 10716 {
9921 LSLError("List must have at least 4 elements"); 10717 int x;
9922 return; 10718 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10719 {
10720 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10721 }
9923 } 10722 }
9924 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10723 int[] nPrice = new int[5];
9925 10724 nPrice[0] = price;
9926 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10725 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9927 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10726 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9928 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10727 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9929 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10728 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10729 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9930 m_host.ParentGroup.HasGroupChanged = true; 10730 m_host.ParentGroup.HasGroupChanged = true;
9931 } 10731 }
9932 10732
@@ -9943,7 +10743,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9943 return new LSL_Vector(); 10743 return new LSL_Vector();
9944 } 10744 }
9945 10745
9946 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10746// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10747 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9947 if (presence != null) 10748 if (presence != null)
9948 { 10749 {
9949 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10750 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9965,7 +10766,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9965 return new LSL_Rotation(); 10766 return new LSL_Rotation();
9966 } 10767 }
9967 10768
9968 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10769// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10770 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9969 if (presence != null) 10771 if (presence != null)
9970 { 10772 {
9971 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10773 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -10025,14 +10827,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10025 { 10827 {
10026 m_host.AddScriptLPS(1); 10828 m_host.AddScriptLPS(1);
10027 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10829 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10028 if (detectedParams == null) return; // only works on the first detected avatar 10830 if (detectedParams == null)
10029 10831 {
10832 if (m_host.ParentGroup.IsAttachment == true)
10833 {
10834 detectedParams = new DetectParams();
10835 detectedParams.Key = m_host.OwnerID;
10836 }
10837 else
10838 {
10839 return;
10840 }
10841 }
10842
10030 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10843 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10031 if (avatar != null) 10844 if (avatar != null)
10032 { 10845 {
10033 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10846 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10034 simname, pos, lookAt); 10847 simname, pos, lookAt);
10035 } 10848 }
10849
10036 ScriptSleep(1000); 10850 ScriptSleep(1000);
10037 } 10851 }
10038 10852
@@ -10156,12 +10970,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10156 10970
10157 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10971 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10158 object[] data = rules.Data; 10972 object[] data = rules.Data;
10159 for (int i = 0; i < data.Length; ++i) { 10973 for (int i = 0; i < data.Length; ++i)
10974 {
10160 int type = Convert.ToInt32(data[i++].ToString()); 10975 int type = Convert.ToInt32(data[i++].ToString());
10161 if (i >= data.Length) break; // odd number of entries => ignore the last 10976 if (i >= data.Length) break; // odd number of entries => ignore the last
10162 10977
10163 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10978 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10164 switch (type) { 10979 switch (type)
10980 {
10165 case ScriptBaseClass.CAMERA_FOCUS: 10981 case ScriptBaseClass.CAMERA_FOCUS:
10166 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10982 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10167 case ScriptBaseClass.CAMERA_POSITION: 10983 case ScriptBaseClass.CAMERA_POSITION:
@@ -10266,19 +11082,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10266 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11082 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10267 { 11083 {
10268 m_host.AddScriptLPS(1); 11084 m_host.AddScriptLPS(1);
10269 string ret = String.Empty; 11085
10270 string src1 = llBase64ToString(str1); 11086 if (str1 == String.Empty)
10271 string src2 = llBase64ToString(str2); 11087 return String.Empty;
10272 int c = 0; 11088 if (str2 == String.Empty)
10273 for (int i = 0; i < src1.Length; i++) 11089 return str1;
11090
11091 int len = str2.Length;
11092 if ((len % 4) != 0) // LL is EVIL!!!!
10274 { 11093 {
10275 ret += (char) (src1[i] ^ src2[c]); 11094 while (str2.EndsWith("="))
11095 str2 = str2.Substring(0, str2.Length - 1);
11096
11097 len = str2.Length;
11098 int mod = len % 4;
11099
11100 if (mod == 1)
11101 str2 = str2.Substring(0, str2.Length - 1);
11102 else if (mod == 2)
11103 str2 += "==";
11104 else if (mod == 3)
11105 str2 += "=";
11106 }
10276 11107
10277 c++; 11108 byte[] data1;
10278 if (c >= src2.Length) 11109 byte[] data2;
10279 c = 0; 11110 try
11111 {
11112 data1 = Convert.FromBase64String(str1);
11113 data2 = Convert.FromBase64String(str2);
10280 } 11114 }
10281 return llStringToBase64(ret); 11115 catch (Exception)
11116 {
11117 return new LSL_String(String.Empty);
11118 }
11119
11120 byte[] d2 = new Byte[data1.Length];
11121 int pos = 0;
11122
11123 if (data1.Length <= data2.Length)
11124 {
11125 Array.Copy(data2, 0, d2, 0, data1.Length);
11126 }
11127 else
11128 {
11129 while (pos < data1.Length)
11130 {
11131 len = data1.Length - pos;
11132 if (len > data2.Length)
11133 len = data2.Length;
11134
11135 Array.Copy(data2, 0, d2, pos, len);
11136 pos += len;
11137 }
11138 }
11139
11140 for (pos = 0 ; pos < data1.Length ; pos++ )
11141 data1[pos] ^= d2[pos];
11142
11143 return Convert.ToBase64String(data1);
10282 } 11144 }
10283 11145
10284 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11146 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10331,16 +11193,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10331 if (userAgent != null) 11193 if (userAgent != null)
10332 httpHeaders["User-Agent"] = userAgent; 11194 httpHeaders["User-Agent"] = userAgent;
10333 11195
11196 // See if the URL contains any header hacks
11197 string[] urlParts = url.Split(new char[] {'\n'});
11198 if (urlParts.Length > 1)
11199 {
11200 // Iterate the passed headers and parse them
11201 for (int i = 1 ; i < urlParts.Length ; i++ )
11202 {
11203 // The rest of those would be added to the body in SL.
11204 // Let's not do that.
11205 if (urlParts[i] == String.Empty)
11206 break;
11207
11208 // See if this could be a valid header
11209 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11210 if (headerParts.Length != 2)
11211 continue;
11212
11213 string headerName = headerParts[0].Trim();
11214 string headerValue = headerParts[1].Trim();
11215
11216 // Filter out headers that could be used to abuse
11217 // another system or cloak the request
11218 if (headerName.ToLower() == "x-secondlife-shard" ||
11219 headerName.ToLower() == "x-secondlife-object-name" ||
11220 headerName.ToLower() == "x-secondlife-object-key" ||
11221 headerName.ToLower() == "x-secondlife-region" ||
11222 headerName.ToLower() == "x-secondlife-local-position" ||
11223 headerName.ToLower() == "x-secondlife-local-velocity" ||
11224 headerName.ToLower() == "x-secondlife-local-rotation" ||
11225 headerName.ToLower() == "x-secondlife-owner-name" ||
11226 headerName.ToLower() == "x-secondlife-owner-key" ||
11227 headerName.ToLower() == "connection" ||
11228 headerName.ToLower() == "content-length" ||
11229 headerName.ToLower() == "from" ||
11230 headerName.ToLower() == "host" ||
11231 headerName.ToLower() == "proxy-authorization" ||
11232 headerName.ToLower() == "referer" ||
11233 headerName.ToLower() == "trailer" ||
11234 headerName.ToLower() == "transfer-encoding" ||
11235 headerName.ToLower() == "via" ||
11236 headerName.ToLower() == "authorization")
11237 continue;
11238
11239 httpHeaders[headerName] = headerValue;
11240 }
11241
11242 // Finally, strip any protocol specifier from the URL
11243 url = urlParts[0].Trim();
11244 int idx = url.IndexOf(" HTTP/");
11245 if (idx != -1)
11246 url = url.Substring(0, idx);
11247 }
11248
10334 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11249 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10335 Regex r = new Regex(authregex); 11250 Regex r = new Regex(authregex);
10336 int[] gnums = r.GetGroupNumbers(); 11251 int[] gnums = r.GetGroupNumbers();
10337 Match m = r.Match(url); 11252 Match m = r.Match(url);
10338 if (m.Success) { 11253 if (m.Success)
10339 for (int i = 1; i < gnums.Length; i++) { 11254 {
11255 for (int i = 1; i < gnums.Length; i++)
11256 {
10340 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11257 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10341 //CaptureCollection cc = g.Captures; 11258 //CaptureCollection cc = g.Captures;
10342 } 11259 }
10343 if (m.Groups.Count == 5) { 11260 if (m.Groups.Count == 5)
11261 {
10344 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11262 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10345 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11263 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10346 } 11264 }
@@ -10543,6 +11461,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10543 11461
10544 LSL_List ret = new LSL_List(); 11462 LSL_List ret = new LSL_List();
10545 UUID key = new UUID(); 11463 UUID key = new UUID();
11464
11465
10546 if (UUID.TryParse(id, out key)) 11466 if (UUID.TryParse(id, out key))
10547 { 11467 {
10548 ScenePresence av = World.GetScenePresence(key); 11468 ScenePresence av = World.GetScenePresence(key);
@@ -10560,13 +11480,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10560 ret.Add(new LSL_String("")); 11480 ret.Add(new LSL_String(""));
10561 break; 11481 break;
10562 case ScriptBaseClass.OBJECT_POS: 11482 case ScriptBaseClass.OBJECT_POS:
10563 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11483 Vector3 avpos;
11484
11485 if (av.ParentID != 0 && av.ParentPart != null)
11486 {
11487 avpos = av.OffsetPosition;
11488
11489 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11490 avpos -= sitOffset;
11491
11492 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11493 }
11494 else
11495 avpos = av.AbsolutePosition;
11496
11497 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10564 break; 11498 break;
10565 case ScriptBaseClass.OBJECT_ROT: 11499 case ScriptBaseClass.OBJECT_ROT:
10566 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11500 Quaternion avrot = av.Rotation;
11501 if (av.ParentID != 0 && av.ParentPart != null)
11502 {
11503 avrot = av.ParentPart.GetWorldRotation() * avrot;
11504 }
11505 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10567 break; 11506 break;
10568 case ScriptBaseClass.OBJECT_VELOCITY: 11507 case ScriptBaseClass.OBJECT_VELOCITY:
10569 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11508 Vector3 avvel = av.Velocity;
11509 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10570 break; 11510 break;
10571 case ScriptBaseClass.OBJECT_OWNER: 11511 case ScriptBaseClass.OBJECT_OWNER:
10572 ret.Add(new LSL_String(id)); 11512 ret.Add(new LSL_String(id));
@@ -10651,11 +11591,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10651 case ScriptBaseClass.OBJECT_NAME: 11591 case ScriptBaseClass.OBJECT_NAME:
10652 ret.Add(new LSL_String(obj.Name)); 11592 ret.Add(new LSL_String(obj.Name));
10653 break; 11593 break;
10654 case ScriptBaseClass.OBJECT_DESC: 11594 case ScriptBaseClass.OBJECT_DESC:
10655 ret.Add(new LSL_String(obj.Description)); 11595 ret.Add(new LSL_String(obj.Description));
10656 break; 11596 break;
10657 case ScriptBaseClass.OBJECT_POS: 11597 case ScriptBaseClass.OBJECT_POS:
10658 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11598 Vector3 opos = obj.AbsolutePosition;
11599 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10659 break; 11600 break;
10660 case ScriptBaseClass.OBJECT_ROT: 11601 case ScriptBaseClass.OBJECT_ROT:
10661 { 11602 {
@@ -10705,9 +11646,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10705 // The value returned in SL for normal prims is prim count 11646 // The value returned in SL for normal prims is prim count
10706 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11647 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10707 break; 11648 break;
10708 // The following 3 costs I have intentionaly coded to return zero. They are part of 11649
10709 // "Land Impact" calculations. These calculations are probably not applicable 11650 // costs below may need to be diferent for root parts, need to check
10710 // to OpenSim and are not yet complete in SL
10711 case ScriptBaseClass.OBJECT_SERVER_COST: 11651 case ScriptBaseClass.OBJECT_SERVER_COST:
10712 // The linden calculation is here 11652 // The linden calculation is here
10713 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11653 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10715,16 +11655,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10715 ret.Add(new LSL_Float(0)); 11655 ret.Add(new LSL_Float(0));
10716 break; 11656 break;
10717 case ScriptBaseClass.OBJECT_STREAMING_COST: 11657 case ScriptBaseClass.OBJECT_STREAMING_COST:
10718 // The linden calculation is here 11658 // The value returned in SL for normal prims is prim count * 0.06
10719 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11659 ret.Add(new LSL_Float(obj.StreamingCost));
10720 // The value returned in SL for normal prims looks like the prim count * 0.06
10721 ret.Add(new LSL_Float(0));
10722 break; 11660 break;
10723 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11661 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10724 // The linden calculation is here 11662 // The value returned in SL for normal prims is prim count
10725 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11663 ret.Add(new LSL_Float(obj.PhysicsCost));
10726 // The value returned in SL for normal prims looks like the prim count
10727 ret.Add(new LSL_Float(0));
10728 break; 11664 break;
10729 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11665 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
10730 ret.Add(new LSL_Float(0)); 11666 ret.Add(new LSL_Float(0));
@@ -10981,15 +11917,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10981 return result; 11917 return result;
10982 } 11918 }
10983 11919
10984 public void print(string str) 11920 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10985 { 11921 {
10986 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11922 List<SceneObjectPart> parts = GetLinkParts(link);
10987 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11923 if (parts.Count < 1)
10988 if (ossl != null) 11924 return 0;
10989 { 11925
10990 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11926 return GetNumberOfSides(parts[0]);
10991 m_log.Info("LSL print():" + str);
10992 }
10993 } 11927 }
10994 11928
10995 private string Name2Username(string name) 11929 private string Name2Username(string name)
@@ -11034,7 +11968,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11034 11968
11035 return rq.ToString(); 11969 return rq.ToString();
11036 } 11970 }
11037 11971/*
11972 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11973 {
11974 m_SayShoutCount = 0;
11975 }
11976*/
11038 private struct Tri 11977 private struct Tri
11039 { 11978 {
11040 public Vector3 p1; 11979 public Vector3 p1;
@@ -11183,9 +12122,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11183 12122
11184 ContactResult result = new ContactResult (); 12123 ContactResult result = new ContactResult ();
11185 result.ConsumerID = group.LocalId; 12124 result.ConsumerID = group.LocalId;
11186 result.Depth = intersection.distance; 12125// result.Depth = intersection.distance;
11187 result.Normal = intersection.normal; 12126 result.Normal = intersection.normal;
11188 result.Pos = intersection.ipoint; 12127 result.Pos = intersection.ipoint;
12128 result.Depth = Vector3.Mag(rayStart - result.Pos);
11189 12129
11190 contacts.Add(result); 12130 contacts.Add(result);
11191 }); 12131 });
@@ -11318,6 +12258,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11318 12258
11319 return contacts[0]; 12259 return contacts[0];
11320 } 12260 }
12261/*
12262 // not done:
12263 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12264 {
12265 ContactResult[] contacts = null;
12266 World.ForEachSOG(delegate(SceneObjectGroup group)
12267 {
12268 if (m_host.ParentGroup == group)
12269 return;
12270
12271 if (group.IsAttachment)
12272 return;
12273
12274 if(group.RootPart.PhysActor != null)
12275 return;
12276
12277 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12278 });
12279 return contacts;
12280 }
12281*/
11321 12282
11322 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12283 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11323 { 12284 {
@@ -11441,18 +12402,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11441 } 12402 }
11442 } 12403 }
11443 12404
12405 // Double check this
11444 if (checkTerrain) 12406 if (checkTerrain)
11445 { 12407 {
11446 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12408 bool skipGroundCheck = false;
11447 if (groundContact != null) 12409
11448 results.Add((ContactResult)groundContact); 12410 foreach (ContactResult c in results)
12411 {
12412 if (c.ConsumerID == 0) // Physics gave us a ground collision
12413 skipGroundCheck = true;
12414 }
12415
12416 if (!skipGroundCheck)
12417 {
12418 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12419 if (groundContact != null)
12420 results.Add((ContactResult)groundContact);
12421 }
11449 } 12422 }
11450 12423
11451 results.Sort(delegate(ContactResult a, ContactResult b) 12424 results.Sort(delegate(ContactResult a, ContactResult b)
11452 { 12425 {
11453 return a.Depth.CompareTo(b.Depth); 12426 return a.Depth.CompareTo(b.Depth);
11454 }); 12427 });
11455 12428
11456 int values = 0; 12429 int values = 0;
11457 SceneObjectGroup thisgrp = m_host.ParentGroup; 12430 SceneObjectGroup thisgrp = m_host.ParentGroup;
11458 12431
@@ -11545,7 +12518,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11545 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12518 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11546 if (!isAccount) return 0; 12519 if (!isAccount) return 0;
11547 if (estate.HasAccess(id)) return 1; 12520 if (estate.HasAccess(id)) return 1;
11548 if (estate.IsBanned(id)) 12521 if (estate.IsBanned(id, World.GetUserFlags(id)))
11549 estate.RemoveBan(id); 12522 estate.RemoveBan(id);
11550 estate.AddEstateUser(id); 12523 estate.AddEstateUser(id);
11551 break; 12524 break;
@@ -11564,14 +12537,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11564 break; 12537 break;
11565 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12538 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11566 if (!isAccount) return 0; 12539 if (!isAccount) return 0;
11567 if (estate.IsBanned(id)) return 1; 12540 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11568 EstateBan ban = new EstateBan(); 12541 EstateBan ban = new EstateBan();
11569 ban.EstateID = estate.EstateID; 12542 ban.EstateID = estate.EstateID;
11570 ban.BannedUserID = id; 12543 ban.BannedUserID = id;
11571 estate.AddBan(ban); 12544 estate.AddBan(ban);
11572 break; 12545 break;
11573 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12546 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11574 if (!isAccount || !estate.IsBanned(id)) return 0; 12547 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11575 estate.RemoveBan(id); 12548 estate.RemoveBan(id);
11576 break; 12549 break;
11577 default: return 0; 12550 default: return 0;
@@ -11600,7 +12573,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11600 return 16384; 12573 return 16384;
11601 } 12574 }
11602 12575
11603 public LSL_Integer llGetUsedMemory() 12576 public virtual LSL_Integer llGetUsedMemory()
11604 { 12577 {
11605 m_host.AddScriptLPS(1); 12578 m_host.AddScriptLPS(1);
11606 // The value returned for LSO scripts in SL 12579 // The value returned for LSO scripts in SL
@@ -11628,19 +12601,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11628 public void llSetSoundQueueing(int queue) 12601 public void llSetSoundQueueing(int queue)
11629 { 12602 {
11630 m_host.AddScriptLPS(1); 12603 m_host.AddScriptLPS(1);
11631 NotImplemented("llSetSoundQueueing");
11632 } 12604 }
11633 12605
11634 public void llCollisionSprite(string impact_sprite) 12606 public void llCollisionSprite(string impact_sprite)
11635 { 12607 {
11636 m_host.AddScriptLPS(1); 12608 m_host.AddScriptLPS(1);
11637 NotImplemented("llCollisionSprite"); 12609 // Viewer 2.0 broke this and it's likely LL has no intention
12610 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11638 } 12611 }
11639 12612
11640 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12613 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11641 { 12614 {
11642 m_host.AddScriptLPS(1); 12615 m_host.AddScriptLPS(1);
11643 NotImplemented("llGodLikeRezObject"); 12616
12617 if (!World.Permissions.IsGod(m_host.OwnerID))
12618 NotImplemented("llGodLikeRezObject");
12619
12620 AssetBase rezAsset = World.AssetService.Get(inventory);
12621 if (rezAsset == null)
12622 {
12623 llSay(0, "Asset not found");
12624 return;
12625 }
12626
12627 SceneObjectGroup group = null;
12628
12629 try
12630 {
12631 string xmlData = Utils.BytesToString(rezAsset.Data);
12632 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12633 }
12634 catch
12635 {
12636 llSay(0, "Asset not found");
12637 return;
12638 }
12639
12640 if (group == null)
12641 {
12642 llSay(0, "Asset not found");
12643 return;
12644 }
12645
12646 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12647 group.RootPart.AttachOffset = group.AbsolutePosition;
12648
12649 group.ResetIDs();
12650
12651 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12652 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12653 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12654 group.ScheduleGroupForFullUpdate();
12655
12656 // objects rezzed with this method are die_at_edge by default.
12657 group.RootPart.SetDieAtEdge(true);
12658
12659 group.ResumeScripts();
12660
12661 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12662 "object_rez", new Object[] {
12663 new LSL_String(
12664 group.RootPart.UUID.ToString()) },
12665 new DetectParams[0]));
11644 } 12666 }
11645 12667
11646 public LSL_String llTransferLindenDollars(string destination, int amount) 12668 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -11692,7 +12714,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11692 } 12714 }
11693 12715
11694 bool result = money.ObjectGiveMoney( 12716 bool result = money.ObjectGiveMoney(
11695 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12717 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn);
11696 12718
11697 if (result) 12719 if (result)
11698 { 12720 {
@@ -11717,6 +12739,598 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11717 } 12739 }
11718 12740
11719 #endregion 12741 #endregion
12742
12743 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12744 {
12745 SceneObjectGroup group = m_host.ParentGroup;
12746
12747 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12748 return;
12749 if (group.IsAttachment)
12750 return;
12751
12752 if (frames.Data.Length > 0) // We are getting a new motion
12753 {
12754 if (group.RootPart.KeyframeMotion != null)
12755 group.RootPart.KeyframeMotion.Delete();
12756 group.RootPart.KeyframeMotion = null;
12757
12758 int idx = 0;
12759
12760 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12761 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12762
12763 while (idx < options.Data.Length)
12764 {
12765 int option = (int)options.GetLSLIntegerItem(idx++);
12766 int remain = options.Data.Length - idx;
12767
12768 switch (option)
12769 {
12770 case ScriptBaseClass.KFM_MODE:
12771 if (remain < 1)
12772 break;
12773 int modeval = (int)options.GetLSLIntegerItem(idx++);
12774 switch(modeval)
12775 {
12776 case ScriptBaseClass.KFM_FORWARD:
12777 mode = KeyframeMotion.PlayMode.Forward;
12778 break;
12779 case ScriptBaseClass.KFM_REVERSE:
12780 mode = KeyframeMotion.PlayMode.Reverse;
12781 break;
12782 case ScriptBaseClass.KFM_LOOP:
12783 mode = KeyframeMotion.PlayMode.Loop;
12784 break;
12785 case ScriptBaseClass.KFM_PING_PONG:
12786 mode = KeyframeMotion.PlayMode.PingPong;
12787 break;
12788 }
12789 break;
12790 case ScriptBaseClass.KFM_DATA:
12791 if (remain < 1)
12792 break;
12793 int dataval = (int)options.GetLSLIntegerItem(idx++);
12794 data = (KeyframeMotion.DataFormat)dataval;
12795 break;
12796 }
12797 }
12798
12799 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12800
12801 idx = 0;
12802
12803 int elemLength = 2;
12804 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12805 elemLength = 3;
12806
12807 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12808 while (idx < frames.Data.Length)
12809 {
12810 int remain = frames.Data.Length - idx;
12811
12812 if (remain < elemLength)
12813 break;
12814
12815 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12816 frame.Position = null;
12817 frame.Rotation = null;
12818
12819 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12820 {
12821 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12822 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12823 }
12824 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12825 {
12826 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12827 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12828 q.Normalize();
12829 frame.Rotation = q;
12830 }
12831
12832 float tempf = (float)frames.GetLSLFloatItem(idx++);
12833 frame.TimeMS = (int)(tempf * 1000.0f);
12834
12835 keyframes.Add(frame);
12836 }
12837
12838 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12839 group.RootPart.KeyframeMotion.Start();
12840 }
12841 else
12842 {
12843 if (group.RootPart.KeyframeMotion == null)
12844 return;
12845
12846 if (options.Data.Length == 0)
12847 {
12848 group.RootPart.KeyframeMotion.Stop();
12849 return;
12850 }
12851
12852 int code = (int)options.GetLSLIntegerItem(0);
12853
12854 int idx = 0;
12855
12856 while (idx < options.Data.Length)
12857 {
12858 int option = (int)options.GetLSLIntegerItem(idx++);
12859 int remain = options.Data.Length - idx;
12860
12861 switch (option)
12862 {
12863 case ScriptBaseClass.KFM_COMMAND:
12864 int cmd = (int)options.GetLSLIntegerItem(idx++);
12865 switch (cmd)
12866 {
12867 case ScriptBaseClass.KFM_CMD_PLAY:
12868 group.RootPart.KeyframeMotion.Start();
12869 break;
12870 case ScriptBaseClass.KFM_CMD_STOP:
12871 group.RootPart.KeyframeMotion.Stop();
12872 break;
12873 case ScriptBaseClass.KFM_CMD_PAUSE:
12874 group.RootPart.KeyframeMotion.Pause();
12875 break;
12876 }
12877 break;
12878 }
12879 }
12880 }
12881 }
12882
12883 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12884 {
12885 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12886
12887 int idx = 0;
12888 int idxStart = 0;
12889
12890 bool positionChanged = false;
12891 Vector3 finalPos = Vector3.Zero;
12892
12893 try
12894 {
12895 while (idx < rules.Length)
12896 {
12897 ++rulesParsed;
12898 int code = rules.GetLSLIntegerItem(idx++);
12899
12900 int remain = rules.Length - idx;
12901 idxStart = idx;
12902
12903 switch (code)
12904 {
12905 case (int)ScriptBaseClass.PRIM_POSITION:
12906 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12907 {
12908 if (remain < 1)
12909 return null;
12910
12911 LSL_Vector v;
12912 v = rules.GetVector3Item(idx++);
12913
12914 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12915 if (part == null)
12916 break;
12917
12918 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12919 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12920 if (part.LinkNum > 1)
12921 {
12922 localRot = GetPartLocalRot(part);
12923 localPos = GetPartLocalPos(part);
12924 }
12925
12926 v -= localPos;
12927 v /= localRot;
12928
12929 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12930
12931 v = v + 2 * sitOffset;
12932
12933 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12934 av.SendAvatarDataToAllAgents();
12935
12936 }
12937 break;
12938
12939 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12940 case (int)ScriptBaseClass.PRIM_ROTATION:
12941 {
12942 if (remain < 1)
12943 return null;
12944
12945 LSL_Rotation r;
12946 r = rules.GetQuaternionItem(idx++);
12947
12948 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12949 if (part == null)
12950 break;
12951
12952 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12953 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12954
12955 if (part.LinkNum > 1)
12956 localRot = GetPartLocalRot(part);
12957
12958 r = r * llGetRootRotation() / localRot;
12959 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12960 av.SendAvatarDataToAllAgents();
12961 }
12962 break;
12963
12964 // parse rest doing nothing but number of parameters error check
12965 case (int)ScriptBaseClass.PRIM_SIZE:
12966 case (int)ScriptBaseClass.PRIM_MATERIAL:
12967 case (int)ScriptBaseClass.PRIM_PHANTOM:
12968 case (int)ScriptBaseClass.PRIM_PHYSICS:
12969 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12970 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12971 case (int)ScriptBaseClass.PRIM_NAME:
12972 case (int)ScriptBaseClass.PRIM_DESC:
12973 if (remain < 1)
12974 return null;
12975 idx++;
12976 break;
12977
12978 case (int)ScriptBaseClass.PRIM_GLOW:
12979 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12980 case (int)ScriptBaseClass.PRIM_TEXGEN:
12981 if (remain < 2)
12982 return null;
12983 idx += 2;
12984 break;
12985
12986 case (int)ScriptBaseClass.PRIM_TYPE:
12987 if (remain < 3)
12988 return null;
12989 code = (int)rules.GetLSLIntegerItem(idx++);
12990 remain = rules.Length - idx;
12991 switch (code)
12992 {
12993 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12994 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12995 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12996 if (remain < 6)
12997 return null;
12998 idx += 6;
12999 break;
13000
13001 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
13002 if (remain < 5)
13003 return null;
13004 idx += 5;
13005 break;
13006
13007 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
13008 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
13009 case (int)ScriptBaseClass.PRIM_TYPE_RING:
13010 if (remain < 11)
13011 return null;
13012 idx += 11;
13013 break;
13014
13015 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
13016 if (remain < 2)
13017 return null;
13018 idx += 2;
13019 break;
13020 }
13021 break;
13022
13023 case (int)ScriptBaseClass.PRIM_COLOR:
13024 case (int)ScriptBaseClass.PRIM_TEXT:
13025 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13026 case (int)ScriptBaseClass.PRIM_OMEGA:
13027 if (remain < 3)
13028 return null;
13029 idx += 3;
13030 break;
13031
13032 case (int)ScriptBaseClass.PRIM_TEXTURE:
13033 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13034 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
13035 if (remain < 5)
13036 return null;
13037 idx += 5;
13038 break;
13039
13040 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13041 if (remain < 7)
13042 return null;
13043
13044 idx += 7;
13045 break;
13046
13047 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13048 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13049 return null;
13050
13051 return rules.GetSublist(idx, -1);
13052 }
13053 }
13054 }
13055 catch (InvalidCastException e)
13056 {
13057 ShoutError(string.Format(
13058 "{0} error running rule #{1}: arg #{2} ",
13059 originFunc, rulesParsed, idx - idxStart) + e.Message);
13060 }
13061 finally
13062 {
13063 if (positionChanged)
13064 {
13065 av.OffsetPosition = finalPos;
13066// av.SendAvatarDataToAllAgents();
13067 av.SendTerseUpdateToAllClients();
13068 positionChanged = false;
13069 }
13070 }
13071 return null;
13072 }
13073
13074 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13075 {
13076 // avatars case
13077 // replies as SL wiki
13078
13079// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13080 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13081
13082 int idx = 0;
13083 while (idx < rules.Length)
13084 {
13085 int code = (int)rules.GetLSLIntegerItem(idx++);
13086 int remain = rules.Length - idx;
13087
13088 switch (code)
13089 {
13090 case (int)ScriptBaseClass.PRIM_MATERIAL:
13091 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13092 break;
13093
13094 case (int)ScriptBaseClass.PRIM_PHYSICS:
13095 res.Add(new LSL_Integer(0));
13096 break;
13097
13098 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13099 res.Add(new LSL_Integer(0));
13100 break;
13101
13102 case (int)ScriptBaseClass.PRIM_PHANTOM:
13103 res.Add(new LSL_Integer(0));
13104 break;
13105
13106 case (int)ScriptBaseClass.PRIM_POSITION:
13107
13108 Vector3 pos = avatar.OffsetPosition;
13109
13110 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13111 pos -= sitOffset;
13112
13113 if( sitPart != null)
13114 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13115
13116 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13117 break;
13118
13119 case (int)ScriptBaseClass.PRIM_SIZE:
13120 // as in llGetAgentSize above
13121// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13122 Vector3 s = avatar.Appearance.AvatarSize;
13123 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13124
13125 break;
13126
13127 case (int)ScriptBaseClass.PRIM_ROTATION:
13128 Quaternion rot = avatar.Rotation;
13129 if (sitPart != null)
13130 {
13131 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13132 }
13133
13134 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13135 break;
13136
13137 case (int)ScriptBaseClass.PRIM_TYPE:
13138 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13139 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13140 res.Add(new LSL_Vector(0f,1.0f,0f));
13141 res.Add(new LSL_Float(0.0f));
13142 res.Add(new LSL_Vector(0, 0, 0));
13143 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13144 res.Add(new LSL_Vector(0, 0, 0));
13145 break;
13146
13147 case (int)ScriptBaseClass.PRIM_TEXTURE:
13148 if (remain < 1)
13149 return null;
13150
13151 int face = (int)rules.GetLSLIntegerItem(idx++);
13152 if (face == ScriptBaseClass.ALL_SIDES)
13153 {
13154 for (face = 0; face < 21; face++)
13155 {
13156 res.Add(new LSL_String(""));
13157 res.Add(new LSL_Vector(0,0,0));
13158 res.Add(new LSL_Vector(0,0,0));
13159 res.Add(new LSL_Float(0.0));
13160 }
13161 }
13162 else
13163 {
13164 if (face >= 0 && face < 21)
13165 {
13166 res.Add(new LSL_String(""));
13167 res.Add(new LSL_Vector(0,0,0));
13168 res.Add(new LSL_Vector(0,0,0));
13169 res.Add(new LSL_Float(0.0));
13170 }
13171 }
13172 break;
13173
13174 case (int)ScriptBaseClass.PRIM_COLOR:
13175 if (remain < 1)
13176 return null;
13177
13178 face = (int)rules.GetLSLIntegerItem(idx++);
13179
13180 if (face == ScriptBaseClass.ALL_SIDES)
13181 {
13182 for (face = 0; face < 21; face++)
13183 {
13184 res.Add(new LSL_Vector(0,0,0));
13185 res.Add(new LSL_Float(0));
13186 }
13187 }
13188 else
13189 {
13190 res.Add(new LSL_Vector(0,0,0));
13191 res.Add(new LSL_Float(0));
13192 }
13193 break;
13194
13195 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13196 if (remain < 1)
13197 return null;
13198 face = (int)rules.GetLSLIntegerItem(idx++);
13199
13200 if (face == ScriptBaseClass.ALL_SIDES)
13201 {
13202 for (face = 0; face < 21; face++)
13203 {
13204 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13205 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13206 }
13207 }
13208 else
13209 {
13210 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13211 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13212 }
13213 break;
13214
13215 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13216 if (remain < 1)
13217 return null;
13218 face = (int)rules.GetLSLIntegerItem(idx++);
13219
13220 if (face == ScriptBaseClass.ALL_SIDES)
13221 {
13222 for (face = 0; face < 21; face++)
13223 {
13224 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13225 }
13226 }
13227 else
13228 {
13229 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13230 }
13231 break;
13232
13233 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13234 res.Add(new LSL_Integer(0));
13235 res.Add(new LSL_Integer(0));// softness
13236 res.Add(new LSL_Float(0.0f)); // gravity
13237 res.Add(new LSL_Float(0.0f)); // friction
13238 res.Add(new LSL_Float(0.0f)); // wind
13239 res.Add(new LSL_Float(0.0f)); // tension
13240 res.Add(new LSL_Vector(0f,0f,0f));
13241 break;
13242
13243 case (int)ScriptBaseClass.PRIM_TEXGEN:
13244 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13245 if (remain < 1)
13246 return null;
13247 face = (int)rules.GetLSLIntegerItem(idx++);
13248
13249 if (face == ScriptBaseClass.ALL_SIDES)
13250 {
13251 for (face = 0; face < 21; face++)
13252 {
13253 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13254 }
13255 }
13256 else
13257 {
13258 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13259 }
13260 break;
13261
13262 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13263 res.Add(new LSL_Integer(0));
13264 res.Add(new LSL_Vector(0f,0f,0f));
13265 res.Add(new LSL_Float(0f)); // intensity
13266 res.Add(new LSL_Float(0f)); // radius
13267 res.Add(new LSL_Float(0f)); // falloff
13268 break;
13269
13270 case (int)ScriptBaseClass.PRIM_GLOW:
13271 if (remain < 1)
13272 return null;
13273 face = (int)rules.GetLSLIntegerItem(idx++);
13274
13275 if (face == ScriptBaseClass.ALL_SIDES)
13276 {
13277 for (face = 0; face < 21; face++)
13278 {
13279 res.Add(new LSL_Float(0f));
13280 }
13281 }
13282 else
13283 {
13284 res.Add(new LSL_Float(0f));
13285 }
13286 break;
13287
13288 case (int)ScriptBaseClass.PRIM_TEXT:
13289 res.Add(new LSL_String(""));
13290 res.Add(new LSL_Vector(0f,0f,0f));
13291 res.Add(new LSL_Float(1.0f));
13292 break;
13293
13294 case (int)ScriptBaseClass.PRIM_NAME:
13295 res.Add(new LSL_String(avatar.Name));
13296 break;
13297
13298 case (int)ScriptBaseClass.PRIM_DESC:
13299 res.Add(new LSL_String(""));
13300 break;
13301
13302 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13303 Quaternion lrot = avatar.Rotation;
13304
13305 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13306 {
13307 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13308 }
13309 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13310 break;
13311
13312 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13313 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13314 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13315 lpos -= lsitOffset;
13316
13317 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13318 {
13319 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13320 }
13321 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13322 break;
13323
13324 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13325 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13326 return null;
13327
13328 return rules.GetSublist(idx, -1);
13329 }
13330 }
13331
13332 return null;
13333 }
11720 } 13334 }
11721 13335
11722 public class NotecardCache 13336 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 1426070..6ff6b00 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;
@@ -148,6 +149,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
148 m_ScriptEngine = scriptEngine; 149 m_ScriptEngine = scriptEngine;
149 m_host = host; 150 m_host = host;
150 m_item = item; 151 m_item = item;
152 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
151 153
152 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 154 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
153 155
@@ -211,7 +213,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
211 213
212 internal void OSSLError(string msg) 214 internal void OSSLError(string msg)
213 { 215 {
214 throw new ScriptException("OSSL Runtime Error: " + msg); 216 if (m_debuggerSafe)
217 {
218 OSSLShoutError(msg);
219 }
220 else
221 {
222 throw new ScriptException("OSSL Runtime Error: " + msg);
223 }
215 } 224 }
216 225
217 /// <summary> 226 /// <summary>
@@ -930,18 +939,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
930 if (target != null) 939 if (target != null)
931 { 940 {
932 UUID animID=UUID.Zero; 941 UUID animID=UUID.Zero;
933 lock (m_host.TaskInventory) 942 m_host.TaskInventory.LockItemsForRead(true);
943 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
934 { 944 {
935 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 945 if (inv.Value.Name == animation)
936 { 946 {
937 if (inv.Value.Name == animation) 947 if (inv.Value.Type == (int)AssetType.Animation)
938 { 948 animID = inv.Value.AssetID;
939 if (inv.Value.Type == (int)AssetType.Animation) 949 continue;
940 animID = inv.Value.AssetID;
941 continue;
942 }
943 } 950 }
944 } 951 }
952 m_host.TaskInventory.LockItemsForRead(false);
945 if (animID == UUID.Zero) 953 if (animID == UUID.Zero)
946 target.Animator.AddAnimation(animation, m_host.UUID); 954 target.Animator.AddAnimation(animation, m_host.UUID);
947 else 955 else
@@ -982,6 +990,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
982 else 990 else
983 animID = UUID.Zero; 991 animID = UUID.Zero;
984 } 992 }
993 m_host.TaskInventory.LockItemsForRead(false);
985 994
986 if (animID == UUID.Zero) 995 if (animID == UUID.Zero)
987 target.Animator.RemoveAnimation(animation); 996 target.Animator.RemoveAnimation(animation);
@@ -1848,15 +1857,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1848 { 1857 {
1849 UUID assetID = UUID.Zero; 1858 UUID assetID = UUID.Zero;
1850 1859
1851 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1860 bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID);
1861
1862 if (!notecardNameIsUUID)
1852 { 1863 {
1853 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1864 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1854 {
1855 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1856 {
1857 assetID = item.AssetID;
1858 }
1859 }
1860 } 1865 }
1861 1866
1862 if (assetID == UUID.Zero) 1867 if (assetID == UUID.Zero)
@@ -1867,7 +1872,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1867 AssetBase a = World.AssetService.Get(assetID.ToString()); 1872 AssetBase a = World.AssetService.Get(assetID.ToString());
1868 1873
1869 if (a == null) 1874 if (a == null)
1870 return UUID.Zero; 1875 {
1876 // Whoops, it's still possible here that the notecard name was properly
1877 // formatted like a UUID but isn't an asset UUID so lets look it up by name after all
1878 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1879 if (assetID == UUID.Zero)
1880 return UUID.Zero;
1881
1882 if (!NotecardCache.IsCached(assetID))
1883 {
1884 a = World.AssetService.Get(assetID.ToString());
1885
1886 if (a == null)
1887 {
1888 return UUID.Zero;
1889 }
1890 }
1891 }
1871 1892
1872 string data = Encoding.UTF8.GetString(a.Data); 1893 string data = Encoding.UTF8.GetString(a.Data);
1873 NotecardCache.Cache(assetID, data); 1894 NotecardCache.Cache(assetID, data);
@@ -1875,6 +1896,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1875 1896
1876 return assetID; 1897 return assetID;
1877 } 1898 }
1899 protected UUID SearchTaskInventoryForAssetId(string name)
1900 {
1901 UUID assetId = UUID.Zero;
1902 m_host.TaskInventory.LockItemsForRead(true);
1903 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1904 {
1905 if (item.Type == 7 && item.Name == name)
1906 {
1907 assetId = item.AssetID;
1908 }
1909 }
1910 m_host.TaskInventory.LockItemsForRead(false);
1911 return assetId;
1912 }
1878 1913
1879 /// <summary> 1914 /// <summary>
1880 /// Directly get an entire notecard at once. 1915 /// Directly get an entire notecard at once.
@@ -2342,7 +2377,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2342 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2377 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2343 m_host.AddScriptLPS(1); 2378 m_host.AddScriptLPS(1);
2344 2379
2345 return NpcCreate(firstname, lastname, position, notecard, false, false); 2380 return NpcCreate(firstname, lastname, position, notecard, true, false);
2346 } 2381 }
2347 2382
2348 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2383 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2353,24 +2388,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2353 return NpcCreate( 2388 return NpcCreate(
2354 firstname, lastname, position, notecard, 2389 firstname, lastname, position, notecard,
2355 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2390 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2356 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2391 false);
2392// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2357 } 2393 }
2358 2394
2359 private LSL_Key NpcCreate( 2395 private LSL_Key NpcCreate(
2360 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2396 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2361 { 2397 {
2398 if (!owned)
2399 OSSLError("Unowned NPCs are unsupported");
2400
2401 string groupTitle = String.Empty;
2402
2403 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2404 return new LSL_Key(UUID.Zero.ToString());
2405
2406 if (firstname != String.Empty || lastname != String.Empty)
2407 {
2408 if (firstname != "Shown outfit:")
2409 groupTitle = "- NPC -";
2410 }
2411
2362 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2412 INPCModule module = World.RequestModuleInterface<INPCModule>();
2363 if (module != null) 2413 if (module != null)
2364 { 2414 {
2365 AvatarAppearance appearance = null; 2415 AvatarAppearance appearance = null;
2366 2416
2367 UUID id; 2417// UUID id;
2368 if (UUID.TryParse(notecard, out id)) 2418// if (UUID.TryParse(notecard, out id))
2369 { 2419// {
2370 ScenePresence clonePresence = World.GetScenePresence(id); 2420// ScenePresence clonePresence = World.GetScenePresence(id);
2371 if (clonePresence != null) 2421// if (clonePresence != null)
2372 appearance = clonePresence.Appearance; 2422// appearance = clonePresence.Appearance;
2373 } 2423// }
2374 2424
2375 if (appearance == null) 2425 if (appearance == null)
2376 { 2426 {
@@ -2378,9 +2428,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2378 2428
2379 if (appearanceSerialized != null) 2429 if (appearanceSerialized != null)
2380 { 2430 {
2381 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2431 try
2382 appearance = new AvatarAppearance(); 2432 {
2383 appearance.Unpack(appearanceOsd); 2433 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2434 appearance = new AvatarAppearance();
2435 appearance.Unpack(appearanceOsd);
2436 }
2437 catch
2438 {
2439 return UUID.Zero.ToString();
2440 }
2384 } 2441 }
2385 else 2442 else
2386 { 2443 {
@@ -2399,6 +2456,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2399 World, 2456 World,
2400 appearance); 2457 appearance);
2401 2458
2459 ScenePresence sp;
2460 if (World.TryGetScenePresence(x, out sp))
2461 {
2462 sp.Grouptitle = groupTitle;
2463 sp.SendAvatarDataToAllAgents();
2464 }
2402 return new LSL_Key(x.ToString()); 2465 return new LSL_Key(x.ToString());
2403 } 2466 }
2404 2467
@@ -2702,16 +2765,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2702 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2765 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2703 m_host.AddScriptLPS(1); 2766 m_host.AddScriptLPS(1);
2704 2767
2705 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2768 ManualResetEvent ev = new ManualResetEvent(false);
2706 if (module != null)
2707 {
2708 UUID npcId = new UUID(npc.m_string);
2709 2769
2710 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2770 Util.FireAndForget(delegate(object x) {
2711 return; 2771 try
2772 {
2773 INPCModule module = World.RequestModuleInterface<INPCModule>();
2774 if (module != null)
2775 {
2776 UUID npcId = new UUID(npc.m_string);
2712 2777
2713 module.DeleteNPC(npcId, World); 2778 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2714 } 2779 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2780 {
2781 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2782 return;
2783 }
2784
2785 module.DeleteNPC(npcId, World);
2786 }
2787 }
2788 finally
2789 {
2790 ev.Set();
2791 }
2792 });
2793 ev.WaitOne();
2715 } 2794 }
2716 2795
2717 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2796 public void osNpcPlayAnimation(LSL_Key npc, string animation)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index dd45406..d3ef378 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -93,7 +93,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
93 private const int AGENT = 1; 93 private const int AGENT = 1;
94 private const int AGENT_BY_USERNAME = 0x10; 94 private const int AGENT_BY_USERNAME = 0x10;
95 private const int NPC = 0x20; 95 private const int NPC = 0x20;
96 private const int OS_NPC = 0x01000000;
97 private const int ACTIVE = 2; 96 private const int ACTIVE = 2;
98 private const int PASSIVE = 4; 97 private const int PASSIVE = 4;
99 private const int SCRIPTED = 8; 98 private const int SCRIPTED = 8;
@@ -240,7 +239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
240 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 239 List<SensedEntity> sensedEntities = new List<SensedEntity>();
241 240
242 // Is the sensor type is AGENT and not SCRIPTED then include agents 241 // Is the sensor type is AGENT and not SCRIPTED then include agents
243 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 242 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
244 { 243 {
245 sensedEntities.AddRange(doAgentSensor(ts)); 244 sensedEntities.AddRange(doAgentSensor(ts));
246 } 245 }
@@ -339,7 +338,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
339 float dy; 338 float dy;
340 float dz; 339 float dz;
341 340
342 Quaternion q = SensePoint.GetWorldRotation(); 341// Quaternion q = SensePoint.RotationOffset;
342 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
343 if (SensePoint.ParentGroup.IsAttachment) 343 if (SensePoint.ParentGroup.IsAttachment)
344 { 344 {
345 // In attachments, rotate the sensor cone with the 345 // In attachments, rotate the sensor cone with the
@@ -353,7 +353,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
353 // Position of a sensor in a child prim attached to an avatar 353 // Position of a sensor in a child prim attached to an avatar
354 // will be still wrong. 354 // will be still wrong.
355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
356 q = avatar.Rotation * q; 356 fromRegionPos = avatar.AbsolutePosition;
357 q = avatar.Rotation;
357 } 358 }
358 359
359 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 360 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -480,7 +481,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
480 // Position of a sensor in a child prim attached to an avatar 481 // Position of a sensor in a child prim attached to an avatar
481 // will be still wrong. 482 // will be still wrong.
482 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 483 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
483 q = avatar.Rotation * q; 484 if (avatar == null)
485 return sensedEntities;
486 fromRegionPos = avatar.AbsolutePosition;
487 q = avatar.Rotation;
484 } 488 }
485 489
486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 490 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -496,7 +500,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
496// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 500// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
497// presence.Name, presence.PresenceType, ts.name, ts.type); 501// presence.Name, presence.PresenceType, ts.name, ts.type);
498 502
499 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 503 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
500 { 504 {
501 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 505 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
502 if (npcData == null || !npcData.SenseAsAgent) 506 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 0b14565..68aacd2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -123,25 +123,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
123 if (Timers.Count == 0) 123 if (Timers.Count == 0)
124 return; 124 return;
125 125
126 Dictionary<string, TimerInfo>.ValueCollection tvals;
126 lock (TimerListLock) 127 lock (TimerListLock)
127 { 128 {
128 // Go through all timers 129 // Go through all timers
129 Dictionary<string, TimerInfo>.ValueCollection tvals = Timers.Values; 130 tvals = Timers.Values;
130 foreach (TimerInfo ts in tvals) 131 }
132
133 foreach (TimerInfo ts in tvals)
134 {
135 // Time has passed?
136 if (ts.next < DateTime.Now.Ticks)
131 { 137 {
132 // Time has passed? 138 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
133 if (ts.next < DateTime.Now.Ticks) 139 // Add it to queue
134 { 140 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
135 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 141 new EventParams("timer", new Object[0],
136 // Add it to queue 142 new DetectParams[0]));
137 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 143 // set next interval
138 new EventParams("timer", new Object[0], 144
139 new DetectParams[0])); 145 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
140 // set next interval 146 ts.next = DateTime.Now.Ticks + ts.interval;
141
142 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
143 ts.next = DateTime.Now.Ticks + ts.interval;
144 }
145 } 147 }
146 } 148 }
147 } 149 }