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.cs3122
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs157
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs18
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
7 files changed, 2666 insertions, 809 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 8adf4d9..1fbfc52 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,14 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Framework.Scenes.Scripting; 51using OpenSim.Region.Framework.Scenes.Scripting;
49using OpenSim.Region.Physics.Manager; 52using OpenSim.Region.Physics.Manager;
@@ -67,6 +70,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
67using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 70using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
68using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 71using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
69using System.Reflection; 72using System.Reflection;
73using Timer = System.Timers.Timer;
70 74
71namespace OpenSim.Region.ScriptEngine.Shared.Api 75namespace OpenSim.Region.ScriptEngine.Shared.Api
72{ 76{
@@ -113,17 +117,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
113 protected int m_notecardLineReadCharsMax = 255; 117 protected int m_notecardLineReadCharsMax = 255;
114 protected int m_scriptConsoleChannel = 0; 118 protected int m_scriptConsoleChannel = 0;
115 protected bool m_scriptConsoleChannelEnabled = false; 119 protected bool m_scriptConsoleChannelEnabled = false;
120 protected bool m_debuggerSafe = false;
116 protected IUrlModule m_UrlModule = null; 121 protected IUrlModule m_UrlModule = null;
117 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 122 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
118 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 123 new Dictionary<UUID, UserInfoCacheEntry>();
124 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
119 protected ISoundModule m_SoundModule = null; 125 protected ISoundModule m_SoundModule = null;
120 126
127// protected Timer m_ShoutSayTimer;
128 protected int m_SayShoutCount = 0;
129 DateTime m_lastSayShoutCheck;
130
131 private Dictionary<string, string> MovementAnimationsForLSL =
132 new Dictionary<string, string> {
133 {"FLY", "Flying"},
134 {"FLYSLOW", "FlyingSlow"},
135 {"HOVER_UP", "Hovering Up"},
136 {"HOVER_DOWN", "Hovering Down"},
137 {"HOVER", "Hovering"},
138 {"LAND", "Landing"},
139 {"FALLDOWN", "Falling Down"},
140 {"PREJUMP", "PreJumping"},
141 {"JUMP", "Jumping"},
142 {"STANDUP", "Standing Up"},
143 {"SOFT_LAND", "Soft Landing"},
144 {"STAND", "Standing"},
145 {"CROUCHWALK", "CrouchWalking"},
146 {"RUN", "Running"},
147 {"WALK", "Walking"},
148 {"CROUCH", "Crouching"},
149 {"TURNLEFT", "Turning Left"},
150 {"TURNRIGHT", "Turning Right"}
151 };
152
121 public void Initialize( 153 public void Initialize(
122 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) 154 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
123 { 155 {
156 m_lastSayShoutCheck = DateTime.UtcNow;
157
124 m_ScriptEngine = scriptEngine; 158 m_ScriptEngine = scriptEngine;
125 m_host = host; 159 m_host = host;
126 m_item = item; 160 m_item = item;
161 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
127 m_coopSleepHandle = coopSleepHandle; 162 m_coopSleepHandle = coopSleepHandle;
128 163
129 LoadConfig(); 164 LoadConfig();
@@ -212,6 +247,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
212 get { return m_ScriptEngine.World; } 247 get { return m_ScriptEngine.World; }
213 } 248 }
214 249
250 [DebuggerNonUserCode]
215 public void state(string newState) 251 public void state(string newState)
216 { 252 {
217 m_ScriptEngine.SetState(m_item.ItemID, newState); 253 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -221,6 +257,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
221 /// Reset the named script. The script must be present 257 /// Reset the named script. The script must be present
222 /// in the same prim. 258 /// in the same prim.
223 /// </summary> 259 /// </summary>
260 [DebuggerNonUserCode]
224 public void llResetScript() 261 public void llResetScript()
225 { 262 {
226 m_host.AddScriptLPS(1); 263 m_host.AddScriptLPS(1);
@@ -283,6 +320,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
283 } 320 }
284 } 321 }
285 322
323 public List<ScenePresence> GetLinkAvatars(int linkType)
324 {
325 List<ScenePresence> ret = new List<ScenePresence>();
326 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
327 return ret;
328
329 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
330
331 switch (linkType)
332 {
333 case ScriptBaseClass.LINK_SET:
334 return avs;
335
336 case ScriptBaseClass.LINK_ROOT:
337 return ret;
338
339 case ScriptBaseClass.LINK_ALL_OTHERS:
340 return avs;
341
342 case ScriptBaseClass.LINK_ALL_CHILDREN:
343 return avs;
344
345 case ScriptBaseClass.LINK_THIS:
346 return ret;
347
348 default:
349 if (linkType < 0)
350 return ret;
351
352 int partCount = m_host.ParentGroup.GetPartCount();
353
354 if (linkType <= partCount)
355 {
356 return ret;
357 }
358 else
359 {
360 linkType = linkType - partCount;
361 if (linkType > avs.Count)
362 {
363 return ret;
364 }
365 else
366 {
367 ret.Add(avs[linkType-1]);
368 return ret;
369 }
370 }
371 }
372 }
373
286 /// <summary> 374 /// <summary>
287 /// Get a given link entity from a linkset (linked objects and any sitting avatars). 375 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
288 /// </summary> 376 /// </summary>
@@ -365,6 +453,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
365 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 453 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
366 { 454 {
367 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 455 List<SceneObjectPart> ret = new List<SceneObjectPart>();
456 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
457 return ret;
368 ret.Add(part); 458 ret.Add(part);
369 459
370 switch (linkType) 460 switch (linkType)
@@ -518,31 +608,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
518 608
519 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 609 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
520 610
521 /// <summary> 611 // Utility function for llRot2Euler
522 /// Convert an LSL rotation to a Euler vector. 612
523 /// </summary> 613 // normalize an angle between -PI and PI (-180 to +180 degrees)
524 /// <remarks> 614 protected double NormalizeAngle(double angle)
525 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
526 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
527 /// </remarks>
528 /// <param name="r"></param>
529 /// <returns></returns>
530 public LSL_Vector llRot2Euler(LSL_Rotation r)
531 { 615 {
532 m_host.AddScriptLPS(1); 616 if (angle > -Math.PI && angle < Math.PI)
617 return angle;
533 618
534 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 619 int numPis = (int)(Math.PI / angle);
535 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 620 double remainder = angle - Math.PI * numPis;
536 if (m == 0.0) return new LSL_Vector(); 621 if (numPis % 2 == 1)
537 double x = Math.Atan2(-v.y, v.z); 622 return Math.PI - angle;
538 double sin = v.x / m; 623 return remainder;
539 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 624 }
540 double y = Math.Asin(sin);
541 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
542 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)));
543 double z = Math.Atan2(v.y, v.x);
544 625
545 return new LSL_Vector(x, y, z); 626 public LSL_Vector llRot2Euler(LSL_Rotation q1)
627 {
628 m_host.AddScriptLPS(1);
629 LSL_Vector eul = new LSL_Vector();
630
631 double sqw = q1.s*q1.s;
632 double sqx = q1.x*q1.x;
633 double sqy = q1.z*q1.z;
634 double sqz = q1.y*q1.y;
635 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
636 double test = q1.x*q1.z + q1.y*q1.s;
637 if (test > 0.4999*unit) { // singularity at north pole
638 eul.z = 2 * Math.Atan2(q1.x,q1.s);
639 eul.y = Math.PI/2;
640 eul.x = 0;
641 return eul;
642 }
643 if (test < -0.4999*unit) { // singularity at south pole
644 eul.z = -2 * Math.Atan2(q1.x,q1.s);
645 eul.y = -Math.PI/2;
646 eul.x = 0;
647 return eul;
648 }
649 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
650 eul.y = Math.Asin(2*test/unit);
651 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
652 return eul;
546 } 653 }
547 654
548 /* From wiki: 655 /* From wiki:
@@ -595,18 +702,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
595 m_host.AddScriptLPS(1); 702 m_host.AddScriptLPS(1);
596 703
597 double x,y,z,s; 704 double x,y,z,s;
598 705 v.x *= 0.5;
599 double c1 = Math.Cos(v.x * 0.5); 706 v.y *= 0.5;
600 double c2 = Math.Cos(v.y * 0.5); 707 v.z *= 0.5;
601 double c3 = Math.Cos(v.z * 0.5); 708 double c1 = Math.Cos(v.x);
602 double s1 = Math.Sin(v.x * 0.5); 709 double c2 = Math.Cos(v.y);
603 double s2 = Math.Sin(v.y * 0.5); 710 double c1c2 = c1 * c2;
604 double s3 = Math.Sin(v.z * 0.5); 711 double s1 = Math.Sin(v.x);
605 712 double s2 = Math.Sin(v.y);
606 x = s1 * c2 * c3 + c1 * s2 * s3; 713 double s1s2 = s1 * s2;
607 y = c1 * s2 * c3 - s1 * c2 * s3; 714 double c1s2 = c1 * s2;
608 z = s1 * s2 * c3 + c1 * c2 * s3; 715 double s1c2 = s1 * c2;
609 s = c1 * c2 * c3 - s1 * s2 * s3; 716 double c3 = Math.Cos(v.z);
717 double s3 = Math.Sin(v.z);
718
719 x = s1c2 * c3 + c1s2 * s3;
720 y = c1s2 * c3 - s1c2 * s3;
721 z = s1s2 * c3 + c1c2 * s3;
722 s = c1c2 * c3 - s1s2 * s3;
610 723
611 return new LSL_Rotation(x, y, z, s); 724 return new LSL_Rotation(x, y, z, s);
612 } 725 }
@@ -744,77 +857,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
744 { 857 {
745 //A and B should both be normalized 858 //A and B should both be normalized
746 m_host.AddScriptLPS(1); 859 m_host.AddScriptLPS(1);
747 LSL_Rotation rotBetween; 860 /* This method is more accurate than the SL one, and thus causes problems
748 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 861 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
749 // continue calculation. 862
750 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 863 double dotProduct = LSL_Vector.Dot(a, b);
864 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
865 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
866 double angle = Math.Acos(dotProduct / magProduct);
867 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
868 double s = Math.Sin(angle / 2);
869
870 double x = axis.x * s;
871 double y = axis.y * s;
872 double z = axis.z * s;
873 double w = Math.Cos(angle / 2);
874
875 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
876 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
877
878 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
879 */
880
881 // This method mimics the 180 errors found in SL
882 // See www.euclideanspace.com... angleBetween
883 LSL_Vector vec_a = a;
884 LSL_Vector vec_b = b;
885
886 // Eliminate zero length
887 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
888 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
889 if (vec_a_mag < 0.00001 ||
890 vec_b_mag < 0.00001)
751 { 891 {
752 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 892 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
753 } 893 }
754 else 894
895 // Normalize
896 vec_a = llVecNorm(vec_a);
897 vec_b = llVecNorm(vec_b);
898
899 // Calculate axis and rotation angle
900 LSL_Vector axis = vec_a % vec_b;
901 LSL_Float cos_theta = vec_a * vec_b;
902
903 // Check if parallel
904 if (cos_theta > 0.99999)
755 { 905 {
756 a = LSL_Vector.Norm(a); 906 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
757 b = LSL_Vector.Norm(b); 907 }
758 double dotProduct = LSL_Vector.Dot(a, b); 908
759 // There are two degenerate cases possible. These are for vectors 180 or 909 // Check if anti-parallel
760 // 0 degrees apart. These have to be detected and handled individually. 910 else if (cos_theta < -0.99999)
761 // 911 {
762 // Check for vectors 180 degrees apart. 912 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
763 // A dot product of -1 would mean the angle between vectors is 180 degrees. 913 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
764 if (dotProduct < -0.9999999f) 914 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
765 { 915 }
766 // First assume X axis is orthogonal to the vectors. 916 else // other rotation
767 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 917 {
768 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 918 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
769 // Check for near zero vector. A very small non-zero number here will create 919 axis = llVecNorm(axis);
770 // a rotation in an undesired direction. 920 double x, y, z, s, t;
771 if (LSL_Vector.Mag(orthoVector) > 0.0001) 921 s = Math.Cos(theta);
772 { 922 t = Math.Sin(theta);
773 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 923 x = axis.x * t;
774 } 924 y = axis.y * t;
775 // If the magnitude of the vector was near zero, then assume the X axis is not 925 z = axis.z * t;
776 // orthogonal and use the Z axis instead. 926 return new LSL_Rotation(x,y,z,s);
777 else
778 {
779 // Set 180 z rotation.
780 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
781 }
782 }
783 // Check for parallel vectors.
784 // A dot product of 1 would mean the angle between vectors is 0 degrees.
785 else if (dotProduct > 0.9999999f)
786 {
787 // Set zero rotation.
788 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
789 }
790 else
791 {
792 // All special checks have been performed so get the axis of rotation.
793 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
794 // Quarternion s value is the length of the unit vector + dot product.
795 double qs = 1.0 + dotProduct;
796 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
797 // Normalize the rotation.
798 double mag = LSL_Rotation.Mag(rotBetween);
799 // We shouldn't have to worry about a divide by zero here. The qs value will be
800 // non-zero because we already know if we're here, then the dotProduct is not -1 so
801 // qs will not be zero. Also, we've already handled the input vectors being zero so the
802 // crossProduct vector should also not be zero.
803 rotBetween.x = rotBetween.x / mag;
804 rotBetween.y = rotBetween.y / mag;
805 rotBetween.z = rotBetween.z / mag;
806 rotBetween.s = rotBetween.s / mag;
807 // Check for undefined values and set zero rotation if any found. This code might not actually be required
808 // any longer since zero vectors are checked for at the top.
809 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
810 {
811 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
812 }
813 }
814 } 927 }
815 return rotBetween;
816 } 928 }
817 929
818 public void llWhisper(int channelID, string text) 930 public void llWhisper(int channelID, string text)
819 { 931 {
820 m_host.AddScriptLPS(1); 932 m_host.AddScriptLPS(1);
@@ -830,10 +942,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
830 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 942 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
831 } 943 }
832 944
945 private void CheckSayShoutTime()
946 {
947 DateTime now = DateTime.UtcNow;
948 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
949 {
950 m_lastSayShoutCheck = now;
951 m_SayShoutCount = 0;
952 }
953 else
954 m_SayShoutCount++;
955 }
956
833 public void llSay(int channelID, string text) 957 public void llSay(int channelID, string text)
834 { 958 {
835 m_host.AddScriptLPS(1); 959 m_host.AddScriptLPS(1);
836 960
961 if (channelID == 0)
962// m_SayShoutCount++;
963 CheckSayShoutTime();
964
965 if (m_SayShoutCount >= 11)
966 ScriptSleep(2000);
967
837 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 968 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
838 { 969 {
839 Console.WriteLine(text); 970 Console.WriteLine(text);
@@ -856,6 +987,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
856 { 987 {
857 m_host.AddScriptLPS(1); 988 m_host.AddScriptLPS(1);
858 989
990 if (channelID == 0)
991// m_SayShoutCount++;
992 CheckSayShoutTime();
993
994 if (m_SayShoutCount >= 11)
995 ScriptSleep(2000);
996
859 if (text.Length > 1023) 997 if (text.Length > 1023)
860 text = text.Substring(0, 1023); 998 text = text.Substring(0, 1023);
861 999
@@ -887,22 +1025,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
887 1025
888 public void llRegionSayTo(string target, int channel, string msg) 1026 public void llRegionSayTo(string target, int channel, string msg)
889 { 1027 {
1028 string error = String.Empty;
1029
890 if (msg.Length > 1023) 1030 if (msg.Length > 1023)
891 msg = msg.Substring(0, 1023); 1031 msg = msg.Substring(0, 1023);
892 1032
893 m_host.AddScriptLPS(1); 1033 m_host.AddScriptLPS(1);
894 1034
895 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
896 {
897 return;
898 }
899
900 UUID TargetID; 1035 UUID TargetID;
901 UUID.TryParse(target, out TargetID); 1036 UUID.TryParse(target, out TargetID);
902 1037
903 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1038 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
904 if (wComm != null) 1039 if (wComm != null)
905 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1040 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1041 LSLError(error);
906 } 1042 }
907 1043
908 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1044 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1158,10 +1294,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1158 return detectedParams.TouchUV; 1294 return detectedParams.TouchUV;
1159 } 1295 }
1160 1296
1297 [DebuggerNonUserCode]
1161 public virtual void llDie() 1298 public virtual void llDie()
1162 { 1299 {
1163 m_host.AddScriptLPS(1); 1300 m_host.AddScriptLPS(1);
1164 throw new SelfDeleteException(); 1301 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1165 } 1302 }
1166 1303
1167 public LSL_Float llGround(LSL_Vector offset) 1304 public LSL_Float llGround(LSL_Vector offset)
@@ -1232,6 +1369,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1232 1369
1233 public void llSetStatus(int status, int value) 1370 public void llSetStatus(int status, int value)
1234 { 1371 {
1372 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1373 return;
1235 m_host.AddScriptLPS(1); 1374 m_host.AddScriptLPS(1);
1236 1375
1237 int statusrotationaxis = 0; 1376 int statusrotationaxis = 0;
@@ -1255,6 +1394,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1255 if (!allow) 1394 if (!allow)
1256 return; 1395 return;
1257 1396
1397 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1398 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1399 return;
1400
1258 m_host.ScriptSetPhysicsStatus(true); 1401 m_host.ScriptSetPhysicsStatus(true);
1259 } 1402 }
1260 else 1403 else
@@ -1455,6 +1598,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1455 { 1598 {
1456 m_host.AddScriptLPS(1); 1599 m_host.AddScriptLPS(1);
1457 1600
1601 SetColor(m_host, color, face);
1602 }
1603
1604 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1605 {
1606 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1607 return;
1608
1609 Primitive.TextureEntry tex = part.Shape.Textures;
1610 Color4 texcolor;
1611 if (face >= 0 && face < GetNumberOfSides(part))
1612 {
1613 texcolor = tex.CreateFace((uint)face).RGBA;
1614 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1615 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1616 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1617 tex.FaceTextures[face].RGBA = texcolor;
1618 part.UpdateTextureEntry(tex.GetBytes());
1619 return;
1620 }
1621 else if (face == ScriptBaseClass.ALL_SIDES)
1622 {
1623 for (uint i = 0; i < GetNumberOfSides(part); i++)
1624 {
1625 if (tex.FaceTextures[i] != null)
1626 {
1627 texcolor = tex.FaceTextures[i].RGBA;
1628 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1629 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1630 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1631 tex.FaceTextures[i].RGBA = texcolor;
1632 }
1633 texcolor = tex.DefaultTexture.RGBA;
1634 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1635 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1636 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1637 tex.DefaultTexture.RGBA = texcolor;
1638 }
1639 part.UpdateTextureEntry(tex.GetBytes());
1640 return;
1641 }
1642
1458 if (face == ScriptBaseClass.ALL_SIDES) 1643 if (face == ScriptBaseClass.ALL_SIDES)
1459 face = SceneObjectPart.ALL_SIDES; 1644 face = SceneObjectPart.ALL_SIDES;
1460 1645
@@ -1463,6 +1648,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1463 1648
1464 public void SetTexGen(SceneObjectPart part, int face,int style) 1649 public void SetTexGen(SceneObjectPart part, int face,int style)
1465 { 1650 {
1651 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1652 return;
1653
1466 Primitive.TextureEntry tex = part.Shape.Textures; 1654 Primitive.TextureEntry tex = part.Shape.Textures;
1467 MappingType textype; 1655 MappingType textype;
1468 textype = MappingType.Default; 1656 textype = MappingType.Default;
@@ -1493,6 +1681,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1493 1681
1494 public void SetGlow(SceneObjectPart part, int face, float glow) 1682 public void SetGlow(SceneObjectPart part, int face, float glow)
1495 { 1683 {
1684 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1685 return;
1686
1496 Primitive.TextureEntry tex = part.Shape.Textures; 1687 Primitive.TextureEntry tex = part.Shape.Textures;
1497 if (face >= 0 && face < GetNumberOfSides(part)) 1688 if (face >= 0 && face < GetNumberOfSides(part))
1498 { 1689 {
@@ -1518,6 +1709,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1518 1709
1519 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1710 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1520 { 1711 {
1712 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1713 return;
1521 1714
1522 Shininess sval = new Shininess(); 1715 Shininess sval = new Shininess();
1523 1716
@@ -1568,6 +1761,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1568 1761
1569 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1762 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1570 { 1763 {
1764 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1765 return;
1766
1571 Primitive.TextureEntry tex = part.Shape.Textures; 1767 Primitive.TextureEntry tex = part.Shape.Textures;
1572 if (face >= 0 && face < GetNumberOfSides(part)) 1768 if (face >= 0 && face < GetNumberOfSides(part))
1573 { 1769 {
@@ -1628,13 +1824,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1628 m_host.AddScriptLPS(1); 1824 m_host.AddScriptLPS(1);
1629 1825
1630 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1826 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1631 1827 if (parts.Count > 0)
1632 foreach (SceneObjectPart part in parts) 1828 {
1633 SetAlpha(part, alpha, face); 1829 try
1830 {
1831 foreach (SceneObjectPart part in parts)
1832 SetAlpha(part, alpha, face);
1833 }
1834 finally
1835 {
1836 }
1837 }
1634 } 1838 }
1635 1839
1636 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1840 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1637 { 1841 {
1842 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1843 return;
1844
1638 Primitive.TextureEntry tex = part.Shape.Textures; 1845 Primitive.TextureEntry tex = part.Shape.Textures;
1639 Color4 texcolor; 1846 Color4 texcolor;
1640 if (face >= 0 && face < GetNumberOfSides(part)) 1847 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1687,7 +1894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1687 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1894 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1688 float wind, float tension, LSL_Vector Force) 1895 float wind, float tension, LSL_Vector Force)
1689 { 1896 {
1690 if (part == null) 1897 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1691 return; 1898 return;
1692 1899
1693 if (flexi) 1900 if (flexi)
@@ -1728,7 +1935,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1728 /// <param name="falloff"></param> 1935 /// <param name="falloff"></param>
1729 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1936 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1730 { 1937 {
1731 if (part == null) 1938 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1732 return; 1939 return;
1733 1940
1734 if (light) 1941 if (light)
@@ -1761,11 +1968,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1761 Primitive.TextureEntry tex = part.Shape.Textures; 1968 Primitive.TextureEntry tex = part.Shape.Textures;
1762 Color4 texcolor; 1969 Color4 texcolor;
1763 LSL_Vector rgb = new LSL_Vector(); 1970 LSL_Vector rgb = new LSL_Vector();
1971 int nsides = GetNumberOfSides(part);
1972
1764 if (face == ScriptBaseClass.ALL_SIDES) 1973 if (face == ScriptBaseClass.ALL_SIDES)
1765 { 1974 {
1766 int i; 1975 int i;
1767 1976 for (i = 0; i < nsides; i++)
1768 for (i = 0 ; i < GetNumberOfSides(part); i++)
1769 { 1977 {
1770 texcolor = tex.GetFace((uint)i).RGBA; 1978 texcolor = tex.GetFace((uint)i).RGBA;
1771 rgb.x += texcolor.R; 1979 rgb.x += texcolor.R;
@@ -1773,14 +1981,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1773 rgb.z += texcolor.B; 1981 rgb.z += texcolor.B;
1774 } 1982 }
1775 1983
1776 rgb.x /= (float)GetNumberOfSides(part); 1984 float invnsides = 1.0f / (float)nsides;
1777 rgb.y /= (float)GetNumberOfSides(part); 1985
1778 rgb.z /= (float)GetNumberOfSides(part); 1986 rgb.x *= invnsides;
1987 rgb.y *= invnsides;
1988 rgb.z *= invnsides;
1779 1989
1780 return rgb; 1990 return rgb;
1781 } 1991 }
1782 1992 if (face >= 0 && face < nsides)
1783 if (face >= 0 && face < GetNumberOfSides(part))
1784 { 1993 {
1785 texcolor = tex.GetFace((uint)face).RGBA; 1994 texcolor = tex.GetFace((uint)face).RGBA;
1786 rgb.x = texcolor.R; 1995 rgb.x = texcolor.R;
@@ -1807,15 +2016,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1807 m_host.AddScriptLPS(1); 2016 m_host.AddScriptLPS(1);
1808 2017
1809 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2018 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1810 2019 if (parts.Count > 0)
1811 foreach (SceneObjectPart part in parts) 2020 {
1812 SetTexture(part, texture, face); 2021 try
1813 2022 {
2023 foreach (SceneObjectPart part in parts)
2024 SetTexture(part, texture, face);
2025 }
2026 finally
2027 {
2028 }
2029 }
1814 ScriptSleep(200); 2030 ScriptSleep(200);
1815 } 2031 }
1816 2032
1817 protected void SetTexture(SceneObjectPart part, string texture, int face) 2033 protected void SetTexture(SceneObjectPart part, string texture, int face)
1818 { 2034 {
2035 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2036 return;
2037
1819 UUID textureID = new UUID(); 2038 UUID textureID = new UUID();
1820 2039
1821 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 2040 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
@@ -1860,6 +2079,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1860 2079
1861 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2080 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1862 { 2081 {
2082 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2083 return;
2084
1863 Primitive.TextureEntry tex = part.Shape.Textures; 2085 Primitive.TextureEntry tex = part.Shape.Textures;
1864 if (face >= 0 && face < GetNumberOfSides(part)) 2086 if (face >= 0 && face < GetNumberOfSides(part))
1865 { 2087 {
@@ -1896,6 +2118,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1896 2118
1897 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2119 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1898 { 2120 {
2121 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2122 return;
2123
1899 Primitive.TextureEntry tex = part.Shape.Textures; 2124 Primitive.TextureEntry tex = part.Shape.Textures;
1900 if (face >= 0 && face < GetNumberOfSides(part)) 2125 if (face >= 0 && face < GetNumberOfSides(part))
1901 { 2126 {
@@ -1932,6 +2157,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1932 2157
1933 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2158 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1934 { 2159 {
2160 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2161 return;
2162
1935 Primitive.TextureEntry tex = part.Shape.Textures; 2163 Primitive.TextureEntry tex = part.Shape.Textures;
1936 if (face >= 0 && face < GetNumberOfSides(part)) 2164 if (face >= 0 && face < GetNumberOfSides(part))
1937 { 2165 {
@@ -2073,7 +2301,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2073 return end; 2301 return end;
2074 } 2302 }
2075 2303
2076 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2304 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2077 { 2305 {
2078 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2306 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2079 return fromPos; 2307 return fromPos;
@@ -2089,9 +2317,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2089 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2317 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2090 targetPos.z = ground; 2318 targetPos.z = ground;
2091 } 2319 }
2092 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2320 if (adjust)
2321 return SetPosAdjust(fromPos, targetPos);
2093 2322
2094 return real_vec; 2323 return targetPos;
2095 } 2324 }
2096 2325
2097 /// <summary> 2326 /// <summary>
@@ -2102,27 +2331,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2102 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2331 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2103 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2332 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2104 { 2333 {
2105 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2334 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2335 return;
2336
2106 LSL_Vector currentPos = GetPartLocalPos(part); 2337 LSL_Vector currentPos = GetPartLocalPos(part);
2338 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2107 2339
2108 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2109 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2110 2340
2111 if (part.ParentGroup.RootPart == part) 2341 if (part.ParentGroup.RootPart == part)
2112 { 2342 {
2113 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2114 targetPos.z = ground;
2115 SceneObjectGroup parent = part.ParentGroup; 2343 SceneObjectGroup parent = part.ParentGroup;
2116 parent.UpdateGroupPosition(!adjust ? targetPos : 2344 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2117 SetPosAdjust(currentPos, targetPos)); 2345 return;
2346 Util.FireAndForget(delegate(object x) {
2347 parent.UpdateGroupPosition((Vector3)toPos);
2348 });
2118 } 2349 }
2119 else 2350 else
2120 { 2351 {
2121 part.OffsetPosition = !adjust ? targetPos : 2352 part.OffsetPosition = (Vector3)toPos;
2122 SetPosAdjust(currentPos, targetPos); 2353// SceneObjectGroup parent = part.ParentGroup;
2123 SceneObjectGroup parent = part.ParentGroup; 2354// parent.HasGroupChanged = true;
2124 parent.HasGroupChanged = true; 2355// parent.ScheduleGroupForTerseUpdate();
2125 parent.ScheduleGroupForTerseUpdate(); 2356 part.ScheduleTerseUpdate();
2126 } 2357 }
2127 } 2358 }
2128 2359
@@ -2151,13 +2382,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2151 else 2382 else
2152 { 2383 {
2153 if (part.ParentGroup.IsAttachment) 2384 if (part.ParentGroup.IsAttachment)
2154 {
2155 pos = part.AttachedPos; 2385 pos = part.AttachedPos;
2156 }
2157 else 2386 else
2158 {
2159 pos = part.AbsolutePosition; 2387 pos = part.AbsolutePosition;
2160 }
2161 } 2388 }
2162 2389
2163// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2390// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2169,8 +2396,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2169 { 2396 {
2170 m_host.AddScriptLPS(1); 2397 m_host.AddScriptLPS(1);
2171 2398
2399
2400 // 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
2401 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2402 // 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.
2403 // RootPart != null should shortcircuit
2404
2172 // try to let this work as in SL... 2405 // try to let this work as in SL...
2173 if (m_host.ParentID == 0) 2406 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2174 { 2407 {
2175 // special case: If we are root, rotate complete SOG to new rotation 2408 // special case: If we are root, rotate complete SOG to new rotation
2176 SetRot(m_host, rot); 2409 SetRot(m_host, rot);
@@ -2197,25 +2430,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2197 2430
2198 protected void SetRot(SceneObjectPart part, Quaternion rot) 2431 protected void SetRot(SceneObjectPart part, Quaternion rot)
2199 { 2432 {
2200 part.UpdateRotation(rot); 2433 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2201 // Update rotation does not move the object in the physics scene if it's a linkset. 2434 return;
2202 2435
2203//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2436 bool isroot = (part == part.ParentGroup.RootPart);
2204// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2437 bool isphys;
2205 2438
2206 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2207 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2208 // It's perfectly okay when the object is not an active physical body though.
2209 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2210 // but only if the object is not physial and active. This is important for rotating doors.
2211 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2212 // scene
2213 PhysicsActor pa = part.PhysActor; 2439 PhysicsActor pa = part.PhysActor;
2214 2440
2215 if (pa != null && !pa.IsPhysical) 2441 // keep using physactor ideia of isphysical
2442 // it should be SOP ideia of that
2443 // not much of a issue with ubitODE
2444 if (pa != null && pa.IsPhysical)
2445 isphys = true;
2446 else
2447 isphys = false;
2448
2449 // SL doesn't let scripts rotate root of physical linksets
2450 if (isroot && isphys)
2451 return;
2452
2453 part.UpdateRotation(rot);
2454
2455 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2456 // so do a nasty update of parts positions if is a root part rotation
2457 if (isroot && pa != null) // with if above implies non physical root part
2216 { 2458 {
2217 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2459 part.ParentGroup.ResetChildPrimPhysicsPositions();
2218 } 2460 }
2461 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2462 {
2463 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2464 if (sittingavas.Count > 0)
2465 {
2466 foreach (ScenePresence av in sittingavas)
2467 {
2468 if (isroot || part.LocalId == av.ParentID)
2469 av.SendTerseUpdateToAllClients();
2470 }
2471 }
2472 }
2219 } 2473 }
2220 2474
2221 /// <summary> 2475 /// <summary>
@@ -2232,6 +2486,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2232 2486
2233 m_host.AddScriptLPS(1); 2487 m_host.AddScriptLPS(1);
2234 Quaternion q = m_host.GetWorldRotation(); 2488 Quaternion q = m_host.GetWorldRotation();
2489
2490 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2491 {
2492 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2493 if (avatar != null)
2494 {
2495 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2496 q = avatar.CameraRotation * q; // Mouselook
2497 else
2498 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2499 }
2500 }
2501
2235 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2502 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2236 } 2503 }
2237 2504
@@ -2259,14 +2526,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2259 return new LSL_Rotation(q); 2526 return new LSL_Rotation(q);
2260 } 2527 }
2261 2528
2262 return new LSL_Rotation(part.GetWorldRotation()); 2529 q = part.GetWorldRotation();
2530 if (part.ParentGroup.AttachmentPoint != 0)
2531 {
2532 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2533 if (avatar != null)
2534 {
2535 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2536 q = avatar.CameraRotation * q; // Mouselook
2537 else
2538 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2539 }
2540 }
2541
2542 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2263 } 2543 }
2264 2544
2265 public LSL_Rotation llGetLocalRot() 2545 public LSL_Rotation llGetLocalRot()
2266 { 2546 {
2267 m_host.AddScriptLPS(1); 2547 return GetPartLocalRot(m_host);
2548 }
2268 2549
2269 return new LSL_Rotation(m_host.RotationOffset); 2550 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2551 {
2552 m_host.AddScriptLPS(1);
2553 Quaternion rot = part.RotationOffset;
2554 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2270 } 2555 }
2271 2556
2272 public void llSetForce(LSL_Vector force, int local) 2557 public void llSetForce(LSL_Vector force, int local)
@@ -2346,16 +2631,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2346 m_host.ApplyImpulse(v, local != 0); 2631 m_host.ApplyImpulse(v, local != 0);
2347 } 2632 }
2348 2633
2634
2349 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2635 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2350 { 2636 {
2351 m_host.AddScriptLPS(1); 2637 m_host.AddScriptLPS(1);
2352 m_host.ApplyAngularImpulse(force, local != 0); 2638 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2353 } 2639 }
2354 2640
2355 public void llSetTorque(LSL_Vector torque, int local) 2641 public void llSetTorque(LSL_Vector torque, int local)
2356 { 2642 {
2357 m_host.AddScriptLPS(1); 2643 m_host.AddScriptLPS(1);
2358 m_host.SetAngularImpulse(torque, local != 0); 2644 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2359 } 2645 }
2360 2646
2361 public LSL_Vector llGetTorque() 2647 public LSL_Vector llGetTorque()
@@ -2372,20 +2658,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2372 llSetTorque(torque, local); 2658 llSetTorque(torque, local);
2373 } 2659 }
2374 2660
2661 public void llSetVelocity(LSL_Vector vel, int local)
2662 {
2663 m_host.AddScriptLPS(1);
2664 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2665 }
2666
2375 public LSL_Vector llGetVel() 2667 public LSL_Vector llGetVel()
2376 { 2668 {
2377 m_host.AddScriptLPS(1); 2669 m_host.AddScriptLPS(1);
2378 2670
2379 Vector3 vel; 2671 Vector3 vel = Vector3.Zero;
2380 2672
2381 if (m_host.ParentGroup.IsAttachment) 2673 if (m_host.ParentGroup.IsAttachment)
2382 { 2674 {
2383 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2675 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2384 vel = avatar.Velocity; 2676 if (avatar != null)
2677 vel = avatar.Velocity;
2385 } 2678 }
2386 else 2679 else
2387 { 2680 {
2388 vel = m_host.Velocity; 2681 vel = m_host.ParentGroup.RootPart.Velocity;
2389 } 2682 }
2390 2683
2391 return new LSL_Vector(vel); 2684 return new LSL_Vector(vel);
@@ -2398,11 +2691,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2398 return new LSL_Vector(m_host.Acceleration); 2691 return new LSL_Vector(m_host.Acceleration);
2399 } 2692 }
2400 2693
2401 public LSL_Vector llGetOmega() 2694 public void llSetAngularVelocity(LSL_Vector avel, int local)
2402 { 2695 {
2403 m_host.AddScriptLPS(1); 2696 m_host.AddScriptLPS(1);
2697 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2698 }
2404 2699
2405 return new LSL_Vector(m_host.AngularVelocity); 2700 public LSL_Vector llGetOmega()
2701 {
2702 m_host.AddScriptLPS(1);
2703 Vector3 avel = m_host.AngularVelocity;
2704 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2406 } 2705 }
2407 2706
2408 public LSL_Float llGetTimeOfDay() 2707 public LSL_Float llGetTimeOfDay()
@@ -2761,7 +3060,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2761 return src.ToLower(); 3060 return src.ToLower();
2762 } 3061 }
2763 3062
2764 public void llGiveMoney(string destination, int amount) 3063 public LSL_Integer llGiveMoney(string destination, int amount)
2765 { 3064 {
2766 Util.FireAndForget(x => 3065 Util.FireAndForget(x =>
2767 { 3066 {
@@ -2793,8 +3092,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2793 } 3092 }
2794 3093
2795 money.ObjectGiveMoney( 3094 money.ObjectGiveMoney(
2796 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3095 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2797 }); 3096 });
3097
3098 return 0;
2798 } 3099 }
2799 3100
2800 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3101 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -2873,13 +3174,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2873 new_group.RootPart.UUID.ToString()) }, 3174 new_group.RootPart.UUID.ToString()) },
2874 new DetectParams[0])); 3175 new DetectParams[0]));
2875 3176
2876 float groupmass = new_group.GetMass(); 3177 // do recoil
3178 SceneObjectGroup hostgrp = m_host.ParentGroup;
3179 if (hostgrp == null)
3180 return;
3181
3182 if (hostgrp.IsAttachment) // don't recoil avatars
3183 return;
2877 3184
2878 PhysicsActor pa = new_group.RootPart.PhysActor; 3185 PhysicsActor pa = new_group.RootPart.PhysActor;
2879 3186
2880 //Recoil. 3187 //Recoil.
2881 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3188 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2882 { 3189 {
3190 float groupmass = new_group.GetMass();
2883 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3191 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2884 if (recoil != Vector3.Zero) 3192 if (recoil != Vector3.Zero)
2885 { 3193 {
@@ -2887,6 +3195,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2887 } 3195 }
2888 } 3196 }
2889 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3197 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3198 return;
3199
2890 }); 3200 });
2891 3201
2892 //ScriptSleep((int)((groupmass * velmag) / 10)); 3202 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2901,35 +3211,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2901 public void llLookAt(LSL_Vector target, double strength, double damping) 3211 public void llLookAt(LSL_Vector target, double strength, double damping)
2902 { 3212 {
2903 m_host.AddScriptLPS(1); 3213 m_host.AddScriptLPS(1);
2904 // Determine where we are looking from
2905 LSL_Vector from = llGetPos();
2906 3214
2907 // Work out the normalised vector from the source to the target 3215 // Get the normalized vector to the target
2908 LSL_Vector delta = llVecNorm(target - from); 3216 LSL_Vector d1 = llVecNorm(target - llGetPos());
2909 LSL_Vector angle = new LSL_Vector(0,0,0);
2910 3217
2911 // Calculate the yaw 3218 // Get the bearing (yaw)
2912 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3219 LSL_Vector a1 = new LSL_Vector(0,0,0);
2913 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3220 a1.z = llAtan2(d1.y, d1.x);
2914 3221
2915 // Calculate pitch 3222 // Get the elevation (pitch)
2916 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3223 LSL_Vector a2 = new LSL_Vector(0,0,0);
3224 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2917 3225
2918 // we need to convert from a vector describing 3226 LSL_Rotation r1 = llEuler2Rot(a1);
2919 // the angles of rotation in radians into rotation value 3227 LSL_Rotation r2 = llEuler2Rot(a2);
2920 LSL_Rotation rot = llEuler2Rot(angle); 3228 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2921
2922 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2923 // set the rotation of the object, copy that behavior
2924 PhysicsActor pa = m_host.PhysActor;
2925 3229
2926 if (strength == 0 || pa == null || !pa.IsPhysical) 3230 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2927 { 3231 {
2928 llSetRot(rot); 3232 // Do nothing if either value is 0 (this has been checked in SL)
3233 if (strength <= 0.0 || damping <= 0.0)
3234 return;
3235
3236 llSetRot(r3 * r2 * r1);
2929 } 3237 }
2930 else 3238 else
2931 { 3239 {
2932 m_host.StartLookAt(rot, (float)strength, (float)damping); 3240 if (strength == 0)
3241 {
3242 llSetRot(r3 * r2 * r1);
3243 return;
3244 }
3245
3246 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2933 } 3247 }
2934 } 3248 }
2935 3249
@@ -2976,17 +3290,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2976 } 3290 }
2977 else 3291 else
2978 { 3292 {
2979 if (m_host.IsRoot) 3293 // new SL always returns object mass
2980 { 3294// if (m_host.IsRoot)
3295// {
2981 return m_host.ParentGroup.GetMass(); 3296 return m_host.ParentGroup.GetMass();
2982 } 3297// }
2983 else 3298// else
2984 { 3299// {
2985 return m_host.GetMass(); 3300// return m_host.GetMass();
2986 } 3301// }
2987 } 3302 }
2988 } 3303 }
2989 3304
3305
3306 public LSL_Float llGetMassMKS()
3307 {
3308 return 100f * llGetMass();
3309 }
3310
2990 public void llCollisionFilter(string name, string id, int accept) 3311 public void llCollisionFilter(string name, string id, int accept)
2991 { 3312 {
2992 m_host.AddScriptLPS(1); 3313 m_host.AddScriptLPS(1);
@@ -3034,8 +3355,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3034 { 3355 {
3035 // Unregister controls from Presence 3356 // Unregister controls from Presence
3036 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3357 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3037 // Remove Take Control permission.
3038 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3039 } 3358 }
3040 } 3359 }
3041 } 3360 }
@@ -3063,7 +3382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3063 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3382 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3064 3383
3065 if (attachmentsModule != null) 3384 if (attachmentsModule != null)
3066 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3385 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3067 else 3386 else
3068 return false; 3387 return false;
3069 } 3388 }
@@ -3093,9 +3412,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3093 { 3412 {
3094 m_host.AddScriptLPS(1); 3413 m_host.AddScriptLPS(1);
3095 3414
3096// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3097// return;
3098
3099 if (m_item.PermsGranter != m_host.OwnerID) 3415 if (m_item.PermsGranter != m_host.OwnerID)
3100 return; 3416 return;
3101 3417
@@ -3138,6 +3454,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3138 3454
3139 public void llInstantMessage(string user, string message) 3455 public void llInstantMessage(string user, string message)
3140 { 3456 {
3457 UUID result;
3458 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3459 {
3460 ShoutError("An invalid key was passed to llInstantMessage");
3461 ScriptSleep(2000);
3462 return;
3463 }
3464
3465
3141 m_host.AddScriptLPS(1); 3466 m_host.AddScriptLPS(1);
3142 3467
3143 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3468 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3152,14 +3477,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3152 UUID friendTransactionID = UUID.Random(); 3477 UUID friendTransactionID = UUID.Random();
3153 3478
3154 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3479 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3155 3480
3156 GridInstantMessage msg = new GridInstantMessage(); 3481 GridInstantMessage msg = new GridInstantMessage();
3157 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3482 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3158 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3483 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3159 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3484 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3160// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3485// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3161// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3486// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3162 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3487// DateTime dt = DateTime.UtcNow;
3488//
3489// // Ticks from UtcNow, but make it look like local. Evil, huh?
3490// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3491//
3492// try
3493// {
3494// // Convert that to the PST timezone
3495// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3496// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3497// }
3498// catch
3499// {
3500// // No logging here, as it could be VERY spammy
3501// }
3502//
3503// // And make it look local again to fool the unix time util
3504// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3505
3506 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3507
3163 //if (client != null) 3508 //if (client != null)
3164 //{ 3509 //{
3165 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3510 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3173,10 +3518,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3173 msg.message = message.Substring(0, 1024); 3518 msg.message = message.Substring(0, 1024);
3174 else 3519 else
3175 msg.message = message; 3520 msg.message = message;
3176 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3521 msg.dialog = (byte)19; // MessageFromObject
3177 msg.fromGroup = false;// fromGroup; 3522 msg.fromGroup = false;// fromGroup;
3178 msg.offline = (byte)0; //offline; 3523 msg.offline = (byte)0; //offline;
3179 msg.ParentEstateID = 0; //ParentEstateID; 3524 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3180 msg.Position = new Vector3(m_host.AbsolutePosition); 3525 msg.Position = new Vector3(m_host.AbsolutePosition);
3181 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3526 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3182 3527
@@ -3208,7 +3553,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3208 } 3553 }
3209 3554
3210 emailModule.SendEmail(m_host.UUID, address, subject, message); 3555 emailModule.SendEmail(m_host.UUID, address, subject, message);
3211 llSleep(EMAIL_PAUSE_TIME); 3556 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3212 } 3557 }
3213 3558
3214 public void llGetNextEmail(string address, string subject) 3559 public void llGetNextEmail(string address, string subject)
@@ -3454,7 +3799,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3454 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3799 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3455 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3800 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3456 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3801 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3802 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3457 ScriptBaseClass.PERMISSION_ATTACH; 3803 ScriptBaseClass.PERMISSION_ATTACH;
3804
3458 } 3805 }
3459 else 3806 else
3460 { 3807 {
@@ -3471,15 +3818,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3471 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3818 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3472 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3819 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3473 } 3820 }
3821 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3822 {
3823 implicitPerms = perm;
3824 }
3474 } 3825 }
3475 3826
3476 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3827 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3477 { 3828 {
3478 lock (m_host.TaskInventory) 3829 m_host.TaskInventory.LockItemsForWrite(true);
3479 { 3830 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3480 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3831 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3481 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3832 m_host.TaskInventory.LockItemsForWrite(false);
3482 }
3483 3833
3484 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3834 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3485 "run_time_permissions", new Object[] { 3835 "run_time_permissions", new Object[] {
@@ -3522,11 +3872,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3522 3872
3523 if (!m_waitingForScriptAnswer) 3873 if (!m_waitingForScriptAnswer)
3524 { 3874 {
3525 lock (m_host.TaskInventory) 3875 m_host.TaskInventory.LockItemsForWrite(true);
3526 { 3876 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3527 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3877 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3528 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3878 m_host.TaskInventory.LockItemsForWrite(false);
3529 }
3530 3879
3531 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3880 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3532 m_waitingForScriptAnswer=true; 3881 m_waitingForScriptAnswer=true;
@@ -3555,14 +3904,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3555 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3904 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3556 llReleaseControls(); 3905 llReleaseControls();
3557 3906
3558 lock (m_host.TaskInventory) 3907 m_host.TaskInventory.LockItemsForWrite(true);
3559 { 3908 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3560 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3909 m_host.TaskInventory.LockItemsForWrite(false);
3561 } 3910
3562 3911 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3563 m_ScriptEngine.PostScriptEvent( 3912 "run_time_permissions", new Object[] {
3564 m_item.ItemID, 3913 new LSL_Integer(answer) },
3565 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3914 new DetectParams[0]));
3566 } 3915 }
3567 3916
3568 public LSL_String llGetPermissionsKey() 3917 public LSL_String llGetPermissionsKey()
@@ -3601,14 +3950,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3601 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3950 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3602 { 3951 {
3603 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3952 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3604 3953 if (parts.Count > 0)
3605 foreach (SceneObjectPart part in parts) 3954 {
3606 part.SetFaceColorAlpha(face, color, null); 3955 try
3956 {
3957 foreach (SceneObjectPart part in parts)
3958 part.SetFaceColorAlpha(face, color, null);
3959 }
3960 finally
3961 {
3962 }
3963 }
3607 } 3964 }
3608 3965
3609 public void llCreateLink(string target, int parent) 3966 public void llCreateLink(string target, int parent)
3610 { 3967 {
3611 m_host.AddScriptLPS(1); 3968 m_host.AddScriptLPS(1);
3969
3612 UUID targetID; 3970 UUID targetID;
3613 3971
3614 if (!UUID.TryParse(target, out targetID)) 3972 if (!UUID.TryParse(target, out targetID))
@@ -3714,10 +4072,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3714 // Restructuring Multiple Prims. 4072 // Restructuring Multiple Prims.
3715 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4073 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3716 parts.Remove(parentPrim.RootPart); 4074 parts.Remove(parentPrim.RootPart);
3717 foreach (SceneObjectPart part in parts) 4075 if (parts.Count > 0)
3718 { 4076 {
3719 parentPrim.DelinkFromGroup(part.LocalId, true); 4077 try
4078 {
4079 foreach (SceneObjectPart part in parts)
4080 {
4081 parentPrim.DelinkFromGroup(part.LocalId, true);
4082 }
4083 }
4084 finally
4085 {
4086 }
3720 } 4087 }
4088
3721 parentPrim.HasGroupChanged = true; 4089 parentPrim.HasGroupChanged = true;
3722 parentPrim.ScheduleGroupForFullUpdate(); 4090 parentPrim.ScheduleGroupForFullUpdate();
3723 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4091 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3726,12 +4094,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3726 { 4094 {
3727 SceneObjectPart newRoot = parts[0]; 4095 SceneObjectPart newRoot = parts[0];
3728 parts.Remove(newRoot); 4096 parts.Remove(newRoot);
3729 foreach (SceneObjectPart part in parts) 4097
4098 try
3730 { 4099 {
3731 // Required for linking 4100 foreach (SceneObjectPart part in parts)
3732 part.ClearUpdateSchedule(); 4101 {
3733 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4102 part.ClearUpdateSchedule();
4103 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4104 }
3734 } 4105 }
4106 finally
4107 {
4108 }
4109
4110
3735 newRoot.ParentGroup.HasGroupChanged = true; 4111 newRoot.ParentGroup.HasGroupChanged = true;
3736 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4112 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3737 } 4113 }
@@ -3751,6 +4127,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3751 public void llBreakAllLinks() 4127 public void llBreakAllLinks()
3752 { 4128 {
3753 m_host.AddScriptLPS(1); 4129 m_host.AddScriptLPS(1);
4130
4131 TaskInventoryItem item = m_item;
4132
4133 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4134 && !m_automaticLinkPermission)
4135 {
4136 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4137 return;
4138 }
4139
3754 SceneObjectGroup parentPrim = m_host.ParentGroup; 4140 SceneObjectGroup parentPrim = m_host.ParentGroup;
3755 if (parentPrim.AttachmentPoint != 0) 4141 if (parentPrim.AttachmentPoint != 0)
3756 return; // Fail silently if attached 4142 return; // Fail silently if attached
@@ -3770,13 +4156,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3770 public LSL_String llGetLinkKey(int linknum) 4156 public LSL_String llGetLinkKey(int linknum)
3771 { 4157 {
3772 m_host.AddScriptLPS(1); 4158 m_host.AddScriptLPS(1);
4159 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
4160 if (part != null)
4161 {
4162 return part.UUID.ToString();
4163 }
4164 else
4165 {
4166 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4167 {
4168 linknum -= (m_host.ParentGroup.PrimCount) + 1;
3773 4169
3774 ISceneEntity entity = GetLinkEntity(linknum); 4170 if (linknum < 0)
4171 return UUID.Zero.ToString();
3775 4172
3776 if (entity != null) 4173 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
3777 return entity.UUID.ToString(); 4174 if (avatars.Count > linknum)
3778 else 4175 {
3779 return ScriptBaseClass.NULL_KEY; 4176 return avatars[linknum].UUID.ToString();
4177 }
4178 }
4179 return UUID.Zero.ToString();
4180 }
3780 } 4181 }
3781 4182
3782 /// <summary> 4183 /// <summary>
@@ -3835,17 +4236,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3835 m_host.AddScriptLPS(1); 4236 m_host.AddScriptLPS(1);
3836 int count = 0; 4237 int count = 0;
3837 4238
3838 lock (m_host.TaskInventory) 4239 m_host.TaskInventory.LockItemsForRead(true);
4240 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3839 { 4241 {
3840 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4242 if (inv.Value.Type == type || type == -1)
3841 { 4243 {
3842 if (inv.Value.Type == type || type == -1) 4244 count = count + 1;
3843 {
3844 count = count + 1;
3845 }
3846 } 4245 }
3847 } 4246 }
3848 4247
4248 m_host.TaskInventory.LockItemsForRead(false);
3849 return count; 4249 return count;
3850 } 4250 }
3851 4251
@@ -3854,16 +4254,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3854 m_host.AddScriptLPS(1); 4254 m_host.AddScriptLPS(1);
3855 ArrayList keys = new ArrayList(); 4255 ArrayList keys = new ArrayList();
3856 4256
3857 lock (m_host.TaskInventory) 4257 m_host.TaskInventory.LockItemsForRead(true);
4258 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3858 { 4259 {
3859 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4260 if (inv.Value.Type == type || type == -1)
3860 { 4261 {
3861 if (inv.Value.Type == type || type == -1) 4262 keys.Add(inv.Value.Name);
3862 {
3863 keys.Add(inv.Value.Name);
3864 }
3865 } 4263 }
3866 } 4264 }
4265 m_host.TaskInventory.LockItemsForRead(false);
3867 4266
3868 if (keys.Count == 0) 4267 if (keys.Count == 0)
3869 { 4268 {
@@ -3901,7 +4300,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3901 if (item == null) 4300 if (item == null)
3902 { 4301 {
3903 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4302 llSay(0, String.Format("Could not find object '{0}'", inventory));
3904 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4303 return;
4304// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3905 } 4305 }
3906 4306
3907 UUID objId = item.ItemID; 4307 UUID objId = item.ItemID;
@@ -3929,33 +4329,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3929 return; 4329 return;
3930 } 4330 }
3931 } 4331 }
4332
3932 // destination is an avatar 4333 // destination is an avatar
3933 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4334 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3934 4335
3935 if (agentItem == null) 4336 if (agentItem == null)
3936 return; 4337 return;
3937 4338
3938 if (m_TransferModule != null) 4339 byte[] bucket = new byte[1];
3939 { 4340 bucket[0] = (byte)item.Type;
3940 byte[] bucket = new byte[1]; 4341 //byte[] objBytes = agentItem.ID.GetBytes();
3941 bucket[0] = (byte)item.Type; 4342 //Array.Copy(objBytes, 0, bucket, 1, 16);
3942 4343
3943 GridInstantMessage msg = new GridInstantMessage(World, 4344 GridInstantMessage msg = new GridInstantMessage(World,
3944 m_host.OwnerID, m_host.Name, destId, 4345 m_host.OwnerID, m_host.Name, destId,
3945 (byte)InstantMessageDialog.TaskInventoryOffered, 4346 (byte)InstantMessageDialog.TaskInventoryOffered,
3946 false, item.Name+". "+m_host.Name+" is located at "+ 4347 false, item.Name+". "+m_host.Name+" is located at "+
3947 World.RegionInfo.RegionName+" "+ 4348 World.RegionInfo.RegionName+" "+
3948 m_host.AbsolutePosition.ToString(), 4349 m_host.AbsolutePosition.ToString(),
3949 agentItem.ID, true, m_host.AbsolutePosition, 4350 agentItem.ID, true, m_host.AbsolutePosition,
3950 bucket, true); 4351 bucket, true);
3951 4352
3952 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4353 ScenePresence sp;
3953 }
3954 4354
4355 if (World.TryGetScenePresence(destId, out sp))
4356 {
4357 sp.ControllingClient.SendInstantMessage(msg);
4358 }
4359 else
4360 {
4361 if (m_TransferModule != null)
4362 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4363 }
4364
4365 //This delay should only occur when giving inventory to avatars.
3955 ScriptSleep(3000); 4366 ScriptSleep(3000);
3956 } 4367 }
3957 } 4368 }
3958 4369
4370 [DebuggerNonUserCode]
3959 public void llRemoveInventory(string name) 4371 public void llRemoveInventory(string name)
3960 { 4372 {
3961 m_host.AddScriptLPS(1); 4373 m_host.AddScriptLPS(1);
@@ -4010,109 +4422,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4010 { 4422 {
4011 m_host.AddScriptLPS(1); 4423 m_host.AddScriptLPS(1);
4012 4424
4013 UUID uuid = (UUID)id; 4425 UUID uuid;
4014 PresenceInfo pinfo = null; 4426 if (UUID.TryParse(id, out uuid))
4015 UserAccount account;
4016
4017 UserInfoCacheEntry ce;
4018 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4019 { 4427 {
4020 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4428 PresenceInfo pinfo = null;
4021 if (account == null) 4429 UserAccount account;
4430
4431 UserInfoCacheEntry ce;
4432 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4022 { 4433 {
4023 m_userInfoCache[uuid] = null; // Cache negative 4434 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4024 return UUID.Zero.ToString(); 4435 if (account == null)
4025 } 4436 {
4437 m_userInfoCache[uuid] = null; // Cache negative
4438 return UUID.Zero.ToString();
4439 }
4026 4440
4027 4441
4028 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4442 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4029 if (pinfos != null && pinfos.Length > 0) 4443 if (pinfos != null && pinfos.Length > 0)
4030 {
4031 foreach (PresenceInfo p in pinfos)
4032 { 4444 {
4033 if (p.RegionID != UUID.Zero) 4445 foreach (PresenceInfo p in pinfos)
4034 { 4446 {
4035 pinfo = p; 4447 if (p.RegionID != UUID.Zero)
4448 {
4449 pinfo = p;
4450 }
4036 } 4451 }
4037 } 4452 }
4038 }
4039 4453
4040 ce = new UserInfoCacheEntry(); 4454 ce = new UserInfoCacheEntry();
4041 ce.time = Util.EnvironmentTickCount(); 4455 ce.time = Util.EnvironmentTickCount();
4042 ce.account = account; 4456 ce.account = account;
4043 ce.pinfo = pinfo; 4457 ce.pinfo = pinfo;
4044 } 4458 m_userInfoCache[uuid] = ce;
4045 else 4459 }
4046 { 4460 else
4047 if (ce == null) 4461 {
4048 return UUID.Zero.ToString(); 4462 if (ce == null)
4463 return UUID.Zero.ToString();
4049 4464
4050 account = ce.account; 4465 account = ce.account;
4051 pinfo = ce.pinfo; 4466 pinfo = ce.pinfo;
4052 } 4467 }
4053 4468
4054 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4469 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4055 {
4056 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4057 if (pinfos != null && pinfos.Length > 0)
4058 { 4470 {
4059 foreach (PresenceInfo p in pinfos) 4471 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4472 if (pinfos != null && pinfos.Length > 0)
4060 { 4473 {
4061 if (p.RegionID != UUID.Zero) 4474 foreach (PresenceInfo p in pinfos)
4062 { 4475 {
4063 pinfo = p; 4476 if (p.RegionID != UUID.Zero)
4477 {
4478 pinfo = p;
4479 }
4064 } 4480 }
4065 } 4481 }
4066 } 4482 else
4067 else 4483 pinfo = null;
4068 pinfo = null;
4069 4484
4070 ce.time = Util.EnvironmentTickCount(); 4485 ce.time = Util.EnvironmentTickCount();
4071 ce.pinfo = pinfo; 4486 ce.pinfo = pinfo;
4072 } 4487 }
4073 4488
4074 string reply = String.Empty; 4489 string reply = String.Empty;
4075 4490
4076 switch (data) 4491 switch (data)
4077 { 4492 {
4078 case 1: // DATA_ONLINE (0|1) 4493 case 1: // DATA_ONLINE (0|1)
4079 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4494 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4080 reply = "1"; 4495 reply = "1";
4081 else 4496 else
4082 reply = "0"; 4497 reply = "0";
4083 break; 4498 break;
4084 case 2: // DATA_NAME (First Last) 4499 case 2: // DATA_NAME (First Last)
4085 reply = account.FirstName + " " + account.LastName; 4500 reply = account.FirstName + " " + account.LastName;
4086 break; 4501 break;
4087 case 3: // DATA_BORN (YYYY-MM-DD) 4502 case 3: // DATA_BORN (YYYY-MM-DD)
4088 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4503 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4089 born = born.AddSeconds(account.Created); 4504 born = born.AddSeconds(account.Created);
4090 reply = born.ToString("yyyy-MM-dd"); 4505 reply = born.ToString("yyyy-MM-dd");
4091 break; 4506 break;
4092 case 4: // DATA_RATING (0,0,0,0,0,0) 4507 case 4: // DATA_RATING (0,0,0,0,0,0)
4093 reply = "0,0,0,0,0,0"; 4508 reply = "0,0,0,0,0,0";
4094 break; 4509 break;
4095 case 7: // DATA_USERLEVEL (integer) 4510 case 8: // DATA_PAYINFO (0|1|2|3)
4096 reply = account.UserLevel.ToString(); 4511 reply = "0";
4097 break; 4512 break;
4098 case 8: // DATA_PAYINFO (0|1|2|3) 4513 default:
4099 reply = "0"; 4514 return UUID.Zero.ToString(); // Raise no event
4100 break; 4515 }
4101 default:
4102 return UUID.Zero.ToString(); // Raise no event
4103 }
4104 4516
4105 UUID rq = UUID.Random(); 4517 UUID rq = UUID.Random();
4106 4518
4107 UUID tid = AsyncCommands. 4519 UUID tid = AsyncCommands.
4108 DataserverPlugin.RegisterRequest(m_host.LocalId, 4520 DataserverPlugin.RegisterRequest(m_host.LocalId,
4109 m_item.ItemID, rq.ToString()); 4521 m_item.ItemID, rq.ToString());
4110 4522
4111 AsyncCommands. 4523 AsyncCommands.
4112 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4524 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4113 4525
4114 ScriptSleep(100); 4526 ScriptSleep(100);
4115 return tid.ToString(); 4527 return tid.ToString();
4528 }
4529 else
4530 {
4531 ShoutError("Invalid UUID passed to llRequestAgentData.");
4532 }
4533 return "";
4116 } 4534 }
4117 4535
4118 public LSL_String llRequestInventoryData(string name) 4536 public LSL_String llRequestInventoryData(string name)
@@ -4169,12 +4587,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4169 if (UUID.TryParse(agent, out agentId)) 4587 if (UUID.TryParse(agent, out agentId))
4170 { 4588 {
4171 ScenePresence presence = World.GetScenePresence(agentId); 4589 ScenePresence presence = World.GetScenePresence(agentId);
4172 if (presence != null) 4590 if (presence != null && presence.PresenceType != PresenceType.Npc)
4173 { 4591 {
4592 // agent must not be a god
4593 if (presence.UserLevel >= 200) return;
4594
4174 // agent must be over the owners land 4595 // agent must be over the owners land
4175 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4596 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4176 { 4597 {
4177 World.TeleportClientHome(agentId, presence.ControllingClient); 4598 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4599 {
4600 // They can't be teleported home for some reason
4601 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4602 if (regionInfo != null)
4603 {
4604 World.RequestTeleportLocation(
4605 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4606 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4607 }
4608 }
4178 } 4609 }
4179 } 4610 }
4180 } 4611 }
@@ -4280,7 +4711,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4280 UUID av = new UUID(); 4711 UUID av = new UUID();
4281 if (!UUID.TryParse(agent,out av)) 4712 if (!UUID.TryParse(agent,out av))
4282 { 4713 {
4283 LSLError("First parameter to llDialog needs to be a key");
4284 return; 4714 return;
4285 } 4715 }
4286 4716
@@ -4312,10 +4742,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4312 public void llCollisionSound(string impact_sound, double impact_volume) 4742 public void llCollisionSound(string impact_sound, double impact_volume)
4313 { 4743 {
4314 m_host.AddScriptLPS(1); 4744 m_host.AddScriptLPS(1);
4315 4745
4746 if(impact_sound == "")
4747 {
4748 m_host.CollisionSoundVolume = (float)impact_volume;
4749 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4750 m_host.CollisionSoundType = 0;
4751 return;
4752 }
4316 // TODO: Parameter check logic required. 4753 // TODO: Parameter check logic required.
4317 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 4754 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4318 m_host.CollisionSoundVolume = (float)impact_volume; 4755 m_host.CollisionSoundVolume = (float)impact_volume;
4756 m_host.CollisionSoundType = 1;
4319 } 4757 }
4320 4758
4321 public LSL_String llGetAnimation(string id) 4759 public LSL_String llGetAnimation(string id)
@@ -4329,14 +4767,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4329 4767
4330 if (m_host.RegionHandle == presence.RegionHandle) 4768 if (m_host.RegionHandle == presence.RegionHandle)
4331 { 4769 {
4332 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4333
4334 if (presence != null) 4770 if (presence != null)
4335 { 4771 {
4336 AnimationSet currentAnims = presence.Animator.Animations; 4772 if (presence.SitGround)
4337 string currentAnimationState = String.Empty; 4773 return "Sitting on Ground";
4338 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4774 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4339 return currentAnimationState; 4775 return "Sitting";
4776
4777 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4778 string lslMovementAnimation;
4779
4780 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4781 return lslMovementAnimation;
4340 } 4782 }
4341 } 4783 }
4342 4784
@@ -4484,7 +4926,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4484 { 4926 {
4485 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4927 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4486 float distance_term = distance * distance * distance; // Script Energy 4928 float distance_term = distance * distance * distance; // Script Energy
4487 float pusher_mass = m_host.GetMass(); 4929 // use total object mass and not part
4930 float pusher_mass = m_host.ParentGroup.GetMass();
4488 4931
4489 float PUSH_ATTENUATION_DISTANCE = 17f; 4932 float PUSH_ATTENUATION_DISTANCE = 17f;
4490 float PUSH_ATTENUATION_SCALE = 5f; 4933 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4738,6 +5181,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4738 { 5181 {
4739 return item.AssetID.ToString(); 5182 return item.AssetID.ToString();
4740 } 5183 }
5184 m_host.TaskInventory.LockItemsForRead(false);
4741 5185
4742 return UUID.Zero.ToString(); 5186 return UUID.Zero.ToString();
4743 } 5187 }
@@ -4890,14 +5334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4890 { 5334 {
4891 m_host.AddScriptLPS(1); 5335 m_host.AddScriptLPS(1);
4892 5336
4893 if (src == null) 5337 return src.Length;
4894 {
4895 return 0;
4896 }
4897 else
4898 {
4899 return src.Length;
4900 }
4901 } 5338 }
4902 5339
4903 public LSL_Integer llList2Integer(LSL_List src, int index) 5340 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4968,7 +5405,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4968 else if (src.Data[index] is LSL_Float) 5405 else if (src.Data[index] is LSL_Float)
4969 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5406 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4970 else if (src.Data[index] is LSL_String) 5407 else if (src.Data[index] is LSL_String)
4971 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5408 {
5409 string str = ((LSL_String) src.Data[index]).m_string;
5410 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5411 if (m != Match.Empty)
5412 {
5413 str = m.Value;
5414 double d = 0.0;
5415 if (!Double.TryParse(str, out d))
5416 return 0.0;
5417
5418 return d;
5419 }
5420 return 0.0;
5421 }
4972 return Convert.ToDouble(src.Data[index]); 5422 return Convert.ToDouble(src.Data[index]);
4973 } 5423 }
4974 catch (FormatException) 5424 catch (FormatException)
@@ -5010,7 +5460,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5010 // for completion and should LSL_Key ever be implemented 5460 // for completion and should LSL_Key ever be implemented
5011 // as it's own struct 5461 // as it's own struct
5012 else if (!(src.Data[index] is LSL_String || 5462 else if (!(src.Data[index] is LSL_String ||
5013 src.Data[index] is LSL_Key)) 5463 src.Data[index] is LSL_Key ||
5464 src.Data[index] is String))
5014 { 5465 {
5015 return ""; 5466 return "";
5016 } 5467 }
@@ -5268,7 +5719,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5268 } 5719 }
5269 } 5720 }
5270 } 5721 }
5271 else { 5722 else
5723 {
5272 object[] array = new object[src.Length]; 5724 object[] array = new object[src.Length];
5273 Array.Copy(src.Data, 0, array, 0, src.Length); 5725 Array.Copy(src.Data, 0, array, 0, src.Length);
5274 result = new LSL_List(array); 5726 result = new LSL_List(array);
@@ -5375,7 +5827,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5375 public LSL_Integer llGetRegionAgentCount() 5827 public LSL_Integer llGetRegionAgentCount()
5376 { 5828 {
5377 m_host.AddScriptLPS(1); 5829 m_host.AddScriptLPS(1);
5378 return new LSL_Integer(World.GetRootAgentCount()); 5830
5831 int count = 0;
5832 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5833 count++;
5834 });
5835
5836 return new LSL_Integer(count);
5379 } 5837 }
5380 5838
5381 public LSL_Vector llGetRegionCorner() 5839 public LSL_Vector llGetRegionCorner()
@@ -5616,6 +6074,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5616 flags |= ScriptBaseClass.AGENT_AWAY; 6074 flags |= ScriptBaseClass.AGENT_AWAY;
5617 } 6075 }
5618 6076
6077 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6078 UUID[] anims = agent.Animator.GetAnimationArray();
6079 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6080 {
6081 flags |= ScriptBaseClass.AGENT_BUSY;
6082 }
6083
5619 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6084 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5620 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6085 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5621 { 6086 {
@@ -5663,6 +6128,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5663 flags |= ScriptBaseClass.AGENT_SITTING; 6128 flags |= ScriptBaseClass.AGENT_SITTING;
5664 } 6129 }
5665 6130
6131 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6132 {
6133 flags |= ScriptBaseClass.AGENT_MALE;
6134 }
6135
5666 return flags; 6136 return flags;
5667 } 6137 }
5668 6138
@@ -5808,9 +6278,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5808 6278
5809 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6279 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5810 6280
5811 foreach (SceneObjectPart part in parts) 6281 try
6282 {
6283 foreach (SceneObjectPart part in parts)
6284 {
6285 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6286 }
6287 }
6288 finally
5812 { 6289 {
5813 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5814 } 6290 }
5815 } 6291 }
5816 6292
@@ -5864,13 +6340,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5864 6340
5865 if (m_host.OwnerID == land.LandData.OwnerID) 6341 if (m_host.OwnerID == land.LandData.OwnerID)
5866 { 6342 {
5867 World.TeleportClientHome(agentID, presence.ControllingClient); 6343 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6344 presence.TeleportWithMomentum(p, null);
6345 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5868 } 6346 }
5869 } 6347 }
5870 } 6348 }
5871 ScriptSleep(5000); 6349 ScriptSleep(5000);
5872 } 6350 }
5873 6351
6352 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6353 {
6354 return ParseString2List(str, separators, in_spacers, false);
6355 }
6356
5874 public LSL_Integer llOverMyLand(string id) 6357 public LSL_Integer llOverMyLand(string id)
5875 { 6358 {
5876 m_host.AddScriptLPS(1); 6359 m_host.AddScriptLPS(1);
@@ -5923,25 +6406,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5923 } 6406 }
5924 else 6407 else
5925 { 6408 {
5926 agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); 6409// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6410 Vector3 s = avatar.Appearance.AvatarSize;
6411 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5927 } 6412 }
5928 return agentSize; 6413 return agentSize;
5929 } 6414 }
5930 6415
5931 public LSL_Integer llSameGroup(string agent) 6416 public LSL_Integer llSameGroup(string id)
5932 { 6417 {
5933 m_host.AddScriptLPS(1); 6418 m_host.AddScriptLPS(1);
5934 UUID agentId = new UUID(); 6419 UUID uuid = new UUID();
5935 if (!UUID.TryParse(agent, out agentId)) 6420 if (!UUID.TryParse(id, out uuid))
5936 return new LSL_Integer(0); 6421 return new LSL_Integer(0);
5937 ScenePresence presence = World.GetScenePresence(agentId); 6422
5938 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6423 // Check if it's a group key
5939 return new LSL_Integer(0); 6424 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5940 IClientAPI client = presence.ControllingClient;
5941 if (m_host.GroupID == client.ActiveGroupId)
5942 return new LSL_Integer(1); 6425 return new LSL_Integer(1);
5943 else 6426
6427 // We got passed a UUID.Zero
6428 if (uuid == UUID.Zero)
5944 return new LSL_Integer(0); 6429 return new LSL_Integer(0);
6430
6431 // Handle the case where id names an avatar
6432 ScenePresence presence = World.GetScenePresence(uuid);
6433 if (presence != null)
6434 {
6435 if (presence.IsChildAgent)
6436 return new LSL_Integer(0);
6437
6438 IClientAPI client = presence.ControllingClient;
6439 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6440 return new LSL_Integer(1);
6441
6442 return new LSL_Integer(0);
6443 }
6444
6445 // Handle object case
6446 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6447 if (part != null)
6448 {
6449 // This will handle both deed and non-deed and also the no
6450 // group case
6451 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6452 return new LSL_Integer(1);
6453
6454 return new LSL_Integer(0);
6455 }
6456
6457 return new LSL_Integer(0);
5945 } 6458 }
5946 6459
5947 public void llUnSit(string id) 6460 public void llUnSit(string id)
@@ -6068,7 +6581,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6068 return m_host.ParentGroup.AttachmentPoint; 6581 return m_host.ParentGroup.AttachmentPoint;
6069 } 6582 }
6070 6583
6071 public LSL_Integer llGetFreeMemory() 6584 public virtual LSL_Integer llGetFreeMemory()
6072 { 6585 {
6073 m_host.AddScriptLPS(1); 6586 m_host.AddScriptLPS(1);
6074 // Make scripts designed for LSO happy 6587 // Make scripts designed for LSO happy
@@ -6500,6 +7013,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6500 7013
6501 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7014 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6502 { 7015 {
7016 // LSL quaternions can normalize to 0, normal Quaternions can't.
7017 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7018 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7019
6503 part.SitTargetPosition = offset; 7020 part.SitTargetPosition = offset;
6504 part.SitTargetOrientation = rot; 7021 part.SitTargetOrientation = rot;
6505 part.ParentGroup.HasGroupChanged = true; 7022 part.ParentGroup.HasGroupChanged = true;
@@ -6686,30 +7203,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6686 UUID av = new UUID(); 7203 UUID av = new UUID();
6687 if (!UUID.TryParse(avatar,out av)) 7204 if (!UUID.TryParse(avatar,out av))
6688 { 7205 {
6689 LSLError("First parameter to llDialog needs to be a key"); 7206 //LSLError("First parameter to llDialog needs to be a key");
6690 return; 7207 return;
6691 } 7208 }
6692 if (buttons.Length < 1) 7209 if (buttons.Length < 1)
6693 { 7210 {
6694 LSLError("No less than 1 button can be shown"); 7211 buttons.Add("OK");
6695 return;
6696 } 7212 }
6697 if (buttons.Length > 12) 7213 if (buttons.Length > 12)
6698 { 7214 {
6699 LSLError("No more than 12 buttons can be shown"); 7215 ShoutError("button list too long, must be 12 or fewer entries");
6700 return;
6701 } 7216 }
6702 string[] buts = new string[buttons.Length]; 7217 int length = buttons.Length;
6703 for (int i = 0; i < buttons.Length; i++) 7218 if (length > 12)
7219 length = 12;
7220
7221 string[] buts = new string[length];
7222 for (int i = 0; i < length; i++)
6704 { 7223 {
6705 if (buttons.Data[i].ToString() == String.Empty) 7224 if (buttons.Data[i].ToString() == String.Empty)
6706 { 7225 {
6707 LSLError("button label cannot be blank"); 7226 ShoutError("button label cannot be blank");
6708 return; 7227 return;
6709 } 7228 }
6710 if (buttons.Data[i].ToString().Length > 24) 7229 if (buttons.Data[i].ToString().Length > 24)
6711 { 7230 {
6712 LSLError("button label cannot be longer than 24 characters"); 7231 ShoutError("button label cannot be longer than 24 characters");
6713 return; 7232 return;
6714 } 7233 }
6715 buts[i] = buttons.Data[i].ToString(); 7234 buts[i] = buttons.Data[i].ToString();
@@ -6776,9 +7295,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6776 return; 7295 return;
6777 } 7296 }
6778 7297
6779 // the rest of the permission checks are done in RezScript, so check the pin there as well 7298 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6780 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7299 if (dest != null)
7300 {
7301 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7302 {
7303 // the rest of the permission checks are done in RezScript, so check the pin there as well
7304 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6781 7305
7306 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7307 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7308 }
7309 }
6782 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7310 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6783 ScriptSleep(3000); 7311 ScriptSleep(3000);
6784 } 7312 }
@@ -6852,19 +7380,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6852 public LSL_String llMD5String(string src, int nonce) 7380 public LSL_String llMD5String(string src, int nonce)
6853 { 7381 {
6854 m_host.AddScriptLPS(1); 7382 m_host.AddScriptLPS(1);
6855 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7383 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6856 } 7384 }
6857 7385
6858 public LSL_String llSHA1String(string src) 7386 public LSL_String llSHA1String(string src)
6859 { 7387 {
6860 m_host.AddScriptLPS(1); 7388 m_host.AddScriptLPS(1);
6861 return Util.SHA1Hash(src).ToLower(); 7389 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6862 } 7390 }
6863 7391
6864 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7392 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6865 { 7393 {
6866 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7394 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6867 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7395 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7396 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7397 return shapeBlock;
6868 7398
6869 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7399 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6870 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7400 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6969,6 +7499,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6969 // Prim type box, cylinder and prism. 7499 // Prim type box, cylinder and prism.
6970 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) 7500 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)
6971 { 7501 {
7502 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7503 return;
7504
6972 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7505 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6973 ObjectShapePacket.ObjectDataBlock shapeBlock; 7506 ObjectShapePacket.ObjectDataBlock shapeBlock;
6974 7507
@@ -7022,6 +7555,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7022 // Prim type sphere. 7555 // Prim type sphere.
7023 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7556 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7024 { 7557 {
7558 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7559 return;
7560
7025 ObjectShapePacket.ObjectDataBlock shapeBlock; 7561 ObjectShapePacket.ObjectDataBlock shapeBlock;
7026 7562
7027 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7563 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7063,6 +7599,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7063 // Prim type torus, tube and ring. 7599 // Prim type torus, tube and ring.
7064 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) 7600 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)
7065 { 7601 {
7602 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7603 return;
7604
7066 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7605 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7067 ObjectShapePacket.ObjectDataBlock shapeBlock; 7606 ObjectShapePacket.ObjectDataBlock shapeBlock;
7068 7607
@@ -7198,6 +7737,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7198 // Prim type sculpt. 7737 // Prim type sculpt.
7199 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7738 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7200 { 7739 {
7740 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7741 return;
7742
7201 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7743 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7202 UUID sculptId; 7744 UUID sculptId;
7203 7745
@@ -7220,7 +7762,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7220 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7762 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7221 { 7763 {
7222 // default 7764 // default
7223 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7765 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7224 } 7766 }
7225 7767
7226 part.Shape.SetSculptProperties((byte)type, sculptId); 7768 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7237,48 +7779,130 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7237 ScriptSleep(200); 7779 ScriptSleep(200);
7238 } 7780 }
7239 7781
7240 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7782 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7241 { 7783 {
7242 m_host.AddScriptLPS(1); 7784 m_host.AddScriptLPS(1);
7243 7785
7244 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7786 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7787 }
7245 7788
7246 ScriptSleep(200); 7789 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7790 {
7791 List<object> parts = new List<object>();
7792 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7793 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7794 foreach (SceneObjectPart p in prims)
7795 parts.Add(p);
7796 foreach (ScenePresence p in avatars)
7797 parts.Add(p);
7798
7799 LSL_List remaining = null;
7800 uint rulesParsed = 0;
7801
7802 if (parts.Count > 0)
7803 {
7804 foreach (object part in parts)
7805 {
7806 if (part is SceneObjectPart)
7807 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7808 else
7809 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7810 }
7811
7812 while ((object)remaining != null && remaining.Length > 2)
7813 {
7814 linknumber = remaining.GetLSLIntegerItem(0);
7815 rules = remaining.GetSublist(1, -1);
7816 parts.Clear();
7817 prims = GetLinkParts(linknumber);
7818 avatars = GetLinkAvatars(linknumber);
7819 foreach (SceneObjectPart p in prims)
7820 parts.Add(p);
7821 foreach (ScenePresence p in avatars)
7822 parts.Add(p);
7823
7824 remaining = null;
7825 foreach (object part in parts)
7826 {
7827 if (part is SceneObjectPart)
7828 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7829 else
7830 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7831 }
7832 }
7833 }
7247 } 7834 }
7248 7835
7249 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7836 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7837 float material_density, float material_friction,
7838 float material_restitution, float material_gravity_modifier)
7250 { 7839 {
7251 m_host.AddScriptLPS(1); 7840 ExtraPhysicsData physdata = new ExtraPhysicsData();
7841 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7842 physdata.Density = part.Density;
7843 physdata.Friction = part.Friction;
7844 physdata.Bounce = part.Restitution;
7845 physdata.GravitationModifier = part.GravityModifier;
7252 7846
7253 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7847 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7848 physdata.Density = material_density;
7849 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7850 physdata.Friction = material_friction;
7851 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7852 physdata.Bounce = material_restitution;
7853 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7854 physdata.GravitationModifier = material_gravity_modifier;
7855
7856 part.UpdateExtraPhysics(physdata);
7254 } 7857 }
7255 7858
7256 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7859 public void llSetPhysicsMaterial(int material_bits,
7860 float material_gravity_modifier, float material_restitution,
7861 float material_friction, float material_density)
7257 { 7862 {
7258 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7863 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7864 }
7259 7865
7260 LSL_List remaining = null; 7866 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7261 uint rulesParsed = 0; 7867 {
7868 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7869 llSetLinkPrimitiveParamsFast(linknumber, rules);
7870 ScriptSleep(200);
7871 }
7262 7872
7263 foreach (SceneObjectPart part in parts) 7873 // vector up using libomv (c&p from sop )
7264 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7874 // vector up rotated by r
7875 private Vector3 Zrot(Quaternion r)
7876 {
7877 double x, y, z, m;
7265 7878
7266 while (remaining != null && remaining.Length > 2) 7879 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7880 if (Math.Abs(1.0 - m) > 0.000001)
7267 { 7881 {
7268 linknumber = remaining.GetLSLIntegerItem(0); 7882 m = 1.0 / Math.Sqrt(m);
7269 rules = remaining.GetSublist(1, -1); 7883 r.X *= (float)m;
7270 parts = GetLinkParts(linknumber); 7884 r.Y *= (float)m;
7271 7885 r.Z *= (float)m;
7272 foreach (SceneObjectPart part in parts) 7886 r.W *= (float)m;
7273 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7274 } 7887 }
7888
7889 x = 2 * (r.X * r.Z + r.Y * r.W);
7890 y = 2 * (-r.X * r.W + r.Y * r.Z);
7891 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7892
7893 return new Vector3((float)x, (float)y, (float)z);
7275 } 7894 }
7276 7895
7277 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7896 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7278 { 7897 {
7898 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7899 return null;
7900
7279 int idx = 0; 7901 int idx = 0;
7280 int idxStart = 0; 7902 int idxStart = 0;
7281 7903
7904 SceneObjectGroup parentgrp = part.ParentGroup;
7905
7282 bool positionChanged = false; 7906 bool positionChanged = false;
7283 LSL_Vector currentPosition = GetPartLocalPos(part); 7907 LSL_Vector currentPosition = GetPartLocalPos(part);
7284 7908
@@ -7303,8 +7927,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7303 return null; 7927 return null;
7304 7928
7305 v=rules.GetVector3Item(idx++); 7929 v=rules.GetVector3Item(idx++);
7930 if (part.IsRoot && !part.ParentGroup.IsAttachment)
7931 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
7932 else
7933 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7306 positionChanged = true; 7934 positionChanged = true;
7307 currentPosition = GetSetPosTarget(part, v, currentPosition);
7308 7935
7309 break; 7936 break;
7310 case (int)ScriptBaseClass.PRIM_SIZE: 7937 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7321,7 +7948,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7321 7948
7322 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7949 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7323 // try to let this work as in SL... 7950 // try to let this work as in SL...
7324 if (part.ParentID == 0) 7951 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7325 { 7952 {
7326 // special case: If we are root, rotate complete SOG to new rotation 7953 // special case: If we are root, rotate complete SOG to new rotation
7327 SetRot(part, q); 7954 SetRot(part, q);
@@ -7581,7 +8208,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7581 return null; 8208 return null;
7582 8209
7583 string ph = rules.Data[idx++].ToString(); 8210 string ph = rules.Data[idx++].ToString();
7584 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8211 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7585 8212
7586 break; 8213 break;
7587 8214
@@ -7615,12 +8242,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7615 8242
7616 break; 8243 break;
7617 8244
8245 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8246 if (remain < 5)
8247 return null;
8248
8249 int material_bits = rules.GetLSLIntegerItem(idx++);
8250 float material_density = (float)rules.GetLSLFloatItem(idx++);
8251 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8252 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8253 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8254
8255 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8256
8257 break;
8258
7618 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8259 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7619 if (remain < 1) 8260 if (remain < 1)
7620 return null; 8261 return null;
7621 string temp = rules.Data[idx++].ToString(); 8262 string temp = rules.Data[idx++].ToString();
7622 8263
7623 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8264 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7624 8265
7625 break; 8266 break;
7626 8267
@@ -7694,14 +8335,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7694 if (part.ParentGroup.RootPart == part) 8335 if (part.ParentGroup.RootPart == part)
7695 { 8336 {
7696 SceneObjectGroup parent = part.ParentGroup; 8337 SceneObjectGroup parent = part.ParentGroup;
7697 parent.UpdateGroupPosition(currentPosition); 8338 Util.FireAndForget(delegate(object x) {
8339 parent.UpdateGroupPosition(currentPosition);
8340 });
7698 } 8341 }
7699 else 8342 else
7700 { 8343 {
7701 part.OffsetPosition = currentPosition; 8344 part.OffsetPosition = currentPosition;
7702 SceneObjectGroup parent = part.ParentGroup; 8345// SceneObjectGroup parent = part.ParentGroup;
7703 parent.HasGroupChanged = true; 8346// parent.HasGroupChanged = true;
7704 parent.ScheduleGroupForTerseUpdate(); 8347// parent.ScheduleGroupForTerseUpdate();
8348 part.ScheduleTerseUpdate();
7705 } 8349 }
7706 } 8350 }
7707 } 8351 }
@@ -7739,10 +8383,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7739 8383
7740 public LSL_String llXorBase64Strings(string str1, string str2) 8384 public LSL_String llXorBase64Strings(string str1, string str2)
7741 { 8385 {
7742 m_host.AddScriptLPS(1); 8386 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7743 Deprecated("llXorBase64Strings"); 8387
7744 ScriptSleep(300); 8388 ScriptSleep(300);
7745 return String.Empty; 8389 m_host.AddScriptLPS(1);
8390
8391 if (str1 == String.Empty)
8392 return String.Empty;
8393 if (str2 == String.Empty)
8394 return str1;
8395
8396 int len = str2.Length;
8397 if ((len % 4) != 0) // LL is EVIL!!!!
8398 {
8399 while (str2.EndsWith("="))
8400 str2 = str2.Substring(0, str2.Length - 1);
8401
8402 len = str2.Length;
8403 int mod = len % 4;
8404
8405 if (mod == 1)
8406 str2 = str2.Substring(0, str2.Length - 1);
8407 else if (mod == 2)
8408 str2 += "==";
8409 else if (mod == 3)
8410 str2 += "=";
8411 }
8412
8413 byte[] data1;
8414 byte[] data2;
8415 try
8416 {
8417 data1 = Convert.FromBase64String(str1);
8418 data2 = Convert.FromBase64String(str2);
8419 }
8420 catch (Exception)
8421 {
8422 return new LSL_String(String.Empty);
8423 }
8424
8425 // For cases where the decoded length of s2 is greater
8426 // than the decoded length of s1, simply perform a normal
8427 // decode and XOR
8428 //
8429 if (data2.Length >= data1.Length)
8430 {
8431 for (int pos = 0 ; pos < data1.Length ; pos++ )
8432 data1[pos] ^= data2[pos];
8433
8434 return Convert.ToBase64String(data1);
8435 }
8436
8437 // Remove padding
8438 while (str1.EndsWith("="))
8439 str1 = str1.Substring(0, str1.Length - 1);
8440 while (str2.EndsWith("="))
8441 str2 = str2.Substring(0, str2.Length - 1);
8442
8443 byte[] d1 = new byte[str1.Length];
8444 byte[] d2 = new byte[str2.Length];
8445
8446 for (int i = 0 ; i < str1.Length ; i++)
8447 {
8448 int idx = b64.IndexOf(str1.Substring(i, 1));
8449 if (idx == -1)
8450 idx = 0;
8451 d1[i] = (byte)idx;
8452 }
8453
8454 for (int i = 0 ; i < str2.Length ; i++)
8455 {
8456 int idx = b64.IndexOf(str2.Substring(i, 1));
8457 if (idx == -1)
8458 idx = 0;
8459 d2[i] = (byte)idx;
8460 }
8461
8462 string output = String.Empty;
8463
8464 for (int pos = 0 ; pos < d1.Length ; pos++)
8465 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8466
8467 while (output.Length % 3 > 0)
8468 output += "=";
8469
8470 return output;
7746 } 8471 }
7747 8472
7748 public void llRemoteDataSetRegion() 8473 public void llRemoteDataSetRegion()
@@ -7867,8 +8592,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7867 public LSL_Integer llGetNumberOfPrims() 8592 public LSL_Integer llGetNumberOfPrims()
7868 { 8593 {
7869 m_host.AddScriptLPS(1); 8594 m_host.AddScriptLPS(1);
7870 8595 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7871 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8596
8597 return m_host.ParentGroup.PrimCount + avatarCount;
7872 } 8598 }
7873 8599
7874 /// <summary> 8600 /// <summary>
@@ -7883,55 +8609,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7883 m_host.AddScriptLPS(1); 8609 m_host.AddScriptLPS(1);
7884 UUID objID = UUID.Zero; 8610 UUID objID = UUID.Zero;
7885 LSL_List result = new LSL_List(); 8611 LSL_List result = new LSL_List();
8612
8613 // If the ID is not valid, return null result
7886 if (!UUID.TryParse(obj, out objID)) 8614 if (!UUID.TryParse(obj, out objID))
7887 { 8615 {
7888 result.Add(new LSL_Vector()); 8616 result.Add(new LSL_Vector());
7889 result.Add(new LSL_Vector()); 8617 result.Add(new LSL_Vector());
7890 return result; 8618 return result;
7891 } 8619 }
8620
8621 // Check if this is an attached prim. If so, replace
8622 // the UUID with the avatar UUID and report it's bounding box
8623 SceneObjectPart part = World.GetSceneObjectPart(objID);
8624 if (part != null && part.ParentGroup.IsAttachment)
8625 objID = part.ParentGroup.AttachedAvatar;
8626
8627 // Find out if this is an avatar ID. If so, return it's box
7892 ScenePresence presence = World.GetScenePresence(objID); 8628 ScenePresence presence = World.GetScenePresence(objID);
7893 if (presence != null) 8629 if (presence != null)
7894 { 8630 {
7895 if (presence.ParentID == 0) // not sat on an object 8631 // As per LSL Wiki, there is no difference between sitting
8632 // and standing avatar since server 1.36
8633 LSL_Vector lower;
8634 LSL_Vector upper;
8635
8636 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8637
8638 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8639 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8640/*
7896 { 8641 {
7897 LSL_Vector lower; 8642 // This is for ground sitting avatars
7898 LSL_Vector upper; 8643 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7899 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8644 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7900 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8645 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7901 {
7902 // This is for ground sitting avatars
7903 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7904 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7905 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7906 }
7907 else
7908 {
7909 // This is for standing/flying avatars
7910 float height = presence.Appearance.AvatarHeight / 2.0f;
7911 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7912 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7913 }
7914 result.Add(lower);
7915 result.Add(upper);
7916 return result;
7917 } 8646 }
7918 else 8647 else
7919 { 8648 {
7920 // sitting on an object so we need the bounding box of that 8649 // This is for standing/flying avatars
7921 // which should include the avatar so set the UUID to the 8650 float height = presence.Appearance.AvatarHeight / 2.0f;
7922 // UUID of the object the avatar is sat on and allow it to fall through 8651 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7923 // to processing an object 8652 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7924 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID); 8653 }
7925 objID = p.UUID; 8654
8655 // Adjust to the documented error offsets (see LSL Wiki)
8656 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8657 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8658*/
8659 {
8660 // This is for ground sitting avatars TODO!
8661 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8662 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
7926 } 8663 }
8664 else
8665 {
8666 // This is for standing/flying avatars
8667 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8668 upper = new LSL_Vector(box.X, box.Y, box.Z);
8669 }
8670
8671 if (lower.x > upper.x)
8672 lower.x = upper.x;
8673 if (lower.y > upper.y)
8674 lower.y = upper.y;
8675 if (lower.z > upper.z)
8676 lower.z = upper.z;
8677
8678 result.Add(lower);
8679 result.Add(upper);
8680 return result;
7927 } 8681 }
7928 SceneObjectPart part = World.GetSceneObjectPart(objID); 8682
8683 part = World.GetSceneObjectPart(objID);
7929 // Currently only works for single prims without a sitting avatar 8684 // Currently only works for single prims without a sitting avatar
7930 if (part != null) 8685 if (part != null)
7931 { 8686 {
7932 Vector3 halfSize = part.Scale / 2.0f; 8687 float minX;
7933 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8688 float maxX;
7934 LSL_Vector upper = new LSL_Vector(halfSize); 8689 float minY;
8690 float maxY;
8691 float minZ;
8692 float maxZ;
8693
8694 // This BBox is in sim coordinates, with the offset being
8695 // a contained point.
8696 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8697 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8698
8699 minX -= offsets[0].X;
8700 maxX -= offsets[0].X;
8701 minY -= offsets[0].Y;
8702 maxY -= offsets[0].Y;
8703 minZ -= offsets[0].Z;
8704 maxZ -= offsets[0].Z;
8705
8706 LSL_Vector lower;
8707 LSL_Vector upper;
8708
8709 // Adjust to the documented error offsets (see LSL Wiki)
8710 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8711 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8712
8713 if (lower.x > upper.x)
8714 lower.x = upper.x;
8715 if (lower.y > upper.y)
8716 lower.y = upper.y;
8717 if (lower.z > upper.z)
8718 lower.z = upper.z;
8719
7935 result.Add(lower); 8720 result.Add(lower);
7936 result.Add(upper); 8721 result.Add(upper);
7937 return result; 8722 return result;
@@ -7956,7 +8741,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7956 8741
7957 LSL_List remaining = GetPrimParams(m_host, rules, ref result); 8742 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
7958 8743
7959 while (remaining != null && remaining.Length > 2) 8744 while ((object)remaining != null && remaining.Length > 2)
7960 { 8745 {
7961 int linknumber = remaining.GetLSLIntegerItem(0); 8746 int linknumber = remaining.GetLSLIntegerItem(0);
7962 rules = remaining.GetSublist(1, -1); 8747 rules = remaining.GetSublist(1, -1);
@@ -7973,24 +8758,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7973 { 8758 {
7974 m_host.AddScriptLPS(1); 8759 m_host.AddScriptLPS(1);
7975 8760
7976 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8761 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8762 // keep other options as before
7977 8763
8764 List<SceneObjectPart> parts;
8765 List<ScenePresence> avatars;
8766
7978 LSL_List res = new LSL_List(); 8767 LSL_List res = new LSL_List();
7979 LSL_List remaining = null; 8768 LSL_List remaining = null;
7980 8769
7981 foreach (SceneObjectPart part in parts) 8770 while (rules.Length > 0)
7982 { 8771 {
7983 remaining = GetPrimParams(part, rules, ref res);
7984 }
7985
7986 while (remaining != null && remaining.Length > 2)
7987 {
7988 linknumber = remaining.GetLSLIntegerItem(0);
7989 rules = remaining.GetSublist(1, -1);
7990 parts = GetLinkParts(linknumber); 8772 parts = GetLinkParts(linknumber);
8773 avatars = GetLinkAvatars(linknumber);
7991 8774
8775 remaining = null;
7992 foreach (SceneObjectPart part in parts) 8776 foreach (SceneObjectPart part in parts)
8777 {
7993 remaining = GetPrimParams(part, rules, ref res); 8778 remaining = GetPrimParams(part, rules, ref res);
8779 }
8780 foreach (ScenePresence avatar in avatars)
8781 {
8782 remaining = GetPrimParams(avatar, rules, ref res);
8783 }
8784
8785 if ((object)remaining != null && remaining.Length > 0)
8786 {
8787 linknumber = remaining.GetLSLIntegerItem(0);
8788 rules = remaining.GetSublist(1, -1);
8789 }
8790 else
8791 break;
7994 } 8792 }
7995 8793
7996 return res; 8794 return res;
@@ -8032,19 +8830,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8032 break; 8830 break;
8033 8831
8034 case (int)ScriptBaseClass.PRIM_POSITION: 8832 case (int)ScriptBaseClass.PRIM_POSITION:
8035 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 8833 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8036 8834 part.AbsolutePosition.Y,
8037 // For some reason, the part.AbsolutePosition.* values do not change if the 8835 part.AbsolutePosition.Z);
8038 // linkset is rotated; they always reflect the child prim's world position
8039 // as though the linkset is unrotated. This is incompatible behavior with SL's
8040 // implementation, so will break scripts imported from there (not to mention it
8041 // makes it more difficult to determine a child prim's actual inworld position).
8042 if (!part.IsRoot)
8043 {
8044 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8045 v = ((v - rootPos) * llGetRootRotation()) + rootPos;
8046 }
8047
8048 res.Add(v); 8836 res.Add(v);
8049 break; 8837 break;
8050 8838
@@ -8214,30 +9002,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8214 if (remain < 1) 9002 if (remain < 1)
8215 return null; 9003 return null;
8216 9004
8217 face=(int)rules.GetLSLIntegerItem(idx++); 9005 face = (int)rules.GetLSLIntegerItem(idx++);
8218 9006
8219 tex = part.Shape.Textures; 9007 tex = part.Shape.Textures;
9008 int shiny;
8220 if (face == ScriptBaseClass.ALL_SIDES) 9009 if (face == ScriptBaseClass.ALL_SIDES)
8221 { 9010 {
8222 for (face = 0; face < GetNumberOfSides(part); face++) 9011 for (face = 0; face < GetNumberOfSides(part); face++)
8223 { 9012 {
8224 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9013 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8225 // Convert Shininess to PRIM_SHINY_* 9014 if (shinyness == Shininess.High)
8226 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9015 {
8227 // PRIM_BUMP_* 9016 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8228 res.Add(new LSL_Integer((int)texface.Bump)); 9017 }
9018 else if (shinyness == Shininess.Medium)
9019 {
9020 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9021 }
9022 else if (shinyness == Shininess.Low)
9023 {
9024 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9025 }
9026 else
9027 {
9028 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9029 }
9030 res.Add(new LSL_Integer(shiny));
9031 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8229 } 9032 }
8230 } 9033 }
8231 else 9034 else
8232 { 9035 {
8233 if (face >= 0 && face < GetNumberOfSides(part)) 9036 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9037 if (shinyness == Shininess.High)
8234 { 9038 {
8235 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9039 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8236 // Convert Shininess to PRIM_SHINY_* 9040 }
8237 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9041 else if (shinyness == Shininess.Medium)
8238 // PRIM_BUMP_* 9042 {
8239 res.Add(new LSL_Integer((int)texface.Bump)); 9043 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9044 }
9045 else if (shinyness == Shininess.Low)
9046 {
9047 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8240 } 9048 }
9049 else
9050 {
9051 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9052 }
9053 res.Add(new LSL_Integer(shiny));
9054 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8241 } 9055 }
8242 break; 9056 break;
8243 9057
@@ -8245,24 +9059,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8245 if (remain < 1) 9059 if (remain < 1)
8246 return null; 9060 return null;
8247 9061
8248 face=(int)rules.GetLSLIntegerItem(idx++); 9062 face = (int)rules.GetLSLIntegerItem(idx++);
8249 9063
8250 tex = part.Shape.Textures; 9064 tex = part.Shape.Textures;
9065 int fullbright;
8251 if (face == ScriptBaseClass.ALL_SIDES) 9066 if (face == ScriptBaseClass.ALL_SIDES)
8252 { 9067 {
8253 for (face = 0; face < GetNumberOfSides(part); face++) 9068 for (face = 0; face < GetNumberOfSides(part); face++)
8254 { 9069 {
8255 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9070 if (tex.GetFace((uint)face).Fullbright == true)
8256 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9071 {
9072 fullbright = ScriptBaseClass.TRUE;
9073 }
9074 else
9075 {
9076 fullbright = ScriptBaseClass.FALSE;
9077 }
9078 res.Add(new LSL_Integer(fullbright));
8257 } 9079 }
8258 } 9080 }
8259 else 9081 else
8260 { 9082 {
8261 if (face >= 0 && face < GetNumberOfSides(part)) 9083 if (tex.GetFace((uint)face).Fullbright == true)
8262 { 9084 {
8263 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9085 fullbright = ScriptBaseClass.TRUE;
8264 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8265 } 9086 }
9087 else
9088 {
9089 fullbright = ScriptBaseClass.FALSE;
9090 }
9091 res.Add(new LSL_Integer(fullbright));
8266 } 9092 }
8267 break; 9093 break;
8268 9094
@@ -8284,27 +9110,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8284 break; 9110 break;
8285 9111
8286 case (int)ScriptBaseClass.PRIM_TEXGEN: 9112 case (int)ScriptBaseClass.PRIM_TEXGEN:
9113 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8287 if (remain < 1) 9114 if (remain < 1)
8288 return null; 9115 return null;
8289 9116
8290 face=(int)rules.GetLSLIntegerItem(idx++); 9117 face = (int)rules.GetLSLIntegerItem(idx++);
8291 9118
8292 tex = part.Shape.Textures; 9119 tex = part.Shape.Textures;
8293 if (face == ScriptBaseClass.ALL_SIDES) 9120 if (face == ScriptBaseClass.ALL_SIDES)
8294 { 9121 {
8295 for (face = 0; face < GetNumberOfSides(part); face++) 9122 for (face = 0; face < GetNumberOfSides(part); face++)
8296 { 9123 {
8297 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9124 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8298 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9125 {
8299 res.Add(new LSL_Integer((uint)texgen >> 1)); 9126 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9127 }
9128 else
9129 {
9130 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9131 }
8300 } 9132 }
8301 } 9133 }
8302 else 9134 else
8303 { 9135 {
8304 if (face >= 0 && face < GetNumberOfSides(part)) 9136 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8305 { 9137 {
8306 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9138 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8307 res.Add(new LSL_Integer((uint)texgen >> 1)); 9139 }
9140 else
9141 {
9142 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8308 } 9143 }
8309 } 9144 }
8310 break; 9145 break;
@@ -8328,24 +9163,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8328 if (remain < 1) 9163 if (remain < 1)
8329 return null; 9164 return null;
8330 9165
8331 face=(int)rules.GetLSLIntegerItem(idx++); 9166 face = (int)rules.GetLSLIntegerItem(idx++);
8332 9167
8333 tex = part.Shape.Textures; 9168 tex = part.Shape.Textures;
9169 float primglow;
8334 if (face == ScriptBaseClass.ALL_SIDES) 9170 if (face == ScriptBaseClass.ALL_SIDES)
8335 { 9171 {
8336 for (face = 0; face < GetNumberOfSides(part); face++) 9172 for (face = 0; face < GetNumberOfSides(part); face++)
8337 { 9173 {
8338 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9174 primglow = tex.GetFace((uint)face).Glow;
8339 res.Add(new LSL_Float(texface.Glow)); 9175 res.Add(new LSL_Float(primglow));
8340 } 9176 }
8341 } 9177 }
8342 else 9178 else
8343 { 9179 {
8344 if (face >= 0 && face < GetNumberOfSides(part)) 9180 primglow = tex.GetFace((uint)face).Glow;
8345 { 9181 res.Add(new LSL_Float(primglow));
8346 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8347 res.Add(new LSL_Float(texface.Glow));
8348 }
8349 } 9182 }
8350 break; 9183 break;
8351 9184
@@ -8357,15 +9190,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8357 textColor.B)); 9190 textColor.B));
8358 res.Add(new LSL_Float(textColor.A)); 9191 res.Add(new LSL_Float(textColor.A));
8359 break; 9192 break;
9193
8360 case (int)ScriptBaseClass.PRIM_NAME: 9194 case (int)ScriptBaseClass.PRIM_NAME:
8361 res.Add(new LSL_String(part.Name)); 9195 res.Add(new LSL_String(part.Name));
8362 break; 9196 break;
9197
8363 case (int)ScriptBaseClass.PRIM_DESC: 9198 case (int)ScriptBaseClass.PRIM_DESC:
8364 res.Add(new LSL_String(part.Description)); 9199 res.Add(new LSL_String(part.Description));
8365 break; 9200 break;
8366 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9201 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8367 res.Add(new LSL_Rotation(part.RotationOffset)); 9202 res.Add(new LSL_Rotation(part.RotationOffset));
8368 break; 9203 break;
9204
8369 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9205 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8370 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9206 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8371 break; 9207 break;
@@ -8976,8 +9812,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8976 // The function returns an ordered list 9812 // The function returns an ordered list
8977 // representing the tokens found in the supplied 9813 // representing the tokens found in the supplied
8978 // sources string. If two successive tokenizers 9814 // sources string. If two successive tokenizers
8979 // are encountered, then a NULL entry is added 9815 // are encountered, then a null-string entry is
8980 // to the list. 9816 // added to the list.
8981 // 9817 //
8982 // It is a precondition that the source and 9818 // It is a precondition that the source and
8983 // toekizer lisst are non-null. If they are null, 9819 // toekizer lisst are non-null. If they are null,
@@ -8985,7 +9821,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8985 // while their lengths are being determined. 9821 // while their lengths are being determined.
8986 // 9822 //
8987 // A small amount of working memoryis required 9823 // A small amount of working memoryis required
8988 // of approximately 8*#tokenizers. 9824 // of approximately 8*#tokenizers + 8*srcstrlen.
8989 // 9825 //
8990 // There are many ways in which this function 9826 // There are many ways in which this function
8991 // can be implemented, this implementation is 9827 // can be implemented, this implementation is
@@ -9001,155 +9837,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9001 // and eliminates redundant tokenizers as soon 9837 // and eliminates redundant tokenizers as soon
9002 // as is possible. 9838 // as is possible.
9003 // 9839 //
9004 // The implementation tries to avoid any copying 9840 // The implementation tries to minimize temporary
9005 // of arrays or other objects. 9841 // garbage generation.
9006 // </remarks> 9842 // </remarks>
9007 9843
9008 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9844 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9009 { 9845 {
9010 int beginning = 0; 9846 return ParseString2List(src, separators, spacers, true);
9011 int srclen = src.Length; 9847 }
9012 int seplen = separators.Length;
9013 object[] separray = separators.Data;
9014 int spclen = spacers.Length;
9015 object[] spcarray = spacers.Data;
9016 int mlen = seplen+spclen;
9017
9018 int[] offset = new int[mlen+1];
9019 bool[] active = new bool[mlen];
9020
9021 int best;
9022 int j;
9023
9024 // Initial capacity reduces resize cost
9025 9848
9026 LSL_List tokens = new LSL_List(); 9849 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9850 {
9851 int srclen = src.Length;
9852 int seplen = separators.Length;
9853 object[] separray = separators.Data;
9854 int spclen = spacers.Length;
9855 object[] spcarray = spacers.Data;
9856 int dellen = 0;
9857 string[] delarray = new string[seplen+spclen];
9027 9858
9028 // All entries are initially valid 9859 int outlen = 0;
9860 string[] outarray = new string[srclen*2+1];
9029 9861
9030 for (int i = 0; i < mlen; i++) 9862 int i, j;
9031 active[i] = true; 9863 string d;
9032 9864
9033 offset[mlen] = srclen; 9865 m_host.AddScriptLPS(1);
9034 9866
9035 while (beginning < srclen) 9867 /*
9868 * Convert separator and spacer lists to C# strings.
9869 * Also filter out null strings so we don't hang.
9870 */
9871 for (i = 0; i < seplen; i ++)
9036 { 9872 {
9873 d = separray[i].ToString();
9874 if (d.Length > 0)
9875 {
9876 delarray[dellen++] = d;
9877 }
9878 }
9879 seplen = dellen;
9037 9880
9038 best = mlen; // as bad as it gets 9881 for (i = 0; i < spclen; i ++)
9882 {
9883 d = spcarray[i].ToString();
9884 if (d.Length > 0)
9885 {
9886 delarray[dellen++] = d;
9887 }
9888 }
9039 9889
9040 // Scan for separators 9890 /*
9891 * Scan through source string from beginning to end.
9892 */
9893 for (i = 0;;)
9894 {
9041 9895
9042 for (j = 0; j < seplen; j++) 9896 /*
9897 * Find earliest delimeter in src starting at i (if any).
9898 */
9899 int earliestDel = -1;
9900 int earliestSrc = srclen;
9901 string earliestStr = null;
9902 for (j = 0; j < dellen; j ++)
9043 { 9903 {
9044 if (separray[j].ToString() == String.Empty) 9904 d = delarray[j];
9045 active[j] = false; 9905 if (d != null)
9046
9047 if (active[j])
9048 { 9906 {
9049 // scan all of the markers 9907 int index = src.IndexOf(d, i);
9050 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9908 if (index < 0)
9051 { 9909 {
9052 // not present at all 9910 delarray[j] = null; // delim nowhere in src, don't check it anymore
9053 active[j] = false;
9054 } 9911 }
9055 else 9912 else if (index < earliestSrc)
9056 { 9913 {
9057 // present and correct 9914 earliestSrc = index; // where delimeter starts in source string
9058 if (offset[j] < offset[best]) 9915 earliestDel = j; // where delimeter is in delarray[]
9059 { 9916 earliestStr = d; // the delimeter string from delarray[]
9060 // closest so far 9917 if (index == i) break; // can't do any better than found at beg of string
9061 best = j;
9062 if (offset[best] == beginning)
9063 break;
9064 }
9065 } 9918 }
9066 } 9919 }
9067 } 9920 }
9068 9921
9069 // Scan for spacers 9922 /*
9070 9923 * Output source string starting at i through start of earliest delimeter.
9071 if (offset[best] != beginning) 9924 */
9925 if (keepNulls || (earliestSrc > i))
9072 { 9926 {
9073 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9927 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9074 {
9075 if (spcarray[j-seplen].ToString() == String.Empty)
9076 active[j] = false;
9077
9078 if (active[j])
9079 {
9080 // scan all of the markers
9081 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9082 {
9083 // not present at all
9084 active[j] = false;
9085 }
9086 else
9087 {
9088 // present and correct
9089 if (offset[j] < offset[best])
9090 {
9091 // closest so far
9092 best = j;
9093 }
9094 }
9095 }
9096 }
9097 } 9928 }
9098 9929
9099 // This is the normal exit from the scanning loop 9930 /*
9931 * If no delimeter found at or after i, we're done scanning.
9932 */
9933 if (earliestDel < 0) break;
9100 9934
9101 if (best == mlen) 9935 /*
9936 * If delimeter was a spacer, output the spacer.
9937 */
9938 if (earliestDel >= seplen)
9102 { 9939 {
9103 // no markers were found on this pass 9940 outarray[outlen++] = earliestStr;
9104 // so we're pretty much done
9105 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9106 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9107 break;
9108 } 9941 }
9109 9942
9110 // Otherwise we just add the newly delimited token 9943 /*
9111 // and recalculate where the search should continue. 9944 * Look at rest of src string following delimeter.
9112 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9945 */
9113 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9946 i = earliestSrc + earliestStr.Length;
9114
9115 if (best < seplen)
9116 {
9117 beginning = offset[best] + (separray[best].ToString()).Length;
9118 }
9119 else
9120 {
9121 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9122 string str = spcarray[best - seplen].ToString();
9123 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9124 tokens.Add(new LSL_String(str));
9125 }
9126 } 9947 }
9127 9948
9128 // This an awkward an not very intuitive boundary case. If the 9949 /*
9129 // last substring is a tokenizer, then there is an implied trailing 9950 * Make up an exact-sized output array suitable for an LSL_List object.
9130 // null list entry. Hopefully the single comparison will not be too 9951 */
9131 // arduous. Alternatively the 'break' could be replced with a return 9952 object[] outlist = new object[outlen];
9132 // but that's shabby programming. 9953 for (i = 0; i < outlen; i ++)
9133
9134 if ((beginning == srclen) && (keepNulls))
9135 { 9954 {
9136 if (srclen != 0) 9955 outlist[i] = new LSL_String(outarray[i]);
9137 tokens.Add(new LSL_String(""));
9138 } 9956 }
9139 9957 return new LSL_List(outlist);
9140 return tokens;
9141 }
9142
9143 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9144 {
9145 m_host.AddScriptLPS(1);
9146 return this.ParseString(src, separators, spacers, false);
9147 }
9148
9149 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9150 {
9151 m_host.AddScriptLPS(1);
9152 return this.ParseString(src, separators, spacers, true);
9153 } 9958 }
9154 9959
9155 public LSL_Integer llGetObjectPermMask(int mask) 9960 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9244,6 +10049,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9244 case 4: 10049 case 4:
9245 return (int)item.NextPermissions; 10050 return (int)item.NextPermissions;
9246 } 10051 }
10052 m_host.TaskInventory.LockItemsForRead(false);
9247 10053
9248 return -1; 10054 return -1;
9249 } 10055 }
@@ -9447,31 +10253,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9447 UUID key = new UUID(); 10253 UUID key = new UUID();
9448 if (UUID.TryParse(id, out key)) 10254 if (UUID.TryParse(id, out key))
9449 { 10255 {
9450 try 10256 // return total object mass
9451 { 10257 SceneObjectPart part = World.GetSceneObjectPart(key);
9452 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10258 if (part != null)
9453 if (obj != null) 10259 return part.ParentGroup.GetMass();
9454 return (double)obj.GetMass(); 10260
9455 // the object is null so the key is for an avatar 10261 // the object is null so the key is for an avatar
9456 ScenePresence avatar = World.GetScenePresence(key); 10262 ScenePresence avatar = World.GetScenePresence(key);
9457 if (avatar != null) 10263 if (avatar != null)
9458 if (avatar.IsChildAgent)
9459 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9460 // child agents have a mass of 1.0
9461 return 1;
9462 else
9463 return (double)avatar.GetMass();
9464 }
9465 catch (KeyNotFoundException)
9466 { 10264 {
9467 return 0; // The Object/Agent not in the region so just return zero 10265 if (avatar.IsChildAgent)
10266 {
10267 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10268 // child agents have a mass of 1.0
10269 return 1;
10270 }
10271 else
10272 {
10273 return (double)avatar.GetMass();
10274 }
9468 } 10275 }
9469 } 10276 }
9470 return 0; 10277 return 0;
9471 } 10278 }
9472 10279
9473 /// <summary> 10280 /// <summary>
9474 /// illListReplaceList removes the sub-list defined by the inclusive indices 10281 /// llListReplaceList removes the sub-list defined by the inclusive indices
9475 /// start and end and inserts the src list in its place. The inclusive 10282 /// start and end and inserts the src list in its place. The inclusive
9476 /// nature of the indices means that at least one element must be deleted 10283 /// nature of the indices means that at least one element must be deleted
9477 /// if the indices are within the bounds of the existing list. I.e. 2,2 10284 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9528,16 +10335,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9528 // based upon end. Note that if end exceeds the upper 10335 // based upon end. Note that if end exceeds the upper
9529 // bound in this case, the entire destination list 10336 // bound in this case, the entire destination list
9530 // is removed. 10337 // is removed.
9531 else 10338 else if (start == 0)
9532 { 10339 {
9533 if (end + 1 < dest.Length) 10340 if (end + 1 < dest.Length)
9534 {
9535 return src + dest.GetSublist(end + 1, -1); 10341 return src + dest.GetSublist(end + 1, -1);
9536 }
9537 else 10342 else
9538 {
9539 return src; 10343 return src;
9540 } 10344 }
10345 else // Start < 0
10346 {
10347 if (end + 1 < dest.Length)
10348 return dest.GetSublist(end + 1, -1);
10349 else
10350 return new LSL_List();
9541 } 10351 }
9542 } 10352 }
9543 // Finally, if start > end, we strip away a prefix and 10353 // Finally, if start > end, we strip away a prefix and
@@ -9588,17 +10398,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9588 int width = 0; 10398 int width = 0;
9589 int height = 0; 10399 int height = 0;
9590 10400
9591 ParcelMediaCommandEnum? commandToSend = null; 10401 uint commandToSend = 0;
9592 float time = 0.0f; // default is from start 10402 float time = 0.0f; // default is from start
9593 10403
9594 ScenePresence presence = null; 10404 ScenePresence presence = null;
9595 10405
9596 for (int i = 0; i < commandList.Data.Length; i++) 10406 for (int i = 0; i < commandList.Data.Length; i++)
9597 { 10407 {
9598 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10408 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9599 switch (command) 10409 switch (command)
9600 { 10410 {
9601 case ParcelMediaCommandEnum.Agent: 10411 case (uint)ParcelMediaCommandEnum.Agent:
9602 // we send only to one agent 10412 // we send only to one agent
9603 if ((i + 1) < commandList.Length) 10413 if ((i + 1) < commandList.Length)
9604 { 10414 {
@@ -9615,25 +10425,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9615 } 10425 }
9616 break; 10426 break;
9617 10427
9618 case ParcelMediaCommandEnum.Loop: 10428 case (uint)ParcelMediaCommandEnum.Loop:
9619 loop = 1; 10429 loop = 1;
9620 commandToSend = command; 10430 commandToSend = command;
9621 update = true; //need to send the media update packet to set looping 10431 update = true; //need to send the media update packet to set looping
9622 break; 10432 break;
9623 10433
9624 case ParcelMediaCommandEnum.Play: 10434 case (uint)ParcelMediaCommandEnum.Play:
9625 loop = 0; 10435 loop = 0;
9626 commandToSend = command; 10436 commandToSend = command;
9627 update = true; //need to send the media update packet to make sure it doesn't loop 10437 update = true; //need to send the media update packet to make sure it doesn't loop
9628 break; 10438 break;
9629 10439
9630 case ParcelMediaCommandEnum.Pause: 10440 case (uint)ParcelMediaCommandEnum.Pause:
9631 case ParcelMediaCommandEnum.Stop: 10441 case (uint)ParcelMediaCommandEnum.Stop:
9632 case ParcelMediaCommandEnum.Unload: 10442 case (uint)ParcelMediaCommandEnum.Unload:
9633 commandToSend = command; 10443 commandToSend = command;
9634 break; 10444 break;
9635 10445
9636 case ParcelMediaCommandEnum.Url: 10446 case (uint)ParcelMediaCommandEnum.Url:
9637 if ((i + 1) < commandList.Length) 10447 if ((i + 1) < commandList.Length)
9638 { 10448 {
9639 if (commandList.Data[i + 1] is LSL_String) 10449 if (commandList.Data[i + 1] is LSL_String)
@@ -9646,7 +10456,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9646 } 10456 }
9647 break; 10457 break;
9648 10458
9649 case ParcelMediaCommandEnum.Texture: 10459 case (uint)ParcelMediaCommandEnum.Texture:
9650 if ((i + 1) < commandList.Length) 10460 if ((i + 1) < commandList.Length)
9651 { 10461 {
9652 if (commandList.Data[i + 1] is LSL_String) 10462 if (commandList.Data[i + 1] is LSL_String)
@@ -9659,7 +10469,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9659 } 10469 }
9660 break; 10470 break;
9661 10471
9662 case ParcelMediaCommandEnum.Time: 10472 case (uint)ParcelMediaCommandEnum.Time:
9663 if ((i + 1) < commandList.Length) 10473 if ((i + 1) < commandList.Length)
9664 { 10474 {
9665 if (commandList.Data[i + 1] is LSL_Float) 10475 if (commandList.Data[i + 1] is LSL_Float)
@@ -9671,7 +10481,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9671 } 10481 }
9672 break; 10482 break;
9673 10483
9674 case ParcelMediaCommandEnum.AutoAlign: 10484 case (uint)ParcelMediaCommandEnum.AutoAlign:
9675 if ((i + 1) < commandList.Length) 10485 if ((i + 1) < commandList.Length)
9676 { 10486 {
9677 if (commandList.Data[i + 1] is LSL_Integer) 10487 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9685,7 +10495,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9685 } 10495 }
9686 break; 10496 break;
9687 10497
9688 case ParcelMediaCommandEnum.Type: 10498 case (uint)ParcelMediaCommandEnum.Type:
9689 if ((i + 1) < commandList.Length) 10499 if ((i + 1) < commandList.Length)
9690 { 10500 {
9691 if (commandList.Data[i + 1] is LSL_String) 10501 if (commandList.Data[i + 1] is LSL_String)
@@ -9698,7 +10508,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9698 } 10508 }
9699 break; 10509 break;
9700 10510
9701 case ParcelMediaCommandEnum.Desc: 10511 case (uint)ParcelMediaCommandEnum.Desc:
9702 if ((i + 1) < commandList.Length) 10512 if ((i + 1) < commandList.Length)
9703 { 10513 {
9704 if (commandList.Data[i + 1] is LSL_String) 10514 if (commandList.Data[i + 1] is LSL_String)
@@ -9711,7 +10521,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9711 } 10521 }
9712 break; 10522 break;
9713 10523
9714 case ParcelMediaCommandEnum.Size: 10524 case (uint)ParcelMediaCommandEnum.Size:
9715 if ((i + 2) < commandList.Length) 10525 if ((i + 2) < commandList.Length)
9716 { 10526 {
9717 if (commandList.Data[i + 1] is LSL_Integer) 10527 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9781,7 +10591,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9781 } 10591 }
9782 } 10592 }
9783 10593
9784 if (commandToSend != null) 10594 if (commandToSend != 0)
9785 { 10595 {
9786 // the commandList contained a start/stop/... command, too 10596 // the commandList contained a start/stop/... command, too
9787 if (presence == null) 10597 if (presence == null)
@@ -9818,7 +10628,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9818 10628
9819 if (aList.Data[i] != null) 10629 if (aList.Data[i] != null)
9820 { 10630 {
9821 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10631 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9822 { 10632 {
9823 case ParcelMediaCommandEnum.Url: 10633 case ParcelMediaCommandEnum.Url:
9824 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10634 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9875,15 +10685,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9875 10685
9876 if (quick_pay_buttons.Data.Length < 4) 10686 if (quick_pay_buttons.Data.Length < 4)
9877 { 10687 {
9878 LSLError("List must have at least 4 elements"); 10688 int x;
9879 return; 10689 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10690 {
10691 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10692 }
9880 } 10693 }
9881 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10694 int[] nPrice = new int[5];
9882 10695 nPrice[0] = price;
9883 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10696 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9884 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10697 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9885 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10698 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9886 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10699 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10700 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9887 m_host.ParentGroup.HasGroupChanged = true; 10701 m_host.ParentGroup.HasGroupChanged = true;
9888 } 10702 }
9889 10703
@@ -9900,7 +10714,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9900 return Vector3.Zero; 10714 return Vector3.Zero;
9901 } 10715 }
9902 10716
9903 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10717// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10718 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9904 if (presence != null) 10719 if (presence != null)
9905 { 10720 {
9906 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 10721 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
@@ -9923,7 +10738,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9923 return Quaternion.Identity; 10738 return Quaternion.Identity;
9924 } 10739 }
9925 10740
9926 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10741// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10742 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9927 if (presence != null) 10743 if (presence != null)
9928 { 10744 {
9929 return new LSL_Rotation(presence.CameraRotation); 10745 return new LSL_Rotation(presence.CameraRotation);
@@ -9983,14 +10799,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9983 { 10799 {
9984 m_host.AddScriptLPS(1); 10800 m_host.AddScriptLPS(1);
9985 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10801 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9986 if (detectedParams == null) return; // only works on the first detected avatar 10802 if (detectedParams == null)
9987 10803 {
10804 if (m_host.ParentGroup.IsAttachment == true)
10805 {
10806 detectedParams = new DetectParams();
10807 detectedParams.Key = m_host.OwnerID;
10808 }
10809 else
10810 {
10811 return;
10812 }
10813 }
10814
9988 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10815 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9989 if (avatar != null) 10816 if (avatar != null)
9990 { 10817 {
9991 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10818 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9992 simname, pos, lookAt); 10819 simname, pos, lookAt);
9993 } 10820 }
10821
9994 ScriptSleep(1000); 10822 ScriptSleep(1000);
9995 } 10823 }
9996 10824
@@ -10114,12 +10942,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10114 10942
10115 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10943 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10116 object[] data = rules.Data; 10944 object[] data = rules.Data;
10117 for (int i = 0; i < data.Length; ++i) { 10945 for (int i = 0; i < data.Length; ++i)
10946 {
10118 int type = Convert.ToInt32(data[i++].ToString()); 10947 int type = Convert.ToInt32(data[i++].ToString());
10119 if (i >= data.Length) break; // odd number of entries => ignore the last 10948 if (i >= data.Length) break; // odd number of entries => ignore the last
10120 10949
10121 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10950 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10122 switch (type) { 10951 switch (type)
10952 {
10123 case ScriptBaseClass.CAMERA_FOCUS: 10953 case ScriptBaseClass.CAMERA_FOCUS:
10124 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10954 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10125 case ScriptBaseClass.CAMERA_POSITION: 10955 case ScriptBaseClass.CAMERA_POSITION:
@@ -10224,19 +11054,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10224 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11054 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10225 { 11055 {
10226 m_host.AddScriptLPS(1); 11056 m_host.AddScriptLPS(1);
10227 string ret = String.Empty; 11057
10228 string src1 = llBase64ToString(str1); 11058 if (str1 == String.Empty)
10229 string src2 = llBase64ToString(str2); 11059 return String.Empty;
10230 int c = 0; 11060 if (str2 == String.Empty)
10231 for (int i = 0; i < src1.Length; i++) 11061 return str1;
11062
11063 int len = str2.Length;
11064 if ((len % 4) != 0) // LL is EVIL!!!!
10232 { 11065 {
10233 ret += (char) (src1[i] ^ src2[c]); 11066 while (str2.EndsWith("="))
11067 str2 = str2.Substring(0, str2.Length - 1);
11068
11069 len = str2.Length;
11070 int mod = len % 4;
10234 11071
10235 c++; 11072 if (mod == 1)
10236 if (c >= src2.Length) 11073 str2 = str2.Substring(0, str2.Length - 1);
10237 c = 0; 11074 else if (mod == 2)
11075 str2 += "==";
11076 else if (mod == 3)
11077 str2 += "=";
11078 }
11079
11080 byte[] data1;
11081 byte[] data2;
11082 try
11083 {
11084 data1 = Convert.FromBase64String(str1);
11085 data2 = Convert.FromBase64String(str2);
11086 }
11087 catch (Exception)
11088 {
11089 return new LSL_String(String.Empty);
11090 }
11091
11092 byte[] d2 = new Byte[data1.Length];
11093 int pos = 0;
11094
11095 if (data1.Length <= data2.Length)
11096 {
11097 Array.Copy(data2, 0, d2, 0, data1.Length);
10238 } 11098 }
10239 return llStringToBase64(ret); 11099 else
11100 {
11101 while (pos < data1.Length)
11102 {
11103 len = data1.Length - pos;
11104 if (len > data2.Length)
11105 len = data2.Length;
11106
11107 Array.Copy(data2, 0, d2, pos, len);
11108 pos += len;
11109 }
11110 }
11111
11112 for (pos = 0 ; pos < data1.Length ; pos++ )
11113 data1[pos] ^= d2[pos];
11114
11115 return Convert.ToBase64String(data1);
10240 } 11116 }
10241 11117
10242 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11118 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10289,16 +11165,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10289 if (userAgent != null) 11165 if (userAgent != null)
10290 httpHeaders["User-Agent"] = userAgent; 11166 httpHeaders["User-Agent"] = userAgent;
10291 11167
11168 // See if the URL contains any header hacks
11169 string[] urlParts = url.Split(new char[] {'\n'});
11170 if (urlParts.Length > 1)
11171 {
11172 // Iterate the passed headers and parse them
11173 for (int i = 1 ; i < urlParts.Length ; i++ )
11174 {
11175 // The rest of those would be added to the body in SL.
11176 // Let's not do that.
11177 if (urlParts[i] == String.Empty)
11178 break;
11179
11180 // See if this could be a valid header
11181 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11182 if (headerParts.Length != 2)
11183 continue;
11184
11185 string headerName = headerParts[0].Trim();
11186 string headerValue = headerParts[1].Trim();
11187
11188 // Filter out headers that could be used to abuse
11189 // another system or cloak the request
11190 if (headerName.ToLower() == "x-secondlife-shard" ||
11191 headerName.ToLower() == "x-secondlife-object-name" ||
11192 headerName.ToLower() == "x-secondlife-object-key" ||
11193 headerName.ToLower() == "x-secondlife-region" ||
11194 headerName.ToLower() == "x-secondlife-local-position" ||
11195 headerName.ToLower() == "x-secondlife-local-velocity" ||
11196 headerName.ToLower() == "x-secondlife-local-rotation" ||
11197 headerName.ToLower() == "x-secondlife-owner-name" ||
11198 headerName.ToLower() == "x-secondlife-owner-key" ||
11199 headerName.ToLower() == "connection" ||
11200 headerName.ToLower() == "content-length" ||
11201 headerName.ToLower() == "from" ||
11202 headerName.ToLower() == "host" ||
11203 headerName.ToLower() == "proxy-authorization" ||
11204 headerName.ToLower() == "referer" ||
11205 headerName.ToLower() == "trailer" ||
11206 headerName.ToLower() == "transfer-encoding" ||
11207 headerName.ToLower() == "via" ||
11208 headerName.ToLower() == "authorization")
11209 continue;
11210
11211 httpHeaders[headerName] = headerValue;
11212 }
11213
11214 // Finally, strip any protocol specifier from the URL
11215 url = urlParts[0].Trim();
11216 int idx = url.IndexOf(" HTTP/");
11217 if (idx != -1)
11218 url = url.Substring(0, idx);
11219 }
11220
10292 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11221 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10293 Regex r = new Regex(authregex); 11222 Regex r = new Regex(authregex);
10294 int[] gnums = r.GetGroupNumbers(); 11223 int[] gnums = r.GetGroupNumbers();
10295 Match m = r.Match(url); 11224 Match m = r.Match(url);
10296 if (m.Success) { 11225 if (m.Success)
10297 for (int i = 1; i < gnums.Length; i++) { 11226 {
11227 for (int i = 1; i < gnums.Length; i++)
11228 {
10298 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11229 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10299 //CaptureCollection cc = g.Captures; 11230 //CaptureCollection cc = g.Captures;
10300 } 11231 }
10301 if (m.Groups.Count == 5) { 11232 if (m.Groups.Count == 5)
11233 {
10302 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11234 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10303 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11235 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10304 } 11236 }
@@ -10501,6 +11433,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10501 11433
10502 LSL_List ret = new LSL_List(); 11434 LSL_List ret = new LSL_List();
10503 UUID key = new UUID(); 11435 UUID key = new UUID();
11436
11437
10504 if (UUID.TryParse(id, out key)) 11438 if (UUID.TryParse(id, out key))
10505 { 11439 {
10506 ScenePresence av = World.GetScenePresence(key); 11440 ScenePresence av = World.GetScenePresence(key);
@@ -10518,13 +11452,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10518 ret.Add(new LSL_String("")); 11452 ret.Add(new LSL_String(""));
10519 break; 11453 break;
10520 case ScriptBaseClass.OBJECT_POS: 11454 case ScriptBaseClass.OBJECT_POS:
10521 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11455 Vector3 avpos;
11456
11457 if (av.ParentID != 0 && av.ParentPart != null)
11458 {
11459 avpos = av.OffsetPosition;
11460
11461 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11462 avpos -= sitOffset;
11463
11464 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11465 }
11466 else
11467 avpos = av.AbsolutePosition;
11468
11469 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10522 break; 11470 break;
10523 case ScriptBaseClass.OBJECT_ROT: 11471 case ScriptBaseClass.OBJECT_ROT:
10524 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 11472 Quaternion avrot = av.Rotation;
11473 if (av.ParentID != 0 && av.ParentPart != null)
11474 {
11475 avrot = av.ParentPart.GetWorldRotation() * avrot;
11476 }
11477 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10525 break; 11478 break;
10526 case ScriptBaseClass.OBJECT_VELOCITY: 11479 case ScriptBaseClass.OBJECT_VELOCITY:
10527 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11480 Vector3 avvel = av.Velocity;
11481 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10528 break; 11482 break;
10529 case ScriptBaseClass.OBJECT_OWNER: 11483 case ScriptBaseClass.OBJECT_OWNER:
10530 ret.Add(new LSL_String(id)); 11484 ret.Add(new LSL_String(id));
@@ -10609,11 +11563,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10609 case ScriptBaseClass.OBJECT_NAME: 11563 case ScriptBaseClass.OBJECT_NAME:
10610 ret.Add(new LSL_String(obj.Name)); 11564 ret.Add(new LSL_String(obj.Name));
10611 break; 11565 break;
10612 case ScriptBaseClass.OBJECT_DESC: 11566 case ScriptBaseClass.OBJECT_DESC:
10613 ret.Add(new LSL_String(obj.Description)); 11567 ret.Add(new LSL_String(obj.Description));
10614 break; 11568 break;
10615 case ScriptBaseClass.OBJECT_POS: 11569 case ScriptBaseClass.OBJECT_POS:
10616 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11570 Vector3 opos = obj.AbsolutePosition;
11571 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10617 break; 11572 break;
10618 case ScriptBaseClass.OBJECT_ROT: 11573 case ScriptBaseClass.OBJECT_ROT:
10619 { 11574 {
@@ -10663,9 +11618,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10663 // The value returned in SL for normal prims is prim count 11618 // The value returned in SL for normal prims is prim count
10664 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11619 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10665 break; 11620 break;
10666 // The following 3 costs I have intentionaly coded to return zero. They are part of 11621
10667 // "Land Impact" calculations. These calculations are probably not applicable 11622 // costs below may need to be diferent for root parts, need to check
10668 // to OpenSim and are not yet complete in SL
10669 case ScriptBaseClass.OBJECT_SERVER_COST: 11623 case ScriptBaseClass.OBJECT_SERVER_COST:
10670 // The linden calculation is here 11624 // The linden calculation is here
10671 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11625 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10673,16 +11627,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10673 ret.Add(new LSL_Float(0)); 11627 ret.Add(new LSL_Float(0));
10674 break; 11628 break;
10675 case ScriptBaseClass.OBJECT_STREAMING_COST: 11629 case ScriptBaseClass.OBJECT_STREAMING_COST:
10676 // The linden calculation is here 11630 // The value returned in SL for normal prims is prim count * 0.06
10677 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11631 ret.Add(new LSL_Float(obj.StreamingCost));
10678 // The value returned in SL for normal prims looks like the prim count * 0.06
10679 ret.Add(new LSL_Float(0));
10680 break; 11632 break;
10681 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11633 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10682 // The linden calculation is here 11634 // The value returned in SL for normal prims is prim count
10683 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11635 ret.Add(new LSL_Float(obj.PhysicsCost));
10684 // The value returned in SL for normal prims looks like the prim count
10685 ret.Add(new LSL_Float(0));
10686 break; 11636 break;
10687 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11637 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
10688 ret.Add(new LSL_Float(0)); 11638 ret.Add(new LSL_Float(0));
@@ -10941,15 +11891,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10941 return result; 11891 return result;
10942 } 11892 }
10943 11893
10944 public void print(string str) 11894 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10945 { 11895 {
10946 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11896 List<SceneObjectPart> parts = GetLinkParts(link);
10947 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11897 if (parts.Count < 1)
10948 if (ossl != null) 11898 return 0;
10949 { 11899
10950 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11900 return GetNumberOfSides(parts[0]);
10951 m_log.Info("LSL print():" + str);
10952 }
10953 } 11901 }
10954 11902
10955 private string Name2Username(string name) 11903 private string Name2Username(string name)
@@ -10994,7 +11942,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10994 11942
10995 return rq.ToString(); 11943 return rq.ToString();
10996 } 11944 }
10997 11945/*
11946 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11947 {
11948 m_SayShoutCount = 0;
11949 }
11950*/
10998 private struct Tri 11951 private struct Tri
10999 { 11952 {
11000 public Vector3 p1; 11953 public Vector3 p1;
@@ -11143,9 +12096,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11143 12096
11144 ContactResult result = new ContactResult (); 12097 ContactResult result = new ContactResult ();
11145 result.ConsumerID = group.LocalId; 12098 result.ConsumerID = group.LocalId;
11146 result.Depth = intersection.distance; 12099// result.Depth = intersection.distance;
11147 result.Normal = intersection.normal; 12100 result.Normal = intersection.normal;
11148 result.Pos = intersection.ipoint; 12101 result.Pos = intersection.ipoint;
12102 result.Depth = Vector3.Mag(rayStart - result.Pos);
11149 12103
11150 contacts.Add(result); 12104 contacts.Add(result);
11151 }); 12105 });
@@ -11278,6 +12232,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11278 12232
11279 return contacts[0]; 12233 return contacts[0];
11280 } 12234 }
12235/*
12236 // not done:
12237 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12238 {
12239 ContactResult[] contacts = null;
12240 World.ForEachSOG(delegate(SceneObjectGroup group)
12241 {
12242 if (m_host.ParentGroup == group)
12243 return;
12244
12245 if (group.IsAttachment)
12246 return;
12247
12248 if(group.RootPart.PhysActor != null)
12249 return;
12250
12251 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12252 });
12253 return contacts;
12254 }
12255*/
11281 12256
11282 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12257 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11283 { 12258 {
@@ -11401,18 +12376,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11401 } 12376 }
11402 } 12377 }
11403 12378
12379 // Double check this
11404 if (checkTerrain) 12380 if (checkTerrain)
11405 { 12381 {
11406 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12382 bool skipGroundCheck = false;
11407 if (groundContact != null) 12383
11408 results.Add((ContactResult)groundContact); 12384 foreach (ContactResult c in results)
12385 {
12386 if (c.ConsumerID == 0) // Physics gave us a ground collision
12387 skipGroundCheck = true;
12388 }
12389
12390 if (!skipGroundCheck)
12391 {
12392 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12393 if (groundContact != null)
12394 results.Add((ContactResult)groundContact);
12395 }
11409 } 12396 }
11410 12397
11411 results.Sort(delegate(ContactResult a, ContactResult b) 12398 results.Sort(delegate(ContactResult a, ContactResult b)
11412 { 12399 {
11413 return a.Depth.CompareTo(b.Depth); 12400 return a.Depth.CompareTo(b.Depth);
11414 }); 12401 });
11415 12402
11416 int values = 0; 12403 int values = 0;
11417 SceneObjectGroup thisgrp = m_host.ParentGroup; 12404 SceneObjectGroup thisgrp = m_host.ParentGroup;
11418 12405
@@ -11505,7 +12492,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11505 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12492 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11506 if (!isAccount) return 0; 12493 if (!isAccount) return 0;
11507 if (estate.HasAccess(id)) return 1; 12494 if (estate.HasAccess(id)) return 1;
11508 if (estate.IsBanned(id)) 12495 if (estate.IsBanned(id, World.GetUserFlags(id)))
11509 estate.RemoveBan(id); 12496 estate.RemoveBan(id);
11510 estate.AddEstateUser(id); 12497 estate.AddEstateUser(id);
11511 break; 12498 break;
@@ -11524,14 +12511,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11524 break; 12511 break;
11525 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12512 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11526 if (!isAccount) return 0; 12513 if (!isAccount) return 0;
11527 if (estate.IsBanned(id)) return 1; 12514 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11528 EstateBan ban = new EstateBan(); 12515 EstateBan ban = new EstateBan();
11529 ban.EstateID = estate.EstateID; 12516 ban.EstateID = estate.EstateID;
11530 ban.BannedUserID = id; 12517 ban.BannedUserID = id;
11531 estate.AddBan(ban); 12518 estate.AddBan(ban);
11532 break; 12519 break;
11533 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12520 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11534 if (!isAccount || !estate.IsBanned(id)) return 0; 12521 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11535 estate.RemoveBan(id); 12522 estate.RemoveBan(id);
11536 break; 12523 break;
11537 default: return 0; 12524 default: return 0;
@@ -11560,7 +12547,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11560 return 16384; 12547 return 16384;
11561 } 12548 }
11562 12549
11563 public LSL_Integer llGetUsedMemory() 12550 public virtual LSL_Integer llGetUsedMemory()
11564 { 12551 {
11565 m_host.AddScriptLPS(1); 12552 m_host.AddScriptLPS(1);
11566 // The value returned for LSO scripts in SL 12553 // The value returned for LSO scripts in SL
@@ -11588,19 +12575,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11588 public void llSetSoundQueueing(int queue) 12575 public void llSetSoundQueueing(int queue)
11589 { 12576 {
11590 m_host.AddScriptLPS(1); 12577 m_host.AddScriptLPS(1);
11591 NotImplemented("llSetSoundQueueing");
11592 } 12578 }
11593 12579
11594 public void llCollisionSprite(string impact_sprite) 12580 public void llCollisionSprite(string impact_sprite)
11595 { 12581 {
11596 m_host.AddScriptLPS(1); 12582 m_host.AddScriptLPS(1);
11597 NotImplemented("llCollisionSprite"); 12583 // Viewer 2.0 broke this and it's likely LL has no intention
12584 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11598 } 12585 }
11599 12586
11600 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12587 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11601 { 12588 {
11602 m_host.AddScriptLPS(1); 12589 m_host.AddScriptLPS(1);
11603 NotImplemented("llGodLikeRezObject"); 12590
12591 if (!World.Permissions.IsGod(m_host.OwnerID))
12592 NotImplemented("llGodLikeRezObject");
12593
12594 AssetBase rezAsset = World.AssetService.Get(inventory);
12595 if (rezAsset == null)
12596 {
12597 llSay(0, "Asset not found");
12598 return;
12599 }
12600
12601 SceneObjectGroup group = null;
12602
12603 try
12604 {
12605 string xmlData = Utils.BytesToString(rezAsset.Data);
12606 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12607 }
12608 catch
12609 {
12610 llSay(0, "Asset not found");
12611 return;
12612 }
12613
12614 if (group == null)
12615 {
12616 llSay(0, "Asset not found");
12617 return;
12618 }
12619
12620 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12621 group.RootPart.AttachOffset = group.AbsolutePosition;
12622
12623 group.ResetIDs();
12624
12625 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12626 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12627 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12628 group.ScheduleGroupForFullUpdate();
12629
12630 // objects rezzed with this method are die_at_edge by default.
12631 group.RootPart.SetDieAtEdge(true);
12632
12633 group.ResumeScripts();
12634
12635 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12636 "object_rez", new Object[] {
12637 new LSL_String(
12638 group.RootPart.UUID.ToString()) },
12639 new DetectParams[0]));
11604 } 12640 }
11605 12641
11606 public LSL_String llTransferLindenDollars(string destination, int amount) 12642 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -11652,7 +12688,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11652 } 12688 }
11653 12689
11654 bool result = money.ObjectGiveMoney( 12690 bool result = money.ObjectGiveMoney(
11655 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12691 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn);
11656 12692
11657 if (result) 12693 if (result)
11658 { 12694 {
@@ -11677,6 +12713,598 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11677 } 12713 }
11678 12714
11679 #endregion 12715 #endregion
12716
12717 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12718 {
12719 SceneObjectGroup group = m_host.ParentGroup;
12720
12721 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12722 return;
12723 if (group.IsAttachment)
12724 return;
12725
12726 if (frames.Data.Length > 0) // We are getting a new motion
12727 {
12728 if (group.RootPart.KeyframeMotion != null)
12729 group.RootPart.KeyframeMotion.Delete();
12730 group.RootPart.KeyframeMotion = null;
12731
12732 int idx = 0;
12733
12734 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12735 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12736
12737 while (idx < options.Data.Length)
12738 {
12739 int option = (int)options.GetLSLIntegerItem(idx++);
12740 int remain = options.Data.Length - idx;
12741
12742 switch (option)
12743 {
12744 case ScriptBaseClass.KFM_MODE:
12745 if (remain < 1)
12746 break;
12747 int modeval = (int)options.GetLSLIntegerItem(idx++);
12748 switch(modeval)
12749 {
12750 case ScriptBaseClass.KFM_FORWARD:
12751 mode = KeyframeMotion.PlayMode.Forward;
12752 break;
12753 case ScriptBaseClass.KFM_REVERSE:
12754 mode = KeyframeMotion.PlayMode.Reverse;
12755 break;
12756 case ScriptBaseClass.KFM_LOOP:
12757 mode = KeyframeMotion.PlayMode.Loop;
12758 break;
12759 case ScriptBaseClass.KFM_PING_PONG:
12760 mode = KeyframeMotion.PlayMode.PingPong;
12761 break;
12762 }
12763 break;
12764 case ScriptBaseClass.KFM_DATA:
12765 if (remain < 1)
12766 break;
12767 int dataval = (int)options.GetLSLIntegerItem(idx++);
12768 data = (KeyframeMotion.DataFormat)dataval;
12769 break;
12770 }
12771 }
12772
12773 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12774
12775 idx = 0;
12776
12777 int elemLength = 2;
12778 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12779 elemLength = 3;
12780
12781 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12782 while (idx < frames.Data.Length)
12783 {
12784 int remain = frames.Data.Length - idx;
12785
12786 if (remain < elemLength)
12787 break;
12788
12789 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12790 frame.Position = null;
12791 frame.Rotation = null;
12792
12793 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12794 {
12795 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12796 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12797 }
12798 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12799 {
12800 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12801 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12802 q.Normalize();
12803 frame.Rotation = q;
12804 }
12805
12806 float tempf = (float)frames.GetLSLFloatItem(idx++);
12807 frame.TimeMS = (int)(tempf * 1000.0f);
12808
12809 keyframes.Add(frame);
12810 }
12811
12812 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12813 group.RootPart.KeyframeMotion.Start();
12814 }
12815 else
12816 {
12817 if (group.RootPart.KeyframeMotion == null)
12818 return;
12819
12820 if (options.Data.Length == 0)
12821 {
12822 group.RootPart.KeyframeMotion.Stop();
12823 return;
12824 }
12825
12826 int code = (int)options.GetLSLIntegerItem(0);
12827
12828 int idx = 0;
12829
12830 while (idx < options.Data.Length)
12831 {
12832 int option = (int)options.GetLSLIntegerItem(idx++);
12833 int remain = options.Data.Length - idx;
12834
12835 switch (option)
12836 {
12837 case ScriptBaseClass.KFM_COMMAND:
12838 int cmd = (int)options.GetLSLIntegerItem(idx++);
12839 switch (cmd)
12840 {
12841 case ScriptBaseClass.KFM_CMD_PLAY:
12842 group.RootPart.KeyframeMotion.Start();
12843 break;
12844 case ScriptBaseClass.KFM_CMD_STOP:
12845 group.RootPart.KeyframeMotion.Stop();
12846 break;
12847 case ScriptBaseClass.KFM_CMD_PAUSE:
12848 group.RootPart.KeyframeMotion.Pause();
12849 break;
12850 }
12851 break;
12852 }
12853 }
12854 }
12855 }
12856
12857 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12858 {
12859 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12860
12861 int idx = 0;
12862 int idxStart = 0;
12863
12864 bool positionChanged = false;
12865 Vector3 finalPos = Vector3.Zero;
12866
12867 try
12868 {
12869 while (idx < rules.Length)
12870 {
12871 ++rulesParsed;
12872 int code = rules.GetLSLIntegerItem(idx++);
12873
12874 int remain = rules.Length - idx;
12875 idxStart = idx;
12876
12877 switch (code)
12878 {
12879 case (int)ScriptBaseClass.PRIM_POSITION:
12880 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12881 {
12882 if (remain < 1)
12883 return null;
12884
12885 LSL_Vector v;
12886 v = rules.GetVector3Item(idx++);
12887
12888 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12889 if (part == null)
12890 break;
12891
12892 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12893 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12894 if (part.LinkNum > 1)
12895 {
12896 localRot = GetPartLocalRot(part);
12897 localPos = GetPartLocalPos(part);
12898 }
12899
12900 v -= localPos;
12901 v /= localRot;
12902
12903 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12904
12905 v = v + 2 * sitOffset;
12906
12907 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12908 av.SendAvatarDataToAllAgents();
12909
12910 }
12911 break;
12912
12913 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12914 case (int)ScriptBaseClass.PRIM_ROTATION:
12915 {
12916 if (remain < 1)
12917 return null;
12918
12919 LSL_Rotation r;
12920 r = rules.GetQuaternionItem(idx++);
12921
12922 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12923 if (part == null)
12924 break;
12925
12926 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12927 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12928
12929 if (part.LinkNum > 1)
12930 localRot = GetPartLocalRot(part);
12931
12932 r = r * llGetRootRotation() / localRot;
12933 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12934 av.SendAvatarDataToAllAgents();
12935 }
12936 break;
12937
12938 // parse rest doing nothing but number of parameters error check
12939 case (int)ScriptBaseClass.PRIM_SIZE:
12940 case (int)ScriptBaseClass.PRIM_MATERIAL:
12941 case (int)ScriptBaseClass.PRIM_PHANTOM:
12942 case (int)ScriptBaseClass.PRIM_PHYSICS:
12943 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12944 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12945 case (int)ScriptBaseClass.PRIM_NAME:
12946 case (int)ScriptBaseClass.PRIM_DESC:
12947 if (remain < 1)
12948 return null;
12949 idx++;
12950 break;
12951
12952 case (int)ScriptBaseClass.PRIM_GLOW:
12953 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12954 case (int)ScriptBaseClass.PRIM_TEXGEN:
12955 if (remain < 2)
12956 return null;
12957 idx += 2;
12958 break;
12959
12960 case (int)ScriptBaseClass.PRIM_TYPE:
12961 if (remain < 3)
12962 return null;
12963 code = (int)rules.GetLSLIntegerItem(idx++);
12964 remain = rules.Length - idx;
12965 switch (code)
12966 {
12967 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12968 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12969 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12970 if (remain < 6)
12971 return null;
12972 idx += 6;
12973 break;
12974
12975 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12976 if (remain < 5)
12977 return null;
12978 idx += 5;
12979 break;
12980
12981 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12982 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12983 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12984 if (remain < 11)
12985 return null;
12986 idx += 11;
12987 break;
12988
12989 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12990 if (remain < 2)
12991 return null;
12992 idx += 2;
12993 break;
12994 }
12995 break;
12996
12997 case (int)ScriptBaseClass.PRIM_COLOR:
12998 case (int)ScriptBaseClass.PRIM_TEXT:
12999 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13000 case (int)ScriptBaseClass.PRIM_OMEGA:
13001 if (remain < 3)
13002 return null;
13003 idx += 3;
13004 break;
13005
13006 case (int)ScriptBaseClass.PRIM_TEXTURE:
13007 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13008 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
13009 if (remain < 5)
13010 return null;
13011 idx += 5;
13012 break;
13013
13014 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13015 if (remain < 7)
13016 return null;
13017
13018 idx += 7;
13019 break;
13020
13021 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13022 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13023 return null;
13024
13025 return rules.GetSublist(idx, -1);
13026 }
13027 }
13028 }
13029 catch (InvalidCastException e)
13030 {
13031 ShoutError(string.Format(
13032 "{0} error running rule #{1}: arg #{2} ",
13033 originFunc, rulesParsed, idx - idxStart) + e.Message);
13034 }
13035 finally
13036 {
13037 if (positionChanged)
13038 {
13039 av.OffsetPosition = finalPos;
13040// av.SendAvatarDataToAllAgents();
13041 av.SendTerseUpdateToAllClients();
13042 positionChanged = false;
13043 }
13044 }
13045 return null;
13046 }
13047
13048 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13049 {
13050 // avatars case
13051 // replies as SL wiki
13052
13053// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13054 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13055
13056 int idx = 0;
13057 while (idx < rules.Length)
13058 {
13059 int code = (int)rules.GetLSLIntegerItem(idx++);
13060 int remain = rules.Length - idx;
13061
13062 switch (code)
13063 {
13064 case (int)ScriptBaseClass.PRIM_MATERIAL:
13065 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13066 break;
13067
13068 case (int)ScriptBaseClass.PRIM_PHYSICS:
13069 res.Add(new LSL_Integer(0));
13070 break;
13071
13072 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13073 res.Add(new LSL_Integer(0));
13074 break;
13075
13076 case (int)ScriptBaseClass.PRIM_PHANTOM:
13077 res.Add(new LSL_Integer(0));
13078 break;
13079
13080 case (int)ScriptBaseClass.PRIM_POSITION:
13081
13082 Vector3 pos = avatar.OffsetPosition;
13083
13084 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13085 pos -= sitOffset;
13086
13087 if( sitPart != null)
13088 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13089
13090 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13091 break;
13092
13093 case (int)ScriptBaseClass.PRIM_SIZE:
13094 // as in llGetAgentSize above
13095// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13096 Vector3 s = avatar.Appearance.AvatarSize;
13097 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13098
13099 break;
13100
13101 case (int)ScriptBaseClass.PRIM_ROTATION:
13102 Quaternion rot = avatar.Rotation;
13103 if (sitPart != null)
13104 {
13105 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13106 }
13107
13108 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13109 break;
13110
13111 case (int)ScriptBaseClass.PRIM_TYPE:
13112 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13113 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13114 res.Add(new LSL_Vector(0f,1.0f,0f));
13115 res.Add(new LSL_Float(0.0f));
13116 res.Add(new LSL_Vector(0, 0, 0));
13117 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13118 res.Add(new LSL_Vector(0, 0, 0));
13119 break;
13120
13121 case (int)ScriptBaseClass.PRIM_TEXTURE:
13122 if (remain < 1)
13123 return null;
13124
13125 int face = (int)rules.GetLSLIntegerItem(idx++);
13126 if (face == ScriptBaseClass.ALL_SIDES)
13127 {
13128 for (face = 0; face < 21; face++)
13129 {
13130 res.Add(new LSL_String(""));
13131 res.Add(new LSL_Vector(0,0,0));
13132 res.Add(new LSL_Vector(0,0,0));
13133 res.Add(new LSL_Float(0.0));
13134 }
13135 }
13136 else
13137 {
13138 if (face >= 0 && face < 21)
13139 {
13140 res.Add(new LSL_String(""));
13141 res.Add(new LSL_Vector(0,0,0));
13142 res.Add(new LSL_Vector(0,0,0));
13143 res.Add(new LSL_Float(0.0));
13144 }
13145 }
13146 break;
13147
13148 case (int)ScriptBaseClass.PRIM_COLOR:
13149 if (remain < 1)
13150 return null;
13151
13152 face = (int)rules.GetLSLIntegerItem(idx++);
13153
13154 if (face == ScriptBaseClass.ALL_SIDES)
13155 {
13156 for (face = 0; face < 21; face++)
13157 {
13158 res.Add(new LSL_Vector(0,0,0));
13159 res.Add(new LSL_Float(0));
13160 }
13161 }
13162 else
13163 {
13164 res.Add(new LSL_Vector(0,0,0));
13165 res.Add(new LSL_Float(0));
13166 }
13167 break;
13168
13169 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13170 if (remain < 1)
13171 return null;
13172 face = (int)rules.GetLSLIntegerItem(idx++);
13173
13174 if (face == ScriptBaseClass.ALL_SIDES)
13175 {
13176 for (face = 0; face < 21; face++)
13177 {
13178 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13179 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13180 }
13181 }
13182 else
13183 {
13184 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13185 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13186 }
13187 break;
13188
13189 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13190 if (remain < 1)
13191 return null;
13192 face = (int)rules.GetLSLIntegerItem(idx++);
13193
13194 if (face == ScriptBaseClass.ALL_SIDES)
13195 {
13196 for (face = 0; face < 21; face++)
13197 {
13198 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13199 }
13200 }
13201 else
13202 {
13203 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13204 }
13205 break;
13206
13207 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13208 res.Add(new LSL_Integer(0));
13209 res.Add(new LSL_Integer(0));// softness
13210 res.Add(new LSL_Float(0.0f)); // gravity
13211 res.Add(new LSL_Float(0.0f)); // friction
13212 res.Add(new LSL_Float(0.0f)); // wind
13213 res.Add(new LSL_Float(0.0f)); // tension
13214 res.Add(new LSL_Vector(0f,0f,0f));
13215 break;
13216
13217 case (int)ScriptBaseClass.PRIM_TEXGEN:
13218 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13219 if (remain < 1)
13220 return null;
13221 face = (int)rules.GetLSLIntegerItem(idx++);
13222
13223 if (face == ScriptBaseClass.ALL_SIDES)
13224 {
13225 for (face = 0; face < 21; face++)
13226 {
13227 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13228 }
13229 }
13230 else
13231 {
13232 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13233 }
13234 break;
13235
13236 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13237 res.Add(new LSL_Integer(0));
13238 res.Add(new LSL_Vector(0f,0f,0f));
13239 res.Add(new LSL_Float(0f)); // intensity
13240 res.Add(new LSL_Float(0f)); // radius
13241 res.Add(new LSL_Float(0f)); // falloff
13242 break;
13243
13244 case (int)ScriptBaseClass.PRIM_GLOW:
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_Float(0f));
13254 }
13255 }
13256 else
13257 {
13258 res.Add(new LSL_Float(0f));
13259 }
13260 break;
13261
13262 case (int)ScriptBaseClass.PRIM_TEXT:
13263 res.Add(new LSL_String(""));
13264 res.Add(new LSL_Vector(0f,0f,0f));
13265 res.Add(new LSL_Float(1.0f));
13266 break;
13267
13268 case (int)ScriptBaseClass.PRIM_NAME:
13269 res.Add(new LSL_String(avatar.Name));
13270 break;
13271
13272 case (int)ScriptBaseClass.PRIM_DESC:
13273 res.Add(new LSL_String(""));
13274 break;
13275
13276 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13277 Quaternion lrot = avatar.Rotation;
13278
13279 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13280 {
13281 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13282 }
13283 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13284 break;
13285
13286 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13287 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13288 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13289 lpos -= lsitOffset;
13290
13291 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13292 {
13293 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13294 }
13295 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13296 break;
13297
13298 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13299 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13300 return null;
13301
13302 return rules.GetSublist(idx, -1);
13303 }
13304 }
13305
13306 return null;
13307 }
11680 } 13308 }
11681 13309
11682 public class NotecardCache 13310 public class NotecardCache
@@ -11790,4 +13418,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11790 } 13418 }
11791 } 13419 }
11792 } 13420 }
11793} \ No newline at end of file 13421}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 21bae27..bd776b6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -136,7 +136,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
137 137
138 Type returntype = m_comms.LookupReturnType(fname); 138 Type returntype = m_comms.LookupReturnType(fname);
139 if (returntype != typeof(string)) 139 if (returntype != typeof(void))
140 MODError(String.Format("return type mismatch for {0}",fname)); 140 MODError(String.Format("return type mismatch for {0}",fname));
141 141
142 modInvoke(fname,parms); 142 modInvoke(fname,parms);
@@ -329,6 +329,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 if (result != null) 329 if (result != null)
330 return result; 330 return result;
331 331
332 Type returntype = m_comms.LookupReturnType(fname);
333 if (returntype == typeof(void))
334 return null;
335
332 MODError(String.Format("Invocation of {0} failed; null return value",fname)); 336 MODError(String.Format("Invocation of {0} failed; null return value",fname));
333 } 337 }
334 catch (Exception e) 338 catch (Exception e)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index bf1b45b..234ba34 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);
@@ -1644,7 +1653,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1644 } 1653 }
1645 } 1654 }
1646 1655
1647 public Object osParseJSONNew(string JSON) 1656 private Object osParseJSONNew(string JSON)
1648 { 1657 {
1649 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew"); 1658 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew");
1650 1659
@@ -1846,15 +1855,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1846 { 1855 {
1847 UUID assetID = UUID.Zero; 1856 UUID assetID = UUID.Zero;
1848 1857
1849 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1858 bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID);
1859
1860 if (!notecardNameIsUUID)
1850 { 1861 {
1851 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1862 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1852 {
1853 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1854 {
1855 assetID = item.AssetID;
1856 }
1857 }
1858 } 1863 }
1859 1864
1860 if (assetID == UUID.Zero) 1865 if (assetID == UUID.Zero)
@@ -1865,7 +1870,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1865 AssetBase a = World.AssetService.Get(assetID.ToString()); 1870 AssetBase a = World.AssetService.Get(assetID.ToString());
1866 1871
1867 if (a == null) 1872 if (a == null)
1868 return UUID.Zero; 1873 {
1874 // Whoops, it's still possible here that the notecard name was properly
1875 // formatted like a UUID but isn't an asset UUID so lets look it up by name after all
1876 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1877 if (assetID == UUID.Zero)
1878 return UUID.Zero;
1879
1880 if (!NotecardCache.IsCached(assetID))
1881 {
1882 a = World.AssetService.Get(assetID.ToString());
1883
1884 if (a == null)
1885 {
1886 return UUID.Zero;
1887 }
1888 }
1889 }
1869 1890
1870 string data = Encoding.UTF8.GetString(a.Data); 1891 string data = Encoding.UTF8.GetString(a.Data);
1871 NotecardCache.Cache(assetID, data); 1892 NotecardCache.Cache(assetID, data);
@@ -1873,6 +1894,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1873 1894
1874 return assetID; 1895 return assetID;
1875 } 1896 }
1897 protected UUID SearchTaskInventoryForAssetId(string name)
1898 {
1899 UUID assetId = UUID.Zero;
1900 m_host.TaskInventory.LockItemsForRead(true);
1901 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1902 {
1903 if (item.Type == 7 && item.Name == name)
1904 {
1905 assetId = item.AssetID;
1906 }
1907 }
1908 m_host.TaskInventory.LockItemsForRead(false);
1909 return assetId;
1910 }
1876 1911
1877 /// <summary> 1912 /// <summary>
1878 /// Directly get an entire notecard at once. 1913 /// Directly get an entire notecard at once.
@@ -2350,7 +2385,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2350 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2385 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2351 m_host.AddScriptLPS(1); 2386 m_host.AddScriptLPS(1);
2352 2387
2353 return NpcCreate(firstname, lastname, position, notecard, false, false); 2388 return NpcCreate(firstname, lastname, position, notecard, true, false);
2354 } 2389 }
2355 2390
2356 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2391 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2361,24 +2396,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2361 return NpcCreate( 2396 return NpcCreate(
2362 firstname, lastname, position, notecard, 2397 firstname, lastname, position, notecard,
2363 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2398 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2364 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2399 false);
2400// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2365 } 2401 }
2366 2402
2367 private LSL_Key NpcCreate( 2403 private LSL_Key NpcCreate(
2368 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2404 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2369 { 2405 {
2406 if (!owned)
2407 OSSLError("Unowned NPCs are unsupported");
2408
2409 string groupTitle = String.Empty;
2410
2411 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2412 return new LSL_Key(UUID.Zero.ToString());
2413
2414 if (firstname != String.Empty || lastname != String.Empty)
2415 {
2416 if (firstname != "Shown outfit:")
2417 groupTitle = "- NPC -";
2418 }
2419
2370 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2420 INPCModule module = World.RequestModuleInterface<INPCModule>();
2371 if (module != null) 2421 if (module != null)
2372 { 2422 {
2373 AvatarAppearance appearance = null; 2423 AvatarAppearance appearance = null;
2374 2424
2375 UUID id; 2425// UUID id;
2376 if (UUID.TryParse(notecard, out id)) 2426// if (UUID.TryParse(notecard, out id))
2377 { 2427// {
2378 ScenePresence clonePresence = World.GetScenePresence(id); 2428// ScenePresence clonePresence = World.GetScenePresence(id);
2379 if (clonePresence != null) 2429// if (clonePresence != null)
2380 appearance = clonePresence.Appearance; 2430// appearance = clonePresence.Appearance;
2381 } 2431// }
2382 2432
2383 if (appearance == null) 2433 if (appearance == null)
2384 { 2434 {
@@ -2386,9 +2436,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2386 2436
2387 if (appearanceSerialized != null) 2437 if (appearanceSerialized != null)
2388 { 2438 {
2389 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2439 try
2390 appearance = new AvatarAppearance(); 2440 {
2391 appearance.Unpack(appearanceOsd); 2441 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2442 appearance = new AvatarAppearance();
2443 appearance.Unpack(appearanceOsd);
2444 }
2445 catch
2446 {
2447 return UUID.Zero.ToString();
2448 }
2392 } 2449 }
2393 else 2450 else
2394 { 2451 {
@@ -2407,6 +2464,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2407 World, 2464 World,
2408 appearance); 2465 appearance);
2409 2466
2467 ScenePresence sp;
2468 if (World.TryGetScenePresence(x, out sp))
2469 {
2470 sp.Grouptitle = groupTitle;
2471 sp.SendAvatarDataToAllAgents();
2472 }
2410 return new LSL_Key(x.ToString()); 2473 return new LSL_Key(x.ToString());
2411 } 2474 }
2412 2475
@@ -2704,16 +2767,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2704 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2767 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2705 m_host.AddScriptLPS(1); 2768 m_host.AddScriptLPS(1);
2706 2769
2707 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2770 ManualResetEvent ev = new ManualResetEvent(false);
2708 if (module != null)
2709 {
2710 UUID npcId = new UUID(npc.m_string);
2711 2771
2712 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2772 Util.FireAndForget(delegate(object x) {
2713 return; 2773 try
2774 {
2775 INPCModule module = World.RequestModuleInterface<INPCModule>();
2776 if (module != null)
2777 {
2778 UUID npcId = new UUID(npc.m_string);
2714 2779
2715 module.DeleteNPC(npcId, World); 2780 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2716 } 2781 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2782 {
2783 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2784 return;
2785 }
2786
2787 module.DeleteNPC(npcId, World);
2788 }
2789 }
2790 finally
2791 {
2792 ev.Set();
2793 }
2794 });
2795 ev.WaitOne();
2717 } 2796 }
2718 2797
2719 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2798 public void osNpcPlayAnimation(LSL_Key npc, string animation)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 88ab515..884f07c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -93,7 +93,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
93 private const int AGENT = 1; 93 private const int AGENT = 1;
94 private const int AGENT_BY_USERNAME = 0x10; 94 private const int AGENT_BY_USERNAME = 0x10;
95 private const int NPC = 0x20; 95 private const int NPC = 0x20;
96 private const int OS_NPC = 0x01000000;
97 private const int ACTIVE = 2; 96 private const int ACTIVE = 2;
98 private const int PASSIVE = 4; 97 private const int PASSIVE = 4;
99 private const int SCRIPTED = 8; 98 private const int SCRIPTED = 8;
@@ -240,7 +239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
240 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 239 List<SensedEntity> sensedEntities = new List<SensedEntity>();
241 240
242 // Is the sensor type is AGENT and not SCRIPTED then include agents 241 // Is the sensor type is AGENT and not SCRIPTED then include agents
243 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 242 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
244 { 243 {
245 sensedEntities.AddRange(doAgentSensor(ts)); 244 sensedEntities.AddRange(doAgentSensor(ts));
246 } 245 }
@@ -339,7 +338,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
339 float dy; 338 float dy;
340 float dz; 339 float dz;
341 340
342 Quaternion q = SensePoint.GetWorldRotation(); 341// Quaternion q = SensePoint.RotationOffset;
342 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
343 if (SensePoint.ParentGroup.IsAttachment) 343 if (SensePoint.ParentGroup.IsAttachment)
344 { 344 {
345 // In attachments, rotate the sensor cone with the 345 // In attachments, rotate the sensor cone with the
@@ -353,7 +353,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
353 // Position of a sensor in a child prim attached to an avatar 353 // Position of a sensor in a child prim attached to an avatar
354 // will be still wrong. 354 // will be still wrong.
355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
356 q = avatar.GetWorldRotation() * q; 356 fromRegionPos = avatar.AbsolutePosition;
357 q = avatar.Rotation;
357 } 358 }
358 359
359 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 360 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -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.GetWorldRotation() * 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)
@@ -696,4 +700,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
696 return retList; 700 return retList;
697 } 701 }
698 } 702 }
699} \ No newline at end of file 703}
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 }