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.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3231
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs113
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
6 files changed, 2717 insertions, 814 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..b5fa6de
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,116 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal TaskInventoryItem m_item;
63 internal bool m_CMFunctionsEnabled = false;
64
65 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
66 {
67 m_ScriptEngine = ScriptEngine;
68 m_host = host;
69 m_item = item;
70
71 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
72 m_CMFunctionsEnabled = true;
73 }
74
75 public override Object InitializeLifetimeService()
76 {
77 ILease lease = (ILease)base.InitializeLifetimeService();
78
79 if (lease.CurrentState == LeaseState.Initial)
80 {
81 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
82 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
83 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
84 }
85 return lease;
86 }
87
88 public Scene World
89 {
90 get { return m_ScriptEngine.World; }
91 }
92
93 public string cmDetectedCountry(int number)
94 {
95 m_host.AddScriptLPS(1);
96 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
97 if (detectedParams == null)
98 return String.Empty;
99 return detectedParams.Country;
100 }
101
102 public string cmGetAgentCountry(LSL_Key key)
103 {
104 if (!World.Permissions.IsGod(m_host.OwnerID))
105 return String.Empty;
106
107 UUID uuid;
108
109 if (!UUID.TryParse(key, out uuid))
110 return String.Empty;
111
112 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
113 return account.UserCountry;
114 }
115 }
116}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index ea4e609..aa389ba 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,14 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -66,6 +69,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
66using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 69using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
67using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 70using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
68using System.Reflection; 71using System.Reflection;
72using Timer = System.Timers.Timer;
69 73
70namespace OpenSim.Region.ScriptEngine.Shared.Api 74namespace OpenSim.Region.ScriptEngine.Shared.Api
71{ 75{
@@ -105,16 +109,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
105 protected int m_notecardLineReadCharsMax = 255; 109 protected int m_notecardLineReadCharsMax = 255;
106 protected int m_scriptConsoleChannel = 0; 110 protected int m_scriptConsoleChannel = 0;
107 protected bool m_scriptConsoleChannelEnabled = false; 111 protected bool m_scriptConsoleChannelEnabled = false;
112 protected bool m_debuggerSafe = false;
108 protected IUrlModule m_UrlModule = null; 113 protected IUrlModule m_UrlModule = null;
109 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 114 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
110 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 115 new Dictionary<UUID, UserInfoCacheEntry>();
116 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
111 protected ISoundModule m_SoundModule = null; 117 protected ISoundModule m_SoundModule = null;
112 118
119// protected Timer m_ShoutSayTimer;
120 protected int m_SayShoutCount = 0;
121 DateTime m_lastSayShoutCheck;
122
123 private Dictionary<string, string> MovementAnimationsForLSL =
124 new Dictionary<string, string> {
125 {"FLY", "Flying"},
126 {"FLYSLOW", "FlyingSlow"},
127 {"HOVER_UP", "Hovering Up"},
128 {"HOVER_DOWN", "Hovering Down"},
129 {"HOVER", "Hovering"},
130 {"LAND", "Landing"},
131 {"FALLDOWN", "Falling Down"},
132 {"PREJUMP", "PreJumping"},
133 {"JUMP", "Jumping"},
134 {"STANDUP", "Standing Up"},
135 {"SOFT_LAND", "Soft Landing"},
136 {"STAND", "Standing"},
137 {"CROUCHWALK", "CrouchWalking"},
138 {"RUN", "Running"},
139 {"WALK", "Walking"},
140 {"CROUCH", "Crouching"},
141 {"TURNLEFT", "Turning Left"},
142 {"TURNRIGHT", "Turning Right"}
143 };
144
113 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 145 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
114 { 146 {
147/*
148 m_ShoutSayTimer = new Timer(1000);
149 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
150 m_ShoutSayTimer.AutoReset = true;
151 m_ShoutSayTimer.Start();
152*/
153 m_lastSayShoutCheck = DateTime.UtcNow;
154
115 m_ScriptEngine = ScriptEngine; 155 m_ScriptEngine = ScriptEngine;
116 m_host = host; 156 m_host = host;
117 m_item = item; 157 m_item = item;
158 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
118 159
119 LoadLimits(); // read script limits from config. 160 LoadLimits(); // read script limits from config.
120 161
@@ -179,6 +220,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
179 get { return m_ScriptEngine.World; } 220 get { return m_ScriptEngine.World; }
180 } 221 }
181 222
223 [DebuggerNonUserCode]
182 public void state(string newState) 224 public void state(string newState)
183 { 225 {
184 m_ScriptEngine.SetState(m_item.ItemID, newState); 226 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -188,6 +230,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
188 /// Reset the named script. The script must be present 230 /// Reset the named script. The script must be present
189 /// in the same prim. 231 /// in the same prim.
190 /// </summary> 232 /// </summary>
233 [DebuggerNonUserCode]
191 public void llResetScript() 234 public void llResetScript()
192 { 235 {
193 m_host.AddScriptLPS(1); 236 m_host.AddScriptLPS(1);
@@ -250,6 +293,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
250 } 293 }
251 } 294 }
252 295
296 public List<ScenePresence> GetLinkAvatars(int linkType)
297 {
298 List<ScenePresence> ret = new List<ScenePresence>();
299 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
300 return ret;
301
302 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
303
304 switch (linkType)
305 {
306 case ScriptBaseClass.LINK_SET:
307 return avs;
308
309 case ScriptBaseClass.LINK_ROOT:
310 return ret;
311
312 case ScriptBaseClass.LINK_ALL_OTHERS:
313 return avs;
314
315 case ScriptBaseClass.LINK_ALL_CHILDREN:
316 return avs;
317
318 case ScriptBaseClass.LINK_THIS:
319 return ret;
320
321 default:
322 if (linkType < 0)
323 return ret;
324
325 int partCount = m_host.ParentGroup.GetPartCount();
326
327 if (linkType <= partCount)
328 {
329 return ret;
330 }
331 else
332 {
333 linkType = linkType - partCount;
334 if (linkType > avs.Count)
335 {
336 return ret;
337 }
338 else
339 {
340 ret.Add(avs[linkType-1]);
341 return ret;
342 }
343 }
344 }
345 }
346
253 public List<SceneObjectPart> GetLinkParts(int linkType) 347 public List<SceneObjectPart> GetLinkParts(int linkType)
254 { 348 {
255 return GetLinkParts(m_host, linkType); 349 return GetLinkParts(m_host, linkType);
@@ -258,6 +352,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
258 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 352 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
259 { 353 {
260 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 354 List<SceneObjectPart> ret = new List<SceneObjectPart>();
355 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
356 return ret;
261 ret.Add(part); 357 ret.Add(part);
262 358
263 switch (linkType) 359 switch (linkType)
@@ -484,31 +580,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
484 580
485 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 581 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
486 582
487 /// <summary> 583 // Utility function for llRot2Euler
488 /// Convert an LSL rotation to a Euler vector. 584
489 /// </summary> 585 // normalize an angle between -PI and PI (-180 to +180 degrees)
490 /// <remarks> 586 protected double NormalizeAngle(double angle)
491 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
492 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
493 /// </remarks>
494 /// <param name="r"></param>
495 /// <returns></returns>
496 public LSL_Vector llRot2Euler(LSL_Rotation r)
497 { 587 {
498 m_host.AddScriptLPS(1); 588 if (angle > -Math.PI && angle < Math.PI)
589 return angle;
499 590
500 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 591 int numPis = (int)(Math.PI / angle);
501 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 592 double remainder = angle - Math.PI * numPis;
502 if (m == 0.0) return new LSL_Vector(); 593 if (numPis % 2 == 1)
503 double x = Math.Atan2(-v.y, v.z); 594 return Math.PI - angle;
504 double sin = v.x / m; 595 return remainder;
505 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 596 }
506 double y = Math.Asin(sin);
507 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
508 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)));
509 double z = Math.Atan2(v.y, v.x);
510 597
511 return new LSL_Vector(x, y, z); 598 public LSL_Vector llRot2Euler(LSL_Rotation q1)
599 {
600 m_host.AddScriptLPS(1);
601 LSL_Vector eul = new LSL_Vector();
602
603 double sqw = q1.s*q1.s;
604 double sqx = q1.x*q1.x;
605 double sqy = q1.z*q1.z;
606 double sqz = q1.y*q1.y;
607 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
608 double test = q1.x*q1.z + q1.y*q1.s;
609 if (test > 0.4999*unit) { // singularity at north pole
610 eul.z = 2 * Math.Atan2(q1.x,q1.s);
611 eul.y = Math.PI/2;
612 eul.x = 0;
613 return eul;
614 }
615 if (test < -0.4999*unit) { // singularity at south pole
616 eul.z = -2 * Math.Atan2(q1.x,q1.s);
617 eul.y = -Math.PI/2;
618 eul.x = 0;
619 return eul;
620 }
621 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
622 eul.y = Math.Asin(2*test/unit);
623 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
624 return eul;
512 } 625 }
513 626
514 /* From wiki: 627 /* From wiki:
@@ -561,18 +674,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
561 m_host.AddScriptLPS(1); 674 m_host.AddScriptLPS(1);
562 675
563 double x,y,z,s; 676 double x,y,z,s;
564 677 v.x *= 0.5;
565 double c1 = Math.Cos(v.x * 0.5); 678 v.y *= 0.5;
566 double c2 = Math.Cos(v.y * 0.5); 679 v.z *= 0.5;
567 double c3 = Math.Cos(v.z * 0.5); 680 double c1 = Math.Cos(v.x);
568 double s1 = Math.Sin(v.x * 0.5); 681 double c2 = Math.Cos(v.y);
569 double s2 = Math.Sin(v.y * 0.5); 682 double c1c2 = c1 * c2;
570 double s3 = Math.Sin(v.z * 0.5); 683 double s1 = Math.Sin(v.x);
571 684 double s2 = Math.Sin(v.y);
572 x = s1 * c2 * c3 + c1 * s2 * s3; 685 double s1s2 = s1 * s2;
573 y = c1 * s2 * c3 - s1 * c2 * s3; 686 double c1s2 = c1 * s2;
574 z = s1 * s2 * c3 + c1 * c2 * s3; 687 double s1c2 = s1 * c2;
575 s = c1 * c2 * c3 - s1 * s2 * s3; 688 double c3 = Math.Cos(v.z);
689 double s3 = Math.Sin(v.z);
690
691 x = s1c2 * c3 + c1s2 * s3;
692 y = c1s2 * c3 - s1c2 * s3;
693 z = s1s2 * c3 + c1c2 * s3;
694 s = c1c2 * c3 - s1s2 * s3;
576 695
577 return new LSL_Rotation(x, y, z, s); 696 return new LSL_Rotation(x, y, z, s);
578 } 697 }
@@ -710,77 +829,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
710 { 829 {
711 //A and B should both be normalized 830 //A and B should both be normalized
712 m_host.AddScriptLPS(1); 831 m_host.AddScriptLPS(1);
713 LSL_Rotation rotBetween; 832 /* This method is more accurate than the SL one, and thus causes problems
714 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 833 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
715 // continue calculation. 834
716 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 835 double dotProduct = LSL_Vector.Dot(a, b);
836 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
837 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
838 double angle = Math.Acos(dotProduct / magProduct);
839 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
840 double s = Math.Sin(angle / 2);
841
842 double x = axis.x * s;
843 double y = axis.y * s;
844 double z = axis.z * s;
845 double w = Math.Cos(angle / 2);
846
847 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
848 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
849
850 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
851 */
852
853 // This method mimics the 180 errors found in SL
854 // See www.euclideanspace.com... angleBetween
855 LSL_Vector vec_a = a;
856 LSL_Vector vec_b = b;
857
858 // Eliminate zero length
859 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
860 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
861 if (vec_a_mag < 0.00001 ||
862 vec_b_mag < 0.00001)
717 { 863 {
718 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 864 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
719 } 865 }
720 else 866
867 // Normalize
868 vec_a = llVecNorm(vec_a);
869 vec_b = llVecNorm(vec_b);
870
871 // Calculate axis and rotation angle
872 LSL_Vector axis = vec_a % vec_b;
873 LSL_Float cos_theta = vec_a * vec_b;
874
875 // Check if parallel
876 if (cos_theta > 0.99999)
721 { 877 {
722 a = LSL_Vector.Norm(a); 878 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
723 b = LSL_Vector.Norm(b); 879 }
724 double dotProduct = LSL_Vector.Dot(a, b); 880
725 // There are two degenerate cases possible. These are for vectors 180 or 881 // Check if anti-parallel
726 // 0 degrees apart. These have to be detected and handled individually. 882 else if (cos_theta < -0.99999)
727 // 883 {
728 // Check for vectors 180 degrees apart. 884 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
729 // A dot product of -1 would mean the angle between vectors is 180 degrees. 885 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
730 if (dotProduct < -0.9999999f) 886 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
731 { 887 }
732 // First assume X axis is orthogonal to the vectors. 888 else // other rotation
733 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 889 {
734 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 890 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
735 // Check for near zero vector. A very small non-zero number here will create 891 axis = llVecNorm(axis);
736 // a rotation in an undesired direction. 892 double x, y, z, s, t;
737 if (LSL_Vector.Mag(orthoVector) > 0.0001) 893 s = Math.Cos(theta);
738 { 894 t = Math.Sin(theta);
739 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 895 x = axis.x * t;
740 } 896 y = axis.y * t;
741 // If the magnitude of the vector was near zero, then assume the X axis is not 897 z = axis.z * t;
742 // orthogonal and use the Z axis instead. 898 return new LSL_Rotation(x,y,z,s);
743 else
744 {
745 // Set 180 z rotation.
746 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
747 }
748 }
749 // Check for parallel vectors.
750 // A dot product of 1 would mean the angle between vectors is 0 degrees.
751 else if (dotProduct > 0.9999999f)
752 {
753 // Set zero rotation.
754 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
755 }
756 else
757 {
758 // All special checks have been performed so get the axis of rotation.
759 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
760 // Quarternion s value is the length of the unit vector + dot product.
761 double qs = 1.0 + dotProduct;
762 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
763 // Normalize the rotation.
764 double mag = LSL_Rotation.Mag(rotBetween);
765 // We shouldn't have to worry about a divide by zero here. The qs value will be
766 // non-zero because we already know if we're here, then the dotProduct is not -1 so
767 // qs will not be zero. Also, we've already handled the input vectors being zero so the
768 // crossProduct vector should also not be zero.
769 rotBetween.x = rotBetween.x / mag;
770 rotBetween.y = rotBetween.y / mag;
771 rotBetween.z = rotBetween.z / mag;
772 rotBetween.s = rotBetween.s / mag;
773 // Check for undefined values and set zero rotation if any found. This code might not actually be required
774 // any longer since zero vectors are checked for at the top.
775 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
776 {
777 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
778 }
779 }
780 } 899 }
781 return rotBetween;
782 } 900 }
783 901
784 public void llWhisper(int channelID, string text) 902 public void llWhisper(int channelID, string text)
785 { 903 {
786 m_host.AddScriptLPS(1); 904 m_host.AddScriptLPS(1);
@@ -796,10 +914,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
796 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 914 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
797 } 915 }
798 916
917 private void CheckSayShoutTime()
918 {
919 DateTime now = DateTime.UtcNow;
920 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
921 {
922 m_lastSayShoutCheck = now;
923 m_SayShoutCount = 0;
924 }
925 else
926 m_SayShoutCount++;
927 }
928
799 public void llSay(int channelID, string text) 929 public void llSay(int channelID, string text)
800 { 930 {
801 m_host.AddScriptLPS(1); 931 m_host.AddScriptLPS(1);
802 932
933 if (channelID == 0)
934// m_SayShoutCount++;
935 CheckSayShoutTime();
936
937 if (m_SayShoutCount >= 11)
938 ScriptSleep(2000);
939
803 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 940 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
804 { 941 {
805 Console.WriteLine(text); 942 Console.WriteLine(text);
@@ -822,6 +959,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
822 { 959 {
823 m_host.AddScriptLPS(1); 960 m_host.AddScriptLPS(1);
824 961
962 if (channelID == 0)
963// m_SayShoutCount++;
964 CheckSayShoutTime();
965
966 if (m_SayShoutCount >= 11)
967 ScriptSleep(2000);
968
825 if (text.Length > 1023) 969 if (text.Length > 1023)
826 text = text.Substring(0, 1023); 970 text = text.Substring(0, 1023);
827 971
@@ -853,22 +997,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
853 997
854 public void llRegionSayTo(string target, int channel, string msg) 998 public void llRegionSayTo(string target, int channel, string msg)
855 { 999 {
1000 string error = String.Empty;
1001
856 if (msg.Length > 1023) 1002 if (msg.Length > 1023)
857 msg = msg.Substring(0, 1023); 1003 msg = msg.Substring(0, 1023);
858 1004
859 m_host.AddScriptLPS(1); 1005 m_host.AddScriptLPS(1);
860 1006
861 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
862 {
863 return;
864 }
865
866 UUID TargetID; 1007 UUID TargetID;
867 UUID.TryParse(target, out TargetID); 1008 UUID.TryParse(target, out TargetID);
868 1009
869 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1010 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
870 if (wComm != null) 1011 if (wComm != null)
871 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1012 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1013 LSLError(error);
872 } 1014 }
873 1015
874 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1016 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1124,10 +1266,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1124 return detectedParams.TouchUV; 1266 return detectedParams.TouchUV;
1125 } 1267 }
1126 1268
1269 [DebuggerNonUserCode]
1127 public virtual void llDie() 1270 public virtual void llDie()
1128 { 1271 {
1129 m_host.AddScriptLPS(1); 1272 m_host.AddScriptLPS(1);
1130 throw new SelfDeleteException(); 1273 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1131 } 1274 }
1132 1275
1133 public LSL_Float llGround(LSL_Vector offset) 1276 public LSL_Float llGround(LSL_Vector offset)
@@ -1198,6 +1341,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1198 1341
1199 public void llSetStatus(int status, int value) 1342 public void llSetStatus(int status, int value)
1200 { 1343 {
1344 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1345 return;
1201 m_host.AddScriptLPS(1); 1346 m_host.AddScriptLPS(1);
1202 1347
1203 int statusrotationaxis = 0; 1348 int statusrotationaxis = 0;
@@ -1221,6 +1366,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1221 if (!allow) 1366 if (!allow)
1222 return; 1367 return;
1223 1368
1369 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1370 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1371 return;
1372
1224 m_host.ScriptSetPhysicsStatus(true); 1373 m_host.ScriptSetPhysicsStatus(true);
1225 } 1374 }
1226 else 1375 else
@@ -1421,6 +1570,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1421 { 1570 {
1422 m_host.AddScriptLPS(1); 1571 m_host.AddScriptLPS(1);
1423 1572
1573 SetColor(m_host, color, face);
1574 }
1575
1576 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1577 {
1578 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1579 return;
1580
1581 Primitive.TextureEntry tex = part.Shape.Textures;
1582 Color4 texcolor;
1583 if (face >= 0 && face < GetNumberOfSides(part))
1584 {
1585 texcolor = tex.CreateFace((uint)face).RGBA;
1586 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1587 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1588 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1589 tex.FaceTextures[face].RGBA = texcolor;
1590 part.UpdateTextureEntry(tex.GetBytes());
1591 return;
1592 }
1593 else if (face == ScriptBaseClass.ALL_SIDES)
1594 {
1595 for (uint i = 0; i < GetNumberOfSides(part); i++)
1596 {
1597 if (tex.FaceTextures[i] != null)
1598 {
1599 texcolor = tex.FaceTextures[i].RGBA;
1600 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1601 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1602 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1603 tex.FaceTextures[i].RGBA = texcolor;
1604 }
1605 texcolor = tex.DefaultTexture.RGBA;
1606 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1607 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1608 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1609 tex.DefaultTexture.RGBA = texcolor;
1610 }
1611 part.UpdateTextureEntry(tex.GetBytes());
1612 return;
1613 }
1614
1424 if (face == ScriptBaseClass.ALL_SIDES) 1615 if (face == ScriptBaseClass.ALL_SIDES)
1425 face = SceneObjectPart.ALL_SIDES; 1616 face = SceneObjectPart.ALL_SIDES;
1426 1617
@@ -1429,6 +1620,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1429 1620
1430 public void SetTexGen(SceneObjectPart part, int face,int style) 1621 public void SetTexGen(SceneObjectPart part, int face,int style)
1431 { 1622 {
1623 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1624 return;
1625
1432 Primitive.TextureEntry tex = part.Shape.Textures; 1626 Primitive.TextureEntry tex = part.Shape.Textures;
1433 MappingType textype; 1627 MappingType textype;
1434 textype = MappingType.Default; 1628 textype = MappingType.Default;
@@ -1459,6 +1653,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1459 1653
1460 public void SetGlow(SceneObjectPart part, int face, float glow) 1654 public void SetGlow(SceneObjectPart part, int face, float glow)
1461 { 1655 {
1656 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1657 return;
1658
1462 Primitive.TextureEntry tex = part.Shape.Textures; 1659 Primitive.TextureEntry tex = part.Shape.Textures;
1463 if (face >= 0 && face < GetNumberOfSides(part)) 1660 if (face >= 0 && face < GetNumberOfSides(part))
1464 { 1661 {
@@ -1484,6 +1681,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1484 1681
1485 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1682 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1486 { 1683 {
1684 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1685 return;
1487 1686
1488 Shininess sval = new Shininess(); 1687 Shininess sval = new Shininess();
1489 1688
@@ -1534,6 +1733,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1534 1733
1535 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1734 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1536 { 1735 {
1736 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1737 return;
1738
1537 Primitive.TextureEntry tex = part.Shape.Textures; 1739 Primitive.TextureEntry tex = part.Shape.Textures;
1538 if (face >= 0 && face < GetNumberOfSides(part)) 1740 if (face >= 0 && face < GetNumberOfSides(part))
1539 { 1741 {
@@ -1594,13 +1796,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1594 m_host.AddScriptLPS(1); 1796 m_host.AddScriptLPS(1);
1595 1797
1596 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1798 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1597 1799 if (parts.Count > 0)
1598 foreach (SceneObjectPart part in parts) 1800 {
1599 SetAlpha(part, alpha, face); 1801 try
1802 {
1803 foreach (SceneObjectPart part in parts)
1804 SetAlpha(part, alpha, face);
1805 }
1806 finally
1807 {
1808 }
1809 }
1600 } 1810 }
1601 1811
1602 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1812 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1603 { 1813 {
1814 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1815 return;
1816
1604 Primitive.TextureEntry tex = part.Shape.Textures; 1817 Primitive.TextureEntry tex = part.Shape.Textures;
1605 Color4 texcolor; 1818 Color4 texcolor;
1606 if (face >= 0 && face < GetNumberOfSides(part)) 1819 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1653,7 +1866,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1653 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1866 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1654 float wind, float tension, LSL_Vector Force) 1867 float wind, float tension, LSL_Vector Force)
1655 { 1868 {
1656 if (part == null) 1869 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1657 return; 1870 return;
1658 1871
1659 if (flexi) 1872 if (flexi)
@@ -1687,7 +1900,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1687 /// <param name="falloff"></param> 1900 /// <param name="falloff"></param>
1688 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1901 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1689 { 1902 {
1690 if (part == null) 1903 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1691 return; 1904 return;
1692 1905
1693 if (light) 1906 if (light)
@@ -1720,11 +1933,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1720 Primitive.TextureEntry tex = part.Shape.Textures; 1933 Primitive.TextureEntry tex = part.Shape.Textures;
1721 Color4 texcolor; 1934 Color4 texcolor;
1722 LSL_Vector rgb = new LSL_Vector(); 1935 LSL_Vector rgb = new LSL_Vector();
1936 int nsides = GetNumberOfSides(part);
1937
1723 if (face == ScriptBaseClass.ALL_SIDES) 1938 if (face == ScriptBaseClass.ALL_SIDES)
1724 { 1939 {
1725 int i; 1940 int i;
1726 1941 for (i = 0; i < nsides; i++)
1727 for (i = 0 ; i < GetNumberOfSides(part); i++)
1728 { 1942 {
1729 texcolor = tex.GetFace((uint)i).RGBA; 1943 texcolor = tex.GetFace((uint)i).RGBA;
1730 rgb.x += texcolor.R; 1944 rgb.x += texcolor.R;
@@ -1732,14 +1946,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1732 rgb.z += texcolor.B; 1946 rgb.z += texcolor.B;
1733 } 1947 }
1734 1948
1735 rgb.x /= (float)GetNumberOfSides(part); 1949 float invnsides = 1.0f / (float)nsides;
1736 rgb.y /= (float)GetNumberOfSides(part); 1950
1737 rgb.z /= (float)GetNumberOfSides(part); 1951 rgb.x *= invnsides;
1952 rgb.y *= invnsides;
1953 rgb.z *= invnsides;
1738 1954
1739 return rgb; 1955 return rgb;
1740 } 1956 }
1741 1957 if (face >= 0 && face < nsides)
1742 if (face >= 0 && face < GetNumberOfSides(part))
1743 { 1958 {
1744 texcolor = tex.GetFace((uint)face).RGBA; 1959 texcolor = tex.GetFace((uint)face).RGBA;
1745 rgb.x = texcolor.R; 1960 rgb.x = texcolor.R;
@@ -1766,15 +1981,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1766 m_host.AddScriptLPS(1); 1981 m_host.AddScriptLPS(1);
1767 1982
1768 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1983 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1769 1984 if (parts.Count > 0)
1770 foreach (SceneObjectPart part in parts) 1985 {
1771 SetTexture(part, texture, face); 1986 try
1772 1987 {
1988 foreach (SceneObjectPart part in parts)
1989 SetTexture(part, texture, face);
1990 }
1991 finally
1992 {
1993 }
1994 }
1773 ScriptSleep(200); 1995 ScriptSleep(200);
1774 } 1996 }
1775 1997
1776 protected void SetTexture(SceneObjectPart part, string texture, int face) 1998 protected void SetTexture(SceneObjectPart part, string texture, int face)
1777 { 1999 {
2000 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2001 return;
2002
1778 UUID textureID = new UUID(); 2003 UUID textureID = new UUID();
1779 2004
1780 textureID = InventoryKey(texture, (int)AssetType.Texture); 2005 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1819,6 +2044,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1819 2044
1820 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2045 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1821 { 2046 {
2047 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2048 return;
2049
1822 Primitive.TextureEntry tex = part.Shape.Textures; 2050 Primitive.TextureEntry tex = part.Shape.Textures;
1823 if (face >= 0 && face < GetNumberOfSides(part)) 2051 if (face >= 0 && face < GetNumberOfSides(part))
1824 { 2052 {
@@ -1855,6 +2083,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1855 2083
1856 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2084 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1857 { 2085 {
2086 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2087 return;
2088
1858 Primitive.TextureEntry tex = part.Shape.Textures; 2089 Primitive.TextureEntry tex = part.Shape.Textures;
1859 if (face >= 0 && face < GetNumberOfSides(part)) 2090 if (face >= 0 && face < GetNumberOfSides(part))
1860 { 2091 {
@@ -1891,6 +2122,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1891 2122
1892 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2123 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1893 { 2124 {
2125 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2126 return;
2127
1894 Primitive.TextureEntry tex = part.Shape.Textures; 2128 Primitive.TextureEntry tex = part.Shape.Textures;
1895 if (face >= 0 && face < GetNumberOfSides(part)) 2129 if (face >= 0 && face < GetNumberOfSides(part))
1896 { 2130 {
@@ -2061,24 +2295,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2061 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2295 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2062 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2296 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2063 { 2297 {
2064 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2298 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2299 return;
2300
2065 LSL_Vector currentPos = GetPartLocalPos(part); 2301 LSL_Vector currentPos = GetPartLocalPos(part);
2302 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2066 2303
2067 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2068 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2069 2304
2070 if (part.ParentGroup.RootPart == part) 2305 if (part.ParentGroup.RootPart == part)
2071 { 2306 {
2072 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2073 targetPos.z = ground;
2074 SceneObjectGroup parent = part.ParentGroup; 2307 SceneObjectGroup parent = part.ParentGroup;
2075 parent.UpdateGroupPosition(!adjust ? targetPos : 2308 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2076 SetPosAdjust(currentPos, targetPos)); 2309 return;
2310 Util.FireAndForget(delegate(object x) {
2311 parent.UpdateGroupPosition((Vector3)toPos);
2312 });
2077 } 2313 }
2078 else 2314 else
2079 { 2315 {
2080 part.OffsetPosition = !adjust ? targetPos : 2316 part.OffsetPosition = (Vector3)toPos;
2081 SetPosAdjust(currentPos, targetPos);
2082 SceneObjectGroup parent = part.ParentGroup; 2317 SceneObjectGroup parent = part.ParentGroup;
2083 parent.HasGroupChanged = true; 2318 parent.HasGroupChanged = true;
2084 parent.ScheduleGroupForTerseUpdate(); 2319 parent.ScheduleGroupForTerseUpdate();
@@ -2110,13 +2345,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2110 else 2345 else
2111 { 2346 {
2112 if (part.ParentGroup.IsAttachment) 2347 if (part.ParentGroup.IsAttachment)
2113 {
2114 pos = part.AttachedPos; 2348 pos = part.AttachedPos;
2115 }
2116 else 2349 else
2117 {
2118 pos = part.AbsolutePosition; 2350 pos = part.AbsolutePosition;
2119 }
2120 } 2351 }
2121 2352
2122// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2353// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2156,25 +2387,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2156 2387
2157 protected void SetRot(SceneObjectPart part, Quaternion rot) 2388 protected void SetRot(SceneObjectPart part, Quaternion rot)
2158 { 2389 {
2159 part.UpdateRotation(rot); 2390 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2160 // Update rotation does not move the object in the physics scene if it's a linkset. 2391 return;
2161 2392
2162//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2393 bool isroot = (part == part.ParentGroup.RootPart);
2163// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2394 bool isphys;
2164 2395
2165 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2166 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2167 // It's perfectly okay when the object is not an active physical body though.
2168 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2169 // but only if the object is not physial and active. This is important for rotating doors.
2170 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2171 // scene
2172 PhysicsActor pa = part.PhysActor; 2396 PhysicsActor pa = part.PhysActor;
2173 2397
2174 if (pa != null && !pa.IsPhysical) 2398 // keep using physactor ideia of isphysical
2399 // it should be SOP ideia of that
2400 // not much of a issue with ubitODE
2401 if (pa != null && pa.IsPhysical)
2402 isphys = true;
2403 else
2404 isphys = false;
2405
2406 // SL doesn't let scripts rotate root of physical linksets
2407 if (isroot && isphys)
2408 return;
2409
2410 part.UpdateRotation(rot);
2411
2412 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2413 // so do a nasty update of parts positions if is a root part rotation
2414 if (isroot && pa != null) // with if above implies non physical root part
2175 { 2415 {
2176 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2416 part.ParentGroup.ResetChildPrimPhysicsPositions();
2177 } 2417 }
2418 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2419 {
2420 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2421 if (sittingavas.Count > 0)
2422 {
2423 foreach (ScenePresence av in sittingavas)
2424 {
2425 if (isroot || part.LocalId == av.ParentID)
2426 av.SendTerseUpdateToAllClients();
2427 }
2428 }
2429 }
2178 } 2430 }
2179 2431
2180 /// <summary> 2432 /// <summary>
@@ -2222,8 +2474,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2222 2474
2223 public LSL_Rotation llGetLocalRot() 2475 public LSL_Rotation llGetLocalRot()
2224 { 2476 {
2477 return GetPartLocalRot(m_host);
2478 }
2479
2480 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2481 {
2225 m_host.AddScriptLPS(1); 2482 m_host.AddScriptLPS(1);
2226 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2483 Quaternion rot = part.RotationOffset;
2484 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2227 } 2485 }
2228 2486
2229 public void llSetForce(LSL_Vector force, int local) 2487 public void llSetForce(LSL_Vector force, int local)
@@ -2303,16 +2561,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2303 m_host.ApplyImpulse(v, local != 0); 2561 m_host.ApplyImpulse(v, local != 0);
2304 } 2562 }
2305 2563
2564
2306 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2565 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2307 { 2566 {
2308 m_host.AddScriptLPS(1); 2567 m_host.AddScriptLPS(1);
2309 m_host.ApplyAngularImpulse(force, local != 0); 2568 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2310 } 2569 }
2311 2570
2312 public void llSetTorque(LSL_Vector torque, int local) 2571 public void llSetTorque(LSL_Vector torque, int local)
2313 { 2572 {
2314 m_host.AddScriptLPS(1); 2573 m_host.AddScriptLPS(1);
2315 m_host.SetAngularImpulse(torque, local != 0); 2574 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2316 } 2575 }
2317 2576
2318 public LSL_Vector llGetTorque() 2577 public LSL_Vector llGetTorque()
@@ -2329,20 +2588,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2329 llSetTorque(torque, local); 2588 llSetTorque(torque, local);
2330 } 2589 }
2331 2590
2591 public void llSetVelocity(LSL_Vector vel, int local)
2592 {
2593 m_host.AddScriptLPS(1);
2594 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2595 }
2596
2332 public LSL_Vector llGetVel() 2597 public LSL_Vector llGetVel()
2333 { 2598 {
2334 m_host.AddScriptLPS(1); 2599 m_host.AddScriptLPS(1);
2335 2600
2336 Vector3 vel; 2601 Vector3 vel = Vector3.Zero;
2337 2602
2338 if (m_host.ParentGroup.IsAttachment) 2603 if (m_host.ParentGroup.IsAttachment)
2339 { 2604 {
2340 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2605 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2341 vel = avatar.Velocity; 2606 if (avatar != null)
2607 vel = avatar.Velocity;
2342 } 2608 }
2343 else 2609 else
2344 { 2610 {
2345 vel = m_host.Velocity; 2611 vel = m_host.ParentGroup.RootPart.Velocity;
2346 } 2612 }
2347 2613
2348 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2614 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2354,10 +2620,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2354 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2620 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2355 } 2621 }
2356 2622
2623 public void llSetAngularVelocity(LSL_Vector avel, int local)
2624 {
2625 m_host.AddScriptLPS(1);
2626 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2627 }
2628
2357 public LSL_Vector llGetOmega() 2629 public LSL_Vector llGetOmega()
2358 { 2630 {
2359 m_host.AddScriptLPS(1); 2631 m_host.AddScriptLPS(1);
2360 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2632 Vector3 avel = m_host.AngularVelocity;
2633 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2361 } 2634 }
2362 2635
2363 public LSL_Float llGetTimeOfDay() 2636 public LSL_Float llGetTimeOfDay()
@@ -2746,7 +3019,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2746 } 3019 }
2747 3020
2748 bool result = money.ObjectGiveMoney( 3021 bool result = money.ObjectGiveMoney(
2749 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3022 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2750 3023
2751 if (result) 3024 if (result)
2752 return 1; 3025 return 1;
@@ -2830,13 +3103,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2830 new_group.RootPart.UUID.ToString()) }, 3103 new_group.RootPart.UUID.ToString()) },
2831 new DetectParams[0])); 3104 new DetectParams[0]));
2832 3105
2833 float groupmass = new_group.GetMass(); 3106 // do recoil
3107 SceneObjectGroup hostgrp = m_host.ParentGroup;
3108 if (hostgrp == null)
3109 return;
3110
3111 if (hostgrp.IsAttachment) // don't recoil avatars
3112 return;
2834 3113
2835 PhysicsActor pa = new_group.RootPart.PhysActor; 3114 PhysicsActor pa = new_group.RootPart.PhysActor;
2836 3115
2837 //Recoil. 3116 //Recoil.
2838 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3117 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2839 { 3118 {
3119 float groupmass = new_group.GetMass();
2840 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3120 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2841 if (recoil != Vector3.Zero) 3121 if (recoil != Vector3.Zero)
2842 { 3122 {
@@ -2844,6 +3124,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2844 } 3124 }
2845 } 3125 }
2846 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3126 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3127 return;
3128
2847 }); 3129 });
2848 3130
2849 //ScriptSleep((int)((groupmass * velmag) / 10)); 3131 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2858,35 +3140,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2858 public void llLookAt(LSL_Vector target, double strength, double damping) 3140 public void llLookAt(LSL_Vector target, double strength, double damping)
2859 { 3141 {
2860 m_host.AddScriptLPS(1); 3142 m_host.AddScriptLPS(1);
2861 // Determine where we are looking from
2862 LSL_Vector from = llGetPos();
2863 3143
2864 // Work out the normalised vector from the source to the target 3144 // Get the normalized vector to the target
2865 LSL_Vector delta = llVecNorm(target - from); 3145 LSL_Vector d1 = llVecNorm(target - llGetPos());
2866 LSL_Vector angle = new LSL_Vector(0,0,0);
2867 3146
2868 // Calculate the yaw 3147 // Get the bearing (yaw)
2869 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3148 LSL_Vector a1 = new LSL_Vector(0,0,0);
2870 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3149 a1.z = llAtan2(d1.y, d1.x);
2871 3150
2872 // Calculate pitch 3151 // Get the elevation (pitch)
2873 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3152 LSL_Vector a2 = new LSL_Vector(0,0,0);
3153 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2874 3154
2875 // we need to convert from a vector describing 3155 LSL_Rotation r1 = llEuler2Rot(a1);
2876 // the angles of rotation in radians into rotation value 3156 LSL_Rotation r2 = llEuler2Rot(a2);
2877 LSL_Rotation rot = llEuler2Rot(angle); 3157 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2878
2879 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2880 // set the rotation of the object, copy that behavior
2881 PhysicsActor pa = m_host.PhysActor;
2882 3158
2883 if (strength == 0 || pa == null || !pa.IsPhysical) 3159 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2884 { 3160 {
2885 llSetRot(rot); 3161 // Do nothing if either value is 0 (this has been checked in SL)
3162 if (strength <= 0.0 || damping <= 0.0)
3163 return;
3164
3165 llSetRot(r3 * r2 * r1);
2886 } 3166 }
2887 else 3167 else
2888 { 3168 {
2889 m_host.StartLookAt(rot, (float)strength, (float)damping); 3169 if (strength == 0)
3170 {
3171 llSetRot(r3 * r2 * r1);
3172 return;
3173 }
3174
3175 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2890 } 3176 }
2891 } 3177 }
2892 3178
@@ -2932,17 +3218,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2932 } 3218 }
2933 else 3219 else
2934 { 3220 {
2935 if (m_host.IsRoot) 3221 // new SL always returns object mass
2936 { 3222// if (m_host.IsRoot)
3223// {
2937 return m_host.ParentGroup.GetMass(); 3224 return m_host.ParentGroup.GetMass();
2938 } 3225// }
2939 else 3226// else
2940 { 3227// {
2941 return m_host.GetMass(); 3228// return m_host.GetMass();
2942 } 3229// }
2943 } 3230 }
2944 } 3231 }
2945 3232
3233
3234 public LSL_Float llGetMassMKS()
3235 {
3236 return 100f * llGetMass();
3237 }
3238
2946 public void llCollisionFilter(string name, string id, int accept) 3239 public void llCollisionFilter(string name, string id, int accept)
2947 { 3240 {
2948 m_host.AddScriptLPS(1); 3241 m_host.AddScriptLPS(1);
@@ -2990,8 +3283,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2990 { 3283 {
2991 // Unregister controls from Presence 3284 // Unregister controls from Presence
2992 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3285 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2993 // Remove Take Control permission.
2994 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
2995 } 3286 }
2996 } 3287 }
2997 } 3288 }
@@ -3019,7 +3310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3019 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3310 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3020 3311
3021 if (attachmentsModule != null) 3312 if (attachmentsModule != null)
3022 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3313 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3023 else 3314 else
3024 return false; 3315 return false;
3025 } 3316 }
@@ -3049,9 +3340,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3049 { 3340 {
3050 m_host.AddScriptLPS(1); 3341 m_host.AddScriptLPS(1);
3051 3342
3052// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3053// return;
3054
3055 if (m_item.PermsGranter != m_host.OwnerID) 3343 if (m_item.PermsGranter != m_host.OwnerID)
3056 return; 3344 return;
3057 3345
@@ -3094,6 +3382,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3094 3382
3095 public void llInstantMessage(string user, string message) 3383 public void llInstantMessage(string user, string message)
3096 { 3384 {
3385 UUID result;
3386 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3387 {
3388 ShoutError("An invalid key was passed to llInstantMessage");
3389 ScriptSleep(2000);
3390 return;
3391 }
3392
3393
3097 m_host.AddScriptLPS(1); 3394 m_host.AddScriptLPS(1);
3098 3395
3099 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3396 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3108,14 +3405,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3108 UUID friendTransactionID = UUID.Random(); 3405 UUID friendTransactionID = UUID.Random();
3109 3406
3110 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3407 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3111 3408
3112 GridInstantMessage msg = new GridInstantMessage(); 3409 GridInstantMessage msg = new GridInstantMessage();
3113 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3410 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3114 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3411 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3115 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3412 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3116// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3413// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3117// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3414// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3118 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3415// DateTime dt = DateTime.UtcNow;
3416//
3417// // Ticks from UtcNow, but make it look like local. Evil, huh?
3418// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3419//
3420// try
3421// {
3422// // Convert that to the PST timezone
3423// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3424// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3425// }
3426// catch
3427// {
3428// // No logging here, as it could be VERY spammy
3429// }
3430//
3431// // And make it look local again to fool the unix time util
3432// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3433
3434 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3435
3119 //if (client != null) 3436 //if (client != null)
3120 //{ 3437 //{
3121 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3438 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3129,12 +3446,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3129 msg.message = message.Substring(0, 1024); 3446 msg.message = message.Substring(0, 1024);
3130 else 3447 else
3131 msg.message = message; 3448 msg.message = message;
3132 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3449 msg.dialog = (byte)19; // MessageFromObject
3133 msg.fromGroup = false;// fromGroup; 3450 msg.fromGroup = false;// fromGroup;
3134 msg.offline = (byte)0; //offline; 3451 msg.offline = (byte)0; //offline;
3135 msg.ParentEstateID = 0; //ParentEstateID; 3452 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3136 msg.Position = new Vector3(m_host.AbsolutePosition); 3453 msg.Position = new Vector3(m_host.AbsolutePosition);
3137 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3454 msg.RegionID = World.RegionInfo.RegionID.Guid;
3138 msg.binaryBucket 3455 msg.binaryBucket
3139 = Util.StringToBytes256( 3456 = Util.StringToBytes256(
3140 "{0}/{1}/{2}/{3}", 3457 "{0}/{1}/{2}/{3}",
@@ -3162,7 +3479,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3162 } 3479 }
3163 3480
3164 emailModule.SendEmail(m_host.UUID, address, subject, message); 3481 emailModule.SendEmail(m_host.UUID, address, subject, message);
3165 llSleep(EMAIL_PAUSE_TIME); 3482 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3166 } 3483 }
3167 3484
3168 public void llGetNextEmail(string address, string subject) 3485 public void llGetNextEmail(string address, string subject)
@@ -3408,7 +3725,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3408 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3725 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3409 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3726 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3410 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3727 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3728 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3411 ScriptBaseClass.PERMISSION_ATTACH; 3729 ScriptBaseClass.PERMISSION_ATTACH;
3730
3412 } 3731 }
3413 else 3732 else
3414 { 3733 {
@@ -3425,15 +3744,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3425 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3744 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3426 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3745 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3427 } 3746 }
3747 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3748 {
3749 implicitPerms = perm;
3750 }
3428 } 3751 }
3429 3752
3430 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3753 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3431 { 3754 {
3432 lock (m_host.TaskInventory) 3755 m_host.TaskInventory.LockItemsForWrite(true);
3433 { 3756 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3434 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3757 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3435 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3758 m_host.TaskInventory.LockItemsForWrite(false);
3436 }
3437 3759
3438 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3760 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3439 "run_time_permissions", new Object[] { 3761 "run_time_permissions", new Object[] {
@@ -3476,11 +3798,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3476 3798
3477 if (!m_waitingForScriptAnswer) 3799 if (!m_waitingForScriptAnswer)
3478 { 3800 {
3479 lock (m_host.TaskInventory) 3801 m_host.TaskInventory.LockItemsForWrite(true);
3480 { 3802 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3481 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3803 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3482 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3804 m_host.TaskInventory.LockItemsForWrite(false);
3483 }
3484 3805
3485 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3806 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3486 m_waitingForScriptAnswer=true; 3807 m_waitingForScriptAnswer=true;
@@ -3509,14 +3830,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3509 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3830 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3510 llReleaseControls(); 3831 llReleaseControls();
3511 3832
3512 lock (m_host.TaskInventory) 3833 m_host.TaskInventory.LockItemsForWrite(true);
3513 { 3834 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3514 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3835 m_host.TaskInventory.LockItemsForWrite(false);
3515 } 3836
3516 3837 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3517 m_ScriptEngine.PostScriptEvent( 3838 "run_time_permissions", new Object[] {
3518 m_item.ItemID, 3839 new LSL_Integer(answer) },
3519 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3840 new DetectParams[0]));
3520 } 3841 }
3521 3842
3522 public LSL_String llGetPermissionsKey() 3843 public LSL_String llGetPermissionsKey()
@@ -3555,14 +3876,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3555 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3876 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3556 { 3877 {
3557 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3878 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3558 3879 if (parts.Count > 0)
3559 foreach (SceneObjectPart part in parts) 3880 {
3560 part.SetFaceColorAlpha(face, color, null); 3881 try
3882 {
3883 foreach (SceneObjectPart part in parts)
3884 part.SetFaceColorAlpha(face, color, null);
3885 }
3886 finally
3887 {
3888 }
3889 }
3561 } 3890 }
3562 3891
3563 public void llCreateLink(string target, int parent) 3892 public void llCreateLink(string target, int parent)
3564 { 3893 {
3565 m_host.AddScriptLPS(1); 3894 m_host.AddScriptLPS(1);
3895
3566 UUID targetID; 3896 UUID targetID;
3567 3897
3568 if (!UUID.TryParse(target, out targetID)) 3898 if (!UUID.TryParse(target, out targetID))
@@ -3668,10 +3998,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3668 // Restructuring Multiple Prims. 3998 // Restructuring Multiple Prims.
3669 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3999 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3670 parts.Remove(parentPrim.RootPart); 4000 parts.Remove(parentPrim.RootPart);
3671 foreach (SceneObjectPart part in parts) 4001 if (parts.Count > 0)
3672 { 4002 {
3673 parentPrim.DelinkFromGroup(part.LocalId, true); 4003 try
4004 {
4005 foreach (SceneObjectPart part in parts)
4006 {
4007 parentPrim.DelinkFromGroup(part.LocalId, true);
4008 }
4009 }
4010 finally
4011 {
4012 }
3674 } 4013 }
4014
3675 parentPrim.HasGroupChanged = true; 4015 parentPrim.HasGroupChanged = true;
3676 parentPrim.ScheduleGroupForFullUpdate(); 4016 parentPrim.ScheduleGroupForFullUpdate();
3677 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4017 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3680,12 +4020,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3680 { 4020 {
3681 SceneObjectPart newRoot = parts[0]; 4021 SceneObjectPart newRoot = parts[0];
3682 parts.Remove(newRoot); 4022 parts.Remove(newRoot);
3683 foreach (SceneObjectPart part in parts) 4023
4024 try
3684 { 4025 {
3685 // Required for linking 4026 foreach (SceneObjectPart part in parts)
3686 part.ClearUpdateSchedule(); 4027 {
3687 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4028 part.ClearUpdateSchedule();
4029 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4030 }
3688 } 4031 }
4032 finally
4033 {
4034 }
4035
4036
3689 newRoot.ParentGroup.HasGroupChanged = true; 4037 newRoot.ParentGroup.HasGroupChanged = true;
3690 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4038 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3691 } 4039 }
@@ -3705,6 +4053,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3705 public void llBreakAllLinks() 4053 public void llBreakAllLinks()
3706 { 4054 {
3707 m_host.AddScriptLPS(1); 4055 m_host.AddScriptLPS(1);
4056
4057 TaskInventoryItem item = m_item;
4058
4059 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4060 && !m_automaticLinkPermission)
4061 {
4062 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4063 return;
4064 }
4065
3708 SceneObjectGroup parentPrim = m_host.ParentGroup; 4066 SceneObjectGroup parentPrim = m_host.ParentGroup;
3709 if (parentPrim.AttachmentPoint != 0) 4067 if (parentPrim.AttachmentPoint != 0)
3710 return; // Fail silently if attached 4068 return; // Fail silently if attached
@@ -3724,47 +4082,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3724 public LSL_String llGetLinkKey(int linknum) 4082 public LSL_String llGetLinkKey(int linknum)
3725 { 4083 {
3726 m_host.AddScriptLPS(1); 4084 m_host.AddScriptLPS(1);
3727 4085 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3728 if (linknum < 0) 4086 if (part != null)
3729 {
3730 if (linknum == ScriptBaseClass.LINK_THIS)
3731 return m_host.UUID.ToString();
3732 else
3733 return ScriptBaseClass.NULL_KEY;
3734 }
3735
3736 int actualPrimCount = m_host.ParentGroup.PrimCount;
3737 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
3738 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
3739
3740 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
3741 // prim that has any avatars sat upon it (in which case the root prim is link 1).
3742 if (linknum == 0)
3743 {
3744 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
3745 return m_host.UUID.ToString();
3746
3747 return ScriptBaseClass.NULL_KEY;
3748 }
3749 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
3750 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
3751 else if (linknum == 1 && actualPrimCount == 1)
3752 {
3753 if (sittingAvatarIds.Count > 0)
3754 return m_host.ParentGroup.RootPart.UUID.ToString();
3755 else
3756 return ScriptBaseClass.NULL_KEY;
3757 }
3758 else if (linknum <= adjustedPrimCount)
3759 { 4087 {
3760 if (linknum <= actualPrimCount) 4088 return part.UUID.ToString();
3761 return m_host.ParentGroup.GetLinkNumPart(linknum).UUID.ToString();
3762 else
3763 return sittingAvatarIds[linknum - actualPrimCount - 1].ToString();
3764 } 4089 }
3765 else 4090 else
3766 { 4091 {
3767 return ScriptBaseClass.NULL_KEY; 4092 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4093 {
4094 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4095
4096 if (linknum < 0)
4097 return UUID.Zero.ToString();
4098
4099 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4100 if (avatars.Count > linknum)
4101 {
4102 return avatars[linknum].UUID.ToString();
4103 }
4104 }
4105 return UUID.Zero.ToString();
3768 } 4106 }
3769 } 4107 }
3770 4108
@@ -3867,17 +4205,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3867 m_host.AddScriptLPS(1); 4205 m_host.AddScriptLPS(1);
3868 int count = 0; 4206 int count = 0;
3869 4207
3870 lock (m_host.TaskInventory) 4208 m_host.TaskInventory.LockItemsForRead(true);
4209 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3871 { 4210 {
3872 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4211 if (inv.Value.Type == type || type == -1)
3873 { 4212 {
3874 if (inv.Value.Type == type || type == -1) 4213 count = count + 1;
3875 {
3876 count = count + 1;
3877 }
3878 } 4214 }
3879 } 4215 }
3880 4216
4217 m_host.TaskInventory.LockItemsForRead(false);
3881 return count; 4218 return count;
3882 } 4219 }
3883 4220
@@ -3886,16 +4223,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3886 m_host.AddScriptLPS(1); 4223 m_host.AddScriptLPS(1);
3887 ArrayList keys = new ArrayList(); 4224 ArrayList keys = new ArrayList();
3888 4225
3889 lock (m_host.TaskInventory) 4226 m_host.TaskInventory.LockItemsForRead(true);
4227 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3890 { 4228 {
3891 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4229 if (inv.Value.Type == type || type == -1)
3892 { 4230 {
3893 if (inv.Value.Type == type || type == -1) 4231 keys.Add(inv.Value.Name);
3894 {
3895 keys.Add(inv.Value.Name);
3896 }
3897 } 4232 }
3898 } 4233 }
4234 m_host.TaskInventory.LockItemsForRead(false);
3899 4235
3900 if (keys.Count == 0) 4236 if (keys.Count == 0)
3901 { 4237 {
@@ -3933,7 +4269,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3933 if (item == null) 4269 if (item == null)
3934 { 4270 {
3935 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4271 llSay(0, String.Format("Could not find object '{0}'", inventory));
3936 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4272 return;
4273// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3937 } 4274 }
3938 4275
3939 UUID objId = item.ItemID; 4276 UUID objId = item.ItemID;
@@ -3961,33 +4298,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3961 return; 4298 return;
3962 } 4299 }
3963 } 4300 }
4301
3964 // destination is an avatar 4302 // destination is an avatar
3965 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4303 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3966 4304
3967 if (agentItem == null) 4305 if (agentItem == null)
3968 return; 4306 return;
3969 4307
3970 if (m_TransferModule != null) 4308 byte[] bucket = new byte[1];
3971 { 4309 bucket[0] = (byte)item.Type;
3972 byte[] bucket = new byte[1]; 4310 //byte[] objBytes = agentItem.ID.GetBytes();
3973 bucket[0] = (byte)item.Type; 4311 //Array.Copy(objBytes, 0, bucket, 1, 16);
3974 4312
3975 GridInstantMessage msg = new GridInstantMessage(World, 4313 GridInstantMessage msg = new GridInstantMessage(World,
3976 m_host.OwnerID, m_host.Name, destId, 4314 m_host.OwnerID, m_host.Name, destId,
3977 (byte)InstantMessageDialog.TaskInventoryOffered, 4315 (byte)InstantMessageDialog.TaskInventoryOffered,
3978 false, item.Name+". "+m_host.Name+" is located at "+ 4316 false, item.Name+". "+m_host.Name+" is located at "+
3979 World.RegionInfo.RegionName+" "+ 4317 World.RegionInfo.RegionName+" "+
3980 m_host.AbsolutePosition.ToString(), 4318 m_host.AbsolutePosition.ToString(),
3981 agentItem.ID, true, m_host.AbsolutePosition, 4319 agentItem.ID, true, m_host.AbsolutePosition,
3982 bucket, true); 4320 bucket, true);
3983 4321
3984 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4322 ScenePresence sp;
3985 }
3986 4323
4324 if (World.TryGetScenePresence(destId, out sp))
4325 {
4326 sp.ControllingClient.SendInstantMessage(msg);
4327 }
4328 else
4329 {
4330 if (m_TransferModule != null)
4331 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4332 }
4333
4334 //This delay should only occur when giving inventory to avatars.
3987 ScriptSleep(3000); 4335 ScriptSleep(3000);
3988 } 4336 }
3989 } 4337 }
3990 4338
4339 [DebuggerNonUserCode]
3991 public void llRemoveInventory(string name) 4340 public void llRemoveInventory(string name)
3992 { 4341 {
3993 m_host.AddScriptLPS(1); 4342 m_host.AddScriptLPS(1);
@@ -4042,109 +4391,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4042 { 4391 {
4043 m_host.AddScriptLPS(1); 4392 m_host.AddScriptLPS(1);
4044 4393
4045 UUID uuid = (UUID)id; 4394 UUID uuid;
4046 PresenceInfo pinfo = null; 4395 if (UUID.TryParse(id, out uuid))
4047 UserAccount account;
4048
4049 UserInfoCacheEntry ce;
4050 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4051 { 4396 {
4052 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4397 PresenceInfo pinfo = null;
4053 if (account == null) 4398 UserAccount account;
4399
4400 UserInfoCacheEntry ce;
4401 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4054 { 4402 {
4055 m_userInfoCache[uuid] = null; // Cache negative 4403 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4056 return UUID.Zero.ToString(); 4404 if (account == null)
4057 } 4405 {
4406 m_userInfoCache[uuid] = null; // Cache negative
4407 return UUID.Zero.ToString();
4408 }
4058 4409
4059 4410
4060 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4411 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4061 if (pinfos != null && pinfos.Length > 0) 4412 if (pinfos != null && pinfos.Length > 0)
4062 {
4063 foreach (PresenceInfo p in pinfos)
4064 { 4413 {
4065 if (p.RegionID != UUID.Zero) 4414 foreach (PresenceInfo p in pinfos)
4066 { 4415 {
4067 pinfo = p; 4416 if (p.RegionID != UUID.Zero)
4417 {
4418 pinfo = p;
4419 }
4068 } 4420 }
4069 } 4421 }
4070 }
4071 4422
4072 ce = new UserInfoCacheEntry(); 4423 ce = new UserInfoCacheEntry();
4073 ce.time = Util.EnvironmentTickCount(); 4424 ce.time = Util.EnvironmentTickCount();
4074 ce.account = account; 4425 ce.account = account;
4075 ce.pinfo = pinfo; 4426 ce.pinfo = pinfo;
4076 } 4427 m_userInfoCache[uuid] = ce;
4077 else 4428 }
4078 { 4429 else
4079 if (ce == null) 4430 {
4080 return UUID.Zero.ToString(); 4431 if (ce == null)
4432 return UUID.Zero.ToString();
4081 4433
4082 account = ce.account; 4434 account = ce.account;
4083 pinfo = ce.pinfo; 4435 pinfo = ce.pinfo;
4084 } 4436 }
4085 4437
4086 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4438 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4087 {
4088 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4089 if (pinfos != null && pinfos.Length > 0)
4090 { 4439 {
4091 foreach (PresenceInfo p in pinfos) 4440 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4441 if (pinfos != null && pinfos.Length > 0)
4092 { 4442 {
4093 if (p.RegionID != UUID.Zero) 4443 foreach (PresenceInfo p in pinfos)
4094 { 4444 {
4095 pinfo = p; 4445 if (p.RegionID != UUID.Zero)
4446 {
4447 pinfo = p;
4448 }
4096 } 4449 }
4097 } 4450 }
4098 } 4451 else
4099 else 4452 pinfo = null;
4100 pinfo = null;
4101 4453
4102 ce.time = Util.EnvironmentTickCount(); 4454 ce.time = Util.EnvironmentTickCount();
4103 ce.pinfo = pinfo; 4455 ce.pinfo = pinfo;
4104 } 4456 }
4105 4457
4106 string reply = String.Empty; 4458 string reply = String.Empty;
4107 4459
4108 switch (data) 4460 switch (data)
4109 { 4461 {
4110 case 1: // DATA_ONLINE (0|1) 4462 case 1: // DATA_ONLINE (0|1)
4111 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4463 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4112 reply = "1"; 4464 reply = "1";
4113 else 4465 else
4114 reply = "0"; 4466 reply = "0";
4115 break; 4467 break;
4116 case 2: // DATA_NAME (First Last) 4468 case 2: // DATA_NAME (First Last)
4117 reply = account.FirstName + " " + account.LastName; 4469 reply = account.FirstName + " " + account.LastName;
4118 break; 4470 break;
4119 case 3: // DATA_BORN (YYYY-MM-DD) 4471 case 3: // DATA_BORN (YYYY-MM-DD)
4120 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4472 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4121 born = born.AddSeconds(account.Created); 4473 born = born.AddSeconds(account.Created);
4122 reply = born.ToString("yyyy-MM-dd"); 4474 reply = born.ToString("yyyy-MM-dd");
4123 break; 4475 break;
4124 case 4: // DATA_RATING (0,0,0,0,0,0) 4476 case 4: // DATA_RATING (0,0,0,0,0,0)
4125 reply = "0,0,0,0,0,0"; 4477 reply = "0,0,0,0,0,0";
4126 break; 4478 break;
4127 case 7: // DATA_USERLEVEL (integer) 4479 case 8: // DATA_PAYINFO (0|1|2|3)
4128 reply = account.UserLevel.ToString(); 4480 reply = "0";
4129 break; 4481 break;
4130 case 8: // DATA_PAYINFO (0|1|2|3) 4482 default:
4131 reply = "0"; 4483 return UUID.Zero.ToString(); // Raise no event
4132 break; 4484 }
4133 default:
4134 return UUID.Zero.ToString(); // Raise no event
4135 }
4136 4485
4137 UUID rq = UUID.Random(); 4486 UUID rq = UUID.Random();
4138 4487
4139 UUID tid = AsyncCommands. 4488 UUID tid = AsyncCommands.
4140 DataserverPlugin.RegisterRequest(m_host.LocalId, 4489 DataserverPlugin.RegisterRequest(m_host.LocalId,
4141 m_item.ItemID, rq.ToString()); 4490 m_item.ItemID, rq.ToString());
4142 4491
4143 AsyncCommands. 4492 AsyncCommands.
4144 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4493 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4145 4494
4146 ScriptSleep(100); 4495 ScriptSleep(100);
4147 return tid.ToString(); 4496 return tid.ToString();
4497 }
4498 else
4499 {
4500 ShoutError("Invalid UUID passed to llRequestAgentData.");
4501 }
4502 return "";
4148 } 4503 }
4149 4504
4150 public LSL_String llRequestInventoryData(string name) 4505 public LSL_String llRequestInventoryData(string name)
@@ -4201,13 +4556,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4201 if (UUID.TryParse(agent, out agentId)) 4556 if (UUID.TryParse(agent, out agentId))
4202 { 4557 {
4203 ScenePresence presence = World.GetScenePresence(agentId); 4558 ScenePresence presence = World.GetScenePresence(agentId);
4204 if (presence != null) 4559 if (presence != null && presence.PresenceType != PresenceType.Npc)
4205 { 4560 {
4561 // agent must not be a god
4562 if (presence.UserLevel >= 200) return;
4563
4206 // agent must be over the owners land 4564 // agent must be over the owners land
4207 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4565 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4208 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4566 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4209 { 4567 {
4210 World.TeleportClientHome(agentId, presence.ControllingClient); 4568 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4569 {
4570 // They can't be teleported home for some reason
4571 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4572 if (regionInfo != null)
4573 {
4574 World.RequestTeleportLocation(
4575 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4576 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4577 }
4578 }
4211 } 4579 }
4212 } 4580 }
4213 } 4581 }
@@ -4314,7 +4682,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4314 UUID av = new UUID(); 4682 UUID av = new UUID();
4315 if (!UUID.TryParse(agent,out av)) 4683 if (!UUID.TryParse(agent,out av))
4316 { 4684 {
4317 LSLError("First parameter to llDialog needs to be a key"); 4685 //LSLError("First parameter to llDialog needs to be a key");
4318 return; 4686 return;
4319 } 4687 }
4320 4688
@@ -4346,10 +4714,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4346 public void llCollisionSound(string impact_sound, double impact_volume) 4714 public void llCollisionSound(string impact_sound, double impact_volume)
4347 { 4715 {
4348 m_host.AddScriptLPS(1); 4716 m_host.AddScriptLPS(1);
4349 4717
4718 if(impact_sound == "")
4719 {
4720 m_host.CollisionSoundVolume = (float)impact_volume;
4721 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4722 m_host.CollisionSoundType = 0;
4723 return;
4724 }
4350 // TODO: Parameter check logic required. 4725 // TODO: Parameter check logic required.
4351 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4726 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound);
4352 m_host.CollisionSoundVolume = (float)impact_volume; 4727 m_host.CollisionSoundVolume = (float)impact_volume;
4728 m_host.CollisionSoundType = 1;
4353 } 4729 }
4354 4730
4355 public LSL_String llGetAnimation(string id) 4731 public LSL_String llGetAnimation(string id)
@@ -4363,14 +4739,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4363 4739
4364 if (m_host.RegionHandle == presence.RegionHandle) 4740 if (m_host.RegionHandle == presence.RegionHandle)
4365 { 4741 {
4366 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4367
4368 if (presence != null) 4742 if (presence != null)
4369 { 4743 {
4370 AnimationSet currentAnims = presence.Animator.Animations; 4744 if (presence.SitGround)
4371 string currentAnimationState = String.Empty; 4745 return "Sitting on Ground";
4372 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4746 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4373 return currentAnimationState; 4747 return "Sitting";
4748
4749 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4750 string lslMovementAnimation;
4751
4752 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4753 return lslMovementAnimation;
4374 } 4754 }
4375 } 4755 }
4376 4756
@@ -4517,7 +4897,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4517 { 4897 {
4518 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4898 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4519 float distance_term = distance * distance * distance; // Script Energy 4899 float distance_term = distance * distance * distance; // Script Energy
4520 float pusher_mass = m_host.GetMass(); 4900 // use total object mass and not part
4901 float pusher_mass = m_host.ParentGroup.GetMass();
4521 4902
4522 float PUSH_ATTENUATION_DISTANCE = 17f; 4903 float PUSH_ATTENUATION_DISTANCE = 17f;
4523 float PUSH_ATTENUATION_SCALE = 5f; 4904 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4767,6 +5148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4767 { 5148 {
4768 return item.AssetID.ToString(); 5149 return item.AssetID.ToString();
4769 } 5150 }
5151 m_host.TaskInventory.LockItemsForRead(false);
4770 5152
4771 return UUID.Zero.ToString(); 5153 return UUID.Zero.ToString();
4772 } 5154 }
@@ -4900,7 +5282,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4900 public LSL_Vector llGetCenterOfMass() 5282 public LSL_Vector llGetCenterOfMass()
4901 { 5283 {
4902 m_host.AddScriptLPS(1); 5284 m_host.AddScriptLPS(1);
4903 Vector3 center = m_host.GetGeometricCenter(); 5285 Vector3 center = m_host.GetCenterOfMass();
4904 return new LSL_Vector(center.X,center.Y,center.Z); 5286 return new LSL_Vector(center.X,center.Y,center.Z);
4905 } 5287 }
4906 5288
@@ -4919,14 +5301,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4919 { 5301 {
4920 m_host.AddScriptLPS(1); 5302 m_host.AddScriptLPS(1);
4921 5303
4922 if (src == null) 5304 return src.Length;
4923 {
4924 return 0;
4925 }
4926 else
4927 {
4928 return src.Length;
4929 }
4930 } 5305 }
4931 5306
4932 public LSL_Integer llList2Integer(LSL_List src, int index) 5307 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4997,7 +5372,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4997 else if (src.Data[index] is LSL_Float) 5372 else if (src.Data[index] is LSL_Float)
4998 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5373 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4999 else if (src.Data[index] is LSL_String) 5374 else if (src.Data[index] is LSL_String)
5000 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5375 {
5376 string str = ((LSL_String) src.Data[index]).m_string;
5377 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5378 if (m != Match.Empty)
5379 {
5380 str = m.Value;
5381 double d = 0.0;
5382 if (!Double.TryParse(str, out d))
5383 return 0.0;
5384
5385 return d;
5386 }
5387 return 0.0;
5388 }
5001 return Convert.ToDouble(src.Data[index]); 5389 return Convert.ToDouble(src.Data[index]);
5002 } 5390 }
5003 catch (FormatException) 5391 catch (FormatException)
@@ -5039,7 +5427,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5039 // for completion and should LSL_Key ever be implemented 5427 // for completion and should LSL_Key ever be implemented
5040 // as it's own struct 5428 // as it's own struct
5041 else if (!(src.Data[index] is LSL_String || 5429 else if (!(src.Data[index] is LSL_String ||
5042 src.Data[index] is LSL_Key)) 5430 src.Data[index] is LSL_Key ||
5431 src.Data[index] is String))
5043 { 5432 {
5044 return ""; 5433 return "";
5045 } 5434 }
@@ -5297,7 +5686,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5297 } 5686 }
5298 } 5687 }
5299 } 5688 }
5300 else { 5689 else
5690 {
5301 object[] array = new object[src.Length]; 5691 object[] array = new object[src.Length];
5302 Array.Copy(src.Data, 0, array, 0, src.Length); 5692 Array.Copy(src.Data, 0, array, 0, src.Length);
5303 result = new LSL_List(array); 5693 result = new LSL_List(array);
@@ -5404,7 +5794,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5404 public LSL_Integer llGetRegionAgentCount() 5794 public LSL_Integer llGetRegionAgentCount()
5405 { 5795 {
5406 m_host.AddScriptLPS(1); 5796 m_host.AddScriptLPS(1);
5407 return new LSL_Integer(World.GetRootAgentCount()); 5797
5798 int count = 0;
5799 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5800 count++;
5801 });
5802
5803 return new LSL_Integer(count);
5408 } 5804 }
5409 5805
5410 public LSL_Vector llGetRegionCorner() 5806 public LSL_Vector llGetRegionCorner()
@@ -5645,6 +6041,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5645 flags |= ScriptBaseClass.AGENT_AWAY; 6041 flags |= ScriptBaseClass.AGENT_AWAY;
5646 } 6042 }
5647 6043
6044 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6045 UUID[] anims = agent.Animator.GetAnimationArray();
6046 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6047 {
6048 flags |= ScriptBaseClass.AGENT_BUSY;
6049 }
6050
5648 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6051 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5649 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6052 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5650 { 6053 {
@@ -5692,6 +6095,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5692 flags |= ScriptBaseClass.AGENT_SITTING; 6095 flags |= ScriptBaseClass.AGENT_SITTING;
5693 } 6096 }
5694 6097
6098 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6099 {
6100 flags |= ScriptBaseClass.AGENT_MALE;
6101 }
6102
5695 return flags; 6103 return flags;
5696 } 6104 }
5697 6105
@@ -5839,9 +6247,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5839 6247
5840 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6248 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5841 6249
5842 foreach (SceneObjectPart part in parts) 6250 try
6251 {
6252 foreach (SceneObjectPart part in parts)
6253 {
6254 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6255 }
6256 }
6257 finally
5843 { 6258 {
5844 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5845 } 6259 }
5846 } 6260 }
5847 6261
@@ -5895,13 +6309,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5895 6309
5896 if (m_host.OwnerID == land.LandData.OwnerID) 6310 if (m_host.OwnerID == land.LandData.OwnerID)
5897 { 6311 {
5898 World.TeleportClientHome(agentID, presence.ControllingClient); 6312 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6313 presence.TeleportWithMomentum(pos, null);
6314 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5899 } 6315 }
5900 } 6316 }
5901 } 6317 }
5902 ScriptSleep(5000); 6318 ScriptSleep(5000);
5903 } 6319 }
5904 6320
6321 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6322 {
6323 return ParseString2List(str, separators, in_spacers, false);
6324 }
6325
5905 public LSL_Integer llOverMyLand(string id) 6326 public LSL_Integer llOverMyLand(string id)
5906 { 6327 {
5907 m_host.AddScriptLPS(1); 6328 m_host.AddScriptLPS(1);
@@ -5955,25 +6376,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5955 } 6376 }
5956 else 6377 else
5957 { 6378 {
5958 agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); 6379// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6380 Vector3 s = avatar.Appearance.AvatarSize;
6381 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5959 } 6382 }
5960 return agentSize; 6383 return agentSize;
5961 } 6384 }
5962 6385
5963 public LSL_Integer llSameGroup(string agent) 6386 public LSL_Integer llSameGroup(string id)
5964 { 6387 {
5965 m_host.AddScriptLPS(1); 6388 m_host.AddScriptLPS(1);
5966 UUID agentId = new UUID(); 6389 UUID uuid = new UUID();
5967 if (!UUID.TryParse(agent, out agentId)) 6390 if (!UUID.TryParse(id, out uuid))
5968 return new LSL_Integer(0);
5969 ScenePresence presence = World.GetScenePresence(agentId);
5970 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5971 return new LSL_Integer(0); 6391 return new LSL_Integer(0);
5972 IClientAPI client = presence.ControllingClient; 6392
5973 if (m_host.GroupID == client.ActiveGroupId) 6393 // Check if it's a group key
6394 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5974 return new LSL_Integer(1); 6395 return new LSL_Integer(1);
5975 else 6396
6397 // We got passed a UUID.Zero
6398 if (uuid == UUID.Zero)
5976 return new LSL_Integer(0); 6399 return new LSL_Integer(0);
6400
6401 // Handle the case where id names an avatar
6402 ScenePresence presence = World.GetScenePresence(uuid);
6403 if (presence != null)
6404 {
6405 if (presence.IsChildAgent)
6406 return new LSL_Integer(0);
6407
6408 IClientAPI client = presence.ControllingClient;
6409 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6410 return new LSL_Integer(1);
6411
6412 return new LSL_Integer(0);
6413 }
6414
6415 // Handle object case
6416 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6417 if (part != null)
6418 {
6419 // This will handle both deed and non-deed and also the no
6420 // group case
6421 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6422 return new LSL_Integer(1);
6423
6424 return new LSL_Integer(0);
6425 }
6426
6427 return new LSL_Integer(0);
5977 } 6428 }
5978 6429
5979 public void llUnSit(string id) 6430 public void llUnSit(string id)
@@ -6098,7 +6549,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6098 return m_host.ParentGroup.AttachmentPoint; 6549 return m_host.ParentGroup.AttachmentPoint;
6099 } 6550 }
6100 6551
6101 public LSL_Integer llGetFreeMemory() 6552 public virtual LSL_Integer llGetFreeMemory()
6102 { 6553 {
6103 m_host.AddScriptLPS(1); 6554 m_host.AddScriptLPS(1);
6104 // Make scripts designed for LSO happy 6555 // Make scripts designed for LSO happy
@@ -6530,6 +6981,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6530 6981
6531 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6982 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6532 { 6983 {
6984 // LSL quaternions can normalize to 0, normal Quaternions can't.
6985 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6986 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6987
6533 part.SitTargetPosition = offset; 6988 part.SitTargetPosition = offset;
6534 part.SitTargetOrientation = rot; 6989 part.SitTargetOrientation = rot;
6535 part.ParentGroup.HasGroupChanged = true; 6990 part.ParentGroup.HasGroupChanged = true;
@@ -6715,13 +7170,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6715 UUID av = new UUID(); 7170 UUID av = new UUID();
6716 if (!UUID.TryParse(avatar,out av)) 7171 if (!UUID.TryParse(avatar,out av))
6717 { 7172 {
6718 LSLError("First parameter to llDialog needs to be a key"); 7173 //LSLError("First parameter to llDialog needs to be a key");
6719 return; 7174 return;
6720 } 7175 }
6721 if (buttons.Length < 1) 7176 if (buttons.Length < 1)
6722 { 7177 {
6723 LSLError("No less than 1 button can be shown"); 7178 buttons.Add("OK");
6724 return;
6725 } 7179 }
6726 if (buttons.Length > 12) 7180 if (buttons.Length > 12)
6727 { 7181 {
@@ -6738,7 +7192,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6738 } 7192 }
6739 if (buttons.Data[i].ToString().Length > 24) 7193 if (buttons.Data[i].ToString().Length > 24)
6740 { 7194 {
6741 LSLError("button label cannot be longer than 24 characters"); 7195 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6742 return; 7196 return;
6743 } 7197 }
6744 buts[i] = buttons.Data[i].ToString(); 7198 buts[i] = buttons.Data[i].ToString();
@@ -6805,9 +7259,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6805 return; 7259 return;
6806 } 7260 }
6807 7261
6808 // the rest of the permission checks are done in RezScript, so check the pin there as well 7262 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6809 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7263 if (dest != null)
7264 {
7265 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7266 {
7267 // the rest of the permission checks are done in RezScript, so check the pin there as well
7268 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6810 7269
7270 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7271 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7272 }
7273 }
6811 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7274 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6812 ScriptSleep(3000); 7275 ScriptSleep(3000);
6813 } 7276 }
@@ -6877,19 +7340,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6877 public LSL_String llMD5String(string src, int nonce) 7340 public LSL_String llMD5String(string src, int nonce)
6878 { 7341 {
6879 m_host.AddScriptLPS(1); 7342 m_host.AddScriptLPS(1);
6880 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7343 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6881 } 7344 }
6882 7345
6883 public LSL_String llSHA1String(string src) 7346 public LSL_String llSHA1String(string src)
6884 { 7347 {
6885 m_host.AddScriptLPS(1); 7348 m_host.AddScriptLPS(1);
6886 return Util.SHA1Hash(src).ToLower(); 7349 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6887 } 7350 }
6888 7351
6889 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7352 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6890 { 7353 {
6891 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7354 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6892 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7355 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7356 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7357 return shapeBlock;
6893 7358
6894 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7359 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6895 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7360 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6994,6 +7459,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6994 // Prim type box, cylinder and prism. 7459 // Prim type box, cylinder and prism.
6995 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) 7460 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)
6996 { 7461 {
7462 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7463 return;
7464
6997 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7465 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6998 ObjectShapePacket.ObjectDataBlock shapeBlock; 7466 ObjectShapePacket.ObjectDataBlock shapeBlock;
6999 7467
@@ -7047,6 +7515,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7047 // Prim type sphere. 7515 // Prim type sphere.
7048 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7516 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7049 { 7517 {
7518 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7519 return;
7520
7050 ObjectShapePacket.ObjectDataBlock shapeBlock; 7521 ObjectShapePacket.ObjectDataBlock shapeBlock;
7051 7522
7052 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7523 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7088,6 +7559,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7088 // Prim type torus, tube and ring. 7559 // Prim type torus, tube and ring.
7089 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) 7560 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)
7090 { 7561 {
7562 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7563 return;
7564
7091 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7565 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7092 ObjectShapePacket.ObjectDataBlock shapeBlock; 7566 ObjectShapePacket.ObjectDataBlock shapeBlock;
7093 7567
@@ -7223,6 +7697,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7223 // Prim type sculpt. 7697 // Prim type sculpt.
7224 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7698 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7225 { 7699 {
7700 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7701 return;
7702
7226 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7703 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7227 UUID sculptId; 7704 UUID sculptId;
7228 7705
@@ -7247,7 +7724,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7247 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7724 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7248 { 7725 {
7249 // default 7726 // default
7250 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7727 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7251 } 7728 }
7252 7729
7253 part.Shape.SetSculptProperties((byte)type, sculptId); 7730 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7264,48 +7741,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7264 ScriptSleep(200); 7741 ScriptSleep(200);
7265 } 7742 }
7266 7743
7267 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7744 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7268 { 7745 {
7269 m_host.AddScriptLPS(1); 7746 m_host.AddScriptLPS(1);
7270 7747
7271 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7748 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7272 7749
7273 ScriptSleep(200); 7750 ScriptSleep(200);
7274 } 7751 }
7275 7752
7276 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7753 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7277 { 7754 {
7278 m_host.AddScriptLPS(1); 7755 List<object> parts = new List<object>();
7756 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7757 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7758 foreach (SceneObjectPart p in prims)
7759 parts.Add(p);
7760 foreach (ScenePresence p in avatars)
7761 parts.Add(p);
7279 7762
7280 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7763 LSL_List remaining = null;
7764 uint rulesParsed = 0;
7765
7766 if (parts.Count > 0)
7767 {
7768 foreach (object part in parts)
7769 {
7770 if (part is SceneObjectPart)
7771 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7772 else
7773 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7774 }
7775
7776 while ((object)remaining != null && remaining.Length > 2)
7777 {
7778 linknumber = remaining.GetLSLIntegerItem(0);
7779 rules = remaining.GetSublist(1, -1);
7780 parts.Clear();
7781 prims = GetLinkParts(linknumber);
7782 avatars = GetLinkAvatars(linknumber);
7783 foreach (SceneObjectPart p in prims)
7784 parts.Add(p);
7785 foreach (ScenePresence p in avatars)
7786 parts.Add(p);
7787
7788 remaining = null;
7789 foreach (object part in parts)
7790 {
7791 if (part is SceneObjectPart)
7792 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7793 else
7794 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7795 }
7796 }
7797 }
7281 } 7798 }
7282 7799
7283 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7800 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7801 float material_density, float material_friction,
7802 float material_restitution, float material_gravity_modifier)
7284 { 7803 {
7285 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7804 ExtraPhysicsData physdata = new ExtraPhysicsData();
7805 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7806 physdata.Density = part.Density;
7807 physdata.Friction = part.Friction;
7808 physdata.Bounce = part.Bounciness;
7809 physdata.GravitationModifier = part.GravityModifier;
7286 7810
7287 LSL_List remaining = null; 7811 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7288 uint rulesParsed = 0; 7812 physdata.Density = material_density;
7813 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7814 physdata.Friction = material_friction;
7815 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7816 physdata.Bounce = material_restitution;
7817 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7818 physdata.GravitationModifier = material_gravity_modifier;
7289 7819
7290 foreach (SceneObjectPart part in parts) 7820 part.UpdateExtraPhysics(physdata);
7291 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7821 }
7292 7822
7293 while (remaining != null && remaining.Length > 2) 7823 public void llSetPhysicsMaterial(int material_bits,
7294 { 7824 float material_gravity_modifier, float material_restitution,
7295 linknumber = remaining.GetLSLIntegerItem(0); 7825 float material_friction, float material_density)
7296 rules = remaining.GetSublist(1, -1); 7826 {
7297 parts = GetLinkParts(linknumber); 7827 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7828 }
7298 7829
7299 foreach (SceneObjectPart part in parts) 7830 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7300 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7831 {
7832 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7833 llSetLinkPrimitiveParamsFast(linknumber, rules);
7834 ScriptSleep(200);
7835 }
7836
7837 // vector up using libomv (c&p from sop )
7838 // vector up rotated by r
7839 private Vector3 Zrot(Quaternion r)
7840 {
7841 double x, y, z, m;
7842
7843 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7844 if (Math.Abs(1.0 - m) > 0.000001)
7845 {
7846 m = 1.0 / Math.Sqrt(m);
7847 r.X *= (float)m;
7848 r.Y *= (float)m;
7849 r.Z *= (float)m;
7850 r.W *= (float)m;
7301 } 7851 }
7852
7853 x = 2 * (r.X * r.Z + r.Y * r.W);
7854 y = 2 * (-r.X * r.W + r.Y * r.Z);
7855 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7856
7857 return new Vector3((float)x, (float)y, (float)z);
7302 } 7858 }
7303 7859
7304 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7860 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7305 { 7861 {
7862 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7863 return null;
7864
7306 int idx = 0; 7865 int idx = 0;
7307 int idxStart = 0; 7866 int idxStart = 0;
7308 7867
7868 SceneObjectGroup parentgrp = part.ParentGroup;
7869
7309 bool positionChanged = false; 7870 bool positionChanged = false;
7310 LSL_Vector currentPosition = GetPartLocalPos(part); 7871 LSL_Vector currentPosition = GetPartLocalPos(part);
7311 7872
@@ -7330,8 +7891,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7330 return null; 7891 return null;
7331 7892
7332 v=rules.GetVector3Item(idx++); 7893 v=rules.GetVector3Item(idx++);
7333 positionChanged = true;
7334 currentPosition = GetSetPosTarget(part, v, currentPosition); 7894 currentPosition = GetSetPosTarget(part, v, currentPosition);
7895 positionChanged = true;
7335 7896
7336 break; 7897 break;
7337 case (int)ScriptBaseClass.PRIM_SIZE: 7898 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7608,7 +8169,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7608 return null; 8169 return null;
7609 8170
7610 string ph = rules.Data[idx++].ToString(); 8171 string ph = rules.Data[idx++].ToString();
7611 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8172 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7612 8173
7613 break; 8174 break;
7614 8175
@@ -7626,12 +8187,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7626 part.ScriptSetPhysicsStatus(physics); 8187 part.ScriptSetPhysicsStatus(physics);
7627 break; 8188 break;
7628 8189
8190 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8191 if (remain < 1)
8192 return null;
8193
8194 int shape_type = rules.GetLSLIntegerItem(idx++);
8195
8196 ExtraPhysicsData physdata = new ExtraPhysicsData();
8197 physdata.Density = part.Density;
8198 physdata.Bounce = part.Bounciness;
8199 physdata.GravitationModifier = part.GravityModifier;
8200 physdata.PhysShapeType = (PhysShapeType)shape_type;
8201
8202 part.UpdateExtraPhysics(physdata);
8203
8204 break;
8205
8206 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8207 if (remain < 5)
8208 return null;
8209
8210 int material_bits = rules.GetLSLIntegerItem(idx++);
8211 float material_density = (float)rules.GetLSLFloatItem(idx++);
8212 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8213 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8214 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8215
8216 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8217
8218 break;
8219
7629 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8220 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7630 if (remain < 1) 8221 if (remain < 1)
7631 return null; 8222 return null;
7632 string temp = rules.Data[idx++].ToString(); 8223 string temp = rules.Data[idx++].ToString();
7633 8224
7634 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8225 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7635 8226
7636 break; 8227 break;
7637 8228
@@ -7705,7 +8296,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7705 if (part.ParentGroup.RootPart == part) 8296 if (part.ParentGroup.RootPart == part)
7706 { 8297 {
7707 SceneObjectGroup parent = part.ParentGroup; 8298 SceneObjectGroup parent = part.ParentGroup;
7708 parent.UpdateGroupPosition(currentPosition); 8299 Util.FireAndForget(delegate(object x) {
8300 parent.UpdateGroupPosition(currentPosition);
8301 });
7709 } 8302 }
7710 else 8303 else
7711 { 8304 {
@@ -7750,10 +8343,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7750 8343
7751 public LSL_String llXorBase64Strings(string str1, string str2) 8344 public LSL_String llXorBase64Strings(string str1, string str2)
7752 { 8345 {
7753 m_host.AddScriptLPS(1); 8346 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7754 Deprecated("llXorBase64Strings"); 8347
7755 ScriptSleep(300); 8348 ScriptSleep(300);
7756 return String.Empty; 8349 m_host.AddScriptLPS(1);
8350
8351 if (str1 == String.Empty)
8352 return String.Empty;
8353 if (str2 == String.Empty)
8354 return str1;
8355
8356 int len = str2.Length;
8357 if ((len % 4) != 0) // LL is EVIL!!!!
8358 {
8359 while (str2.EndsWith("="))
8360 str2 = str2.Substring(0, str2.Length - 1);
8361
8362 len = str2.Length;
8363 int mod = len % 4;
8364
8365 if (mod == 1)
8366 str2 = str2.Substring(0, str2.Length - 1);
8367 else if (mod == 2)
8368 str2 += "==";
8369 else if (mod == 3)
8370 str2 += "=";
8371 }
8372
8373 byte[] data1;
8374 byte[] data2;
8375 try
8376 {
8377 data1 = Convert.FromBase64String(str1);
8378 data2 = Convert.FromBase64String(str2);
8379 }
8380 catch (Exception)
8381 {
8382 return new LSL_String(String.Empty);
8383 }
8384
8385 // For cases where the decoded length of s2 is greater
8386 // than the decoded length of s1, simply perform a normal
8387 // decode and XOR
8388 //
8389 if (data2.Length >= data1.Length)
8390 {
8391 for (int pos = 0 ; pos < data1.Length ; pos++ )
8392 data1[pos] ^= data2[pos];
8393
8394 return Convert.ToBase64String(data1);
8395 }
8396
8397 // Remove padding
8398 while (str1.EndsWith("="))
8399 str1 = str1.Substring(0, str1.Length - 1);
8400 while (str2.EndsWith("="))
8401 str2 = str2.Substring(0, str2.Length - 1);
8402
8403 byte[] d1 = new byte[str1.Length];
8404 byte[] d2 = new byte[str2.Length];
8405
8406 for (int i = 0 ; i < str1.Length ; i++)
8407 {
8408 int idx = b64.IndexOf(str1.Substring(i, 1));
8409 if (idx == -1)
8410 idx = 0;
8411 d1[i] = (byte)idx;
8412 }
8413
8414 for (int i = 0 ; i < str2.Length ; i++)
8415 {
8416 int idx = b64.IndexOf(str2.Substring(i, 1));
8417 if (idx == -1)
8418 idx = 0;
8419 d2[i] = (byte)idx;
8420 }
8421
8422 string output = String.Empty;
8423
8424 for (int pos = 0 ; pos < d1.Length ; pos++)
8425 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8426
8427 while (output.Length % 3 > 0)
8428 output += "=";
8429
8430 return output;
7757 } 8431 }
7758 8432
7759 public void llRemoteDataSetRegion() 8433 public void llRemoteDataSetRegion()
@@ -7877,8 +8551,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7877 public LSL_Integer llGetNumberOfPrims() 8551 public LSL_Integer llGetNumberOfPrims()
7878 { 8552 {
7879 m_host.AddScriptLPS(1); 8553 m_host.AddScriptLPS(1);
7880 8554 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7881 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8555
8556 return m_host.ParentGroup.PrimCount + avatarCount;
7882 } 8557 }
7883 8558
7884 /// <summary> 8559 /// <summary>
@@ -7893,55 +8568,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7893 m_host.AddScriptLPS(1); 8568 m_host.AddScriptLPS(1);
7894 UUID objID = UUID.Zero; 8569 UUID objID = UUID.Zero;
7895 LSL_List result = new LSL_List(); 8570 LSL_List result = new LSL_List();
8571
8572 // If the ID is not valid, return null result
7896 if (!UUID.TryParse(obj, out objID)) 8573 if (!UUID.TryParse(obj, out objID))
7897 { 8574 {
7898 result.Add(new LSL_Vector()); 8575 result.Add(new LSL_Vector());
7899 result.Add(new LSL_Vector()); 8576 result.Add(new LSL_Vector());
7900 return result; 8577 return result;
7901 } 8578 }
8579
8580 // Check if this is an attached prim. If so, replace
8581 // the UUID with the avatar UUID and report it's bounding box
8582 SceneObjectPart part = World.GetSceneObjectPart(objID);
8583 if (part != null && part.ParentGroup.IsAttachment)
8584 objID = part.ParentGroup.AttachedAvatar;
8585
8586 // Find out if this is an avatar ID. If so, return it's box
7902 ScenePresence presence = World.GetScenePresence(objID); 8587 ScenePresence presence = World.GetScenePresence(objID);
7903 if (presence != null) 8588 if (presence != null)
7904 { 8589 {
7905 if (presence.ParentID == 0) // not sat on an object 8590 // As per LSL Wiki, there is no difference between sitting
8591 // and standing avatar since server 1.36
8592 LSL_Vector lower;
8593 LSL_Vector upper;
8594
8595 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8596
8597 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8598 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8599/*
7906 { 8600 {
7907 LSL_Vector lower; 8601 // This is for ground sitting avatars
7908 LSL_Vector upper; 8602 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7909 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8603 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7910 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8604 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7911 { 8605 }
7912 // This is for ground sitting avatars 8606 else
7913 float height = presence.Appearance.AvatarHeight / 2.66666667f; 8607 {
7914 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); 8608 // This is for standing/flying avatars
7915 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); 8609 float height = presence.Appearance.AvatarHeight / 2.0f;
7916 } 8610 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7917 else 8611 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7918 { 8612 }
7919 // This is for standing/flying avatars 8613
7920 float height = presence.Appearance.AvatarHeight / 2.0f; 8614 // Adjust to the documented error offsets (see LSL Wiki)
7921 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); 8615 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7922 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); 8616 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7923 } 8617*/
7924 result.Add(lower); 8618 {
7925 result.Add(upper); 8619 // This is for ground sitting avatars TODO!
7926 return result; 8620 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8621 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
7927 } 8622 }
7928 else 8623 else
7929 { 8624 {
7930 // sitting on an object so we need the bounding box of that 8625 // This is for standing/flying avatars
7931 // which should include the avatar so set the UUID to the 8626 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
7932 // UUID of the object the avatar is sat on and allow it to fall through 8627 upper = new LSL_Vector(box.X, box.Y, box.Z);
7933 // to processing an object
7934 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7935 objID = p.UUID;
7936 } 8628 }
8629
8630 if (lower.x > upper.x)
8631 lower.x = upper.x;
8632 if (lower.y > upper.y)
8633 lower.y = upper.y;
8634 if (lower.z > upper.z)
8635 lower.z = upper.z;
8636
8637 result.Add(lower);
8638 result.Add(upper);
8639 return result;
7937 } 8640 }
7938 SceneObjectPart part = World.GetSceneObjectPart(objID); 8641
8642 part = World.GetSceneObjectPart(objID);
7939 // Currently only works for single prims without a sitting avatar 8643 // Currently only works for single prims without a sitting avatar
7940 if (part != null) 8644 if (part != null)
7941 { 8645 {
7942 Vector3 halfSize = part.Scale / 2.0f; 8646 float minX;
7943 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8647 float maxX;
7944 LSL_Vector upper = new LSL_Vector(halfSize); 8648 float minY;
8649 float maxY;
8650 float minZ;
8651 float maxZ;
8652
8653 // This BBox is in sim coordinates, with the offset being
8654 // a contained point.
8655 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8656 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8657
8658 minX -= offsets[0].X;
8659 maxX -= offsets[0].X;
8660 minY -= offsets[0].Y;
8661 maxY -= offsets[0].Y;
8662 minZ -= offsets[0].Z;
8663 maxZ -= offsets[0].Z;
8664
8665 LSL_Vector lower;
8666 LSL_Vector upper;
8667
8668 // Adjust to the documented error offsets (see LSL Wiki)
8669 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8670 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8671
8672 if (lower.x > upper.x)
8673 lower.x = upper.x;
8674 if (lower.y > upper.y)
8675 lower.y = upper.y;
8676 if (lower.z > upper.z)
8677 lower.z = upper.z;
8678
7945 result.Add(lower); 8679 result.Add(lower);
7946 result.Add(upper); 8680 result.Add(upper);
7947 return result; 8681 return result;
@@ -7955,7 +8689,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7955 8689
7956 public LSL_Vector llGetGeometricCenter() 8690 public LSL_Vector llGetGeometricCenter()
7957 { 8691 {
7958 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8692 Vector3 tmp = m_host.GetGeometricCenter();
8693 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7959 } 8694 }
7960 8695
7961 public LSL_List llGetPrimitiveParams(LSL_List rules) 8696 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7983,24 +8718,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7983 { 8718 {
7984 m_host.AddScriptLPS(1); 8719 m_host.AddScriptLPS(1);
7985 8720
7986 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8721 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8722 // keep other options as before
7987 8723
8724 List<SceneObjectPart> parts;
8725 List<ScenePresence> avatars;
8726
7988 LSL_List res = new LSL_List(); 8727 LSL_List res = new LSL_List();
7989 LSL_List remaining = null; 8728 LSL_List remaining = null;
7990 8729
7991 foreach (SceneObjectPart part in parts) 8730 while (rules.Length > 0)
7992 {
7993 remaining = GetPrimParams(part, rules, ref res);
7994 }
7995
7996 while (remaining != null && remaining.Length > 2)
7997 { 8731 {
7998 linknumber = remaining.GetLSLIntegerItem(0);
7999 rules = remaining.GetSublist(1, -1);
8000 parts = GetLinkParts(linknumber); 8732 parts = GetLinkParts(linknumber);
8733 avatars = GetLinkAvatars(linknumber);
8001 8734
8735 remaining = null;
8002 foreach (SceneObjectPart part in parts) 8736 foreach (SceneObjectPart part in parts)
8737 {
8003 remaining = GetPrimParams(part, rules, ref res); 8738 remaining = GetPrimParams(part, rules, ref res);
8739 }
8740 foreach (ScenePresence avatar in avatars)
8741 {
8742 remaining = GetPrimParams(avatar, rules, ref res);
8743 }
8744
8745 if (remaining != null && remaining.Length > 0)
8746 {
8747 linknumber = remaining.GetLSLIntegerItem(0);
8748 rules = remaining.GetSublist(1, -1);
8749 }
8004 } 8750 }
8005 8751
8006 return res; 8752 return res;
@@ -8045,13 +8791,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8045 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8791 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8046 part.AbsolutePosition.Y, 8792 part.AbsolutePosition.Y,
8047 part.AbsolutePosition.Z); 8793 part.AbsolutePosition.Z);
8048 // For some reason, the part.AbsolutePosition.* values do not change if the
8049 // linkset is rotated; they always reflect the child prim's world position
8050 // as though the linkset is unrotated. This is incompatible behavior with SL's
8051 // implementation, so will break scripts imported from there (not to mention it
8052 // makes it more difficult to determine a child prim's actual inworld position).
8053 if (part.ParentID != 0)
8054 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8055 res.Add(v); 8794 res.Add(v);
8056 break; 8795 break;
8057 8796
@@ -8223,30 +8962,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8223 if (remain < 1) 8962 if (remain < 1)
8224 return null; 8963 return null;
8225 8964
8226 face=(int)rules.GetLSLIntegerItem(idx++); 8965 face = (int)rules.GetLSLIntegerItem(idx++);
8227 8966
8228 tex = part.Shape.Textures; 8967 tex = part.Shape.Textures;
8968 int shiny;
8229 if (face == ScriptBaseClass.ALL_SIDES) 8969 if (face == ScriptBaseClass.ALL_SIDES)
8230 { 8970 {
8231 for (face = 0; face < GetNumberOfSides(part); face++) 8971 for (face = 0; face < GetNumberOfSides(part); face++)
8232 { 8972 {
8233 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8973 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8234 // Convert Shininess to PRIM_SHINY_* 8974 if (shinyness == Shininess.High)
8235 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8975 {
8236 // PRIM_BUMP_* 8976 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8237 res.Add(new LSL_Integer((int)texface.Bump)); 8977 }
8978 else if (shinyness == Shininess.Medium)
8979 {
8980 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8981 }
8982 else if (shinyness == Shininess.Low)
8983 {
8984 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8985 }
8986 else
8987 {
8988 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8989 }
8990 res.Add(new LSL_Integer(shiny));
8991 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8238 } 8992 }
8239 } 8993 }
8240 else 8994 else
8241 { 8995 {
8242 if (face >= 0 && face < GetNumberOfSides(part)) 8996 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8997 if (shinyness == Shininess.High)
8243 { 8998 {
8244 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8999 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8245 // Convert Shininess to PRIM_SHINY_* 9000 }
8246 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9001 else if (shinyness == Shininess.Medium)
8247 // PRIM_BUMP_* 9002 {
8248 res.Add(new LSL_Integer((int)texface.Bump)); 9003 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9004 }
9005 else if (shinyness == Shininess.Low)
9006 {
9007 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9008 }
9009 else
9010 {
9011 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8249 } 9012 }
9013 res.Add(new LSL_Integer(shiny));
9014 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8250 } 9015 }
8251 break; 9016 break;
8252 9017
@@ -8254,24 +9019,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8254 if (remain < 1) 9019 if (remain < 1)
8255 return null; 9020 return null;
8256 9021
8257 face=(int)rules.GetLSLIntegerItem(idx++); 9022 face = (int)rules.GetLSLIntegerItem(idx++);
8258 9023
8259 tex = part.Shape.Textures; 9024 tex = part.Shape.Textures;
9025 int fullbright;
8260 if (face == ScriptBaseClass.ALL_SIDES) 9026 if (face == ScriptBaseClass.ALL_SIDES)
8261 { 9027 {
8262 for (face = 0; face < GetNumberOfSides(part); face++) 9028 for (face = 0; face < GetNumberOfSides(part); face++)
8263 { 9029 {
8264 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9030 if (tex.GetFace((uint)face).Fullbright == true)
8265 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9031 {
9032 fullbright = ScriptBaseClass.TRUE;
9033 }
9034 else
9035 {
9036 fullbright = ScriptBaseClass.FALSE;
9037 }
9038 res.Add(new LSL_Integer(fullbright));
8266 } 9039 }
8267 } 9040 }
8268 else 9041 else
8269 { 9042 {
8270 if (face >= 0 && face < GetNumberOfSides(part)) 9043 if (tex.GetFace((uint)face).Fullbright == true)
8271 { 9044 {
8272 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9045 fullbright = ScriptBaseClass.TRUE;
8273 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8274 } 9046 }
9047 else
9048 {
9049 fullbright = ScriptBaseClass.FALSE;
9050 }
9051 res.Add(new LSL_Integer(fullbright));
8275 } 9052 }
8276 break; 9053 break;
8277 9054
@@ -8293,27 +9070,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8293 break; 9070 break;
8294 9071
8295 case (int)ScriptBaseClass.PRIM_TEXGEN: 9072 case (int)ScriptBaseClass.PRIM_TEXGEN:
9073 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8296 if (remain < 1) 9074 if (remain < 1)
8297 return null; 9075 return null;
8298 9076
8299 face=(int)rules.GetLSLIntegerItem(idx++); 9077 face = (int)rules.GetLSLIntegerItem(idx++);
8300 9078
8301 tex = part.Shape.Textures; 9079 tex = part.Shape.Textures;
8302 if (face == ScriptBaseClass.ALL_SIDES) 9080 if (face == ScriptBaseClass.ALL_SIDES)
8303 { 9081 {
8304 for (face = 0; face < GetNumberOfSides(part); face++) 9082 for (face = 0; face < GetNumberOfSides(part); face++)
8305 { 9083 {
8306 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9084 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8307 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9085 {
8308 res.Add(new LSL_Integer((uint)texgen >> 1)); 9086 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9087 }
9088 else
9089 {
9090 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9091 }
8309 } 9092 }
8310 } 9093 }
8311 else 9094 else
8312 { 9095 {
8313 if (face >= 0 && face < GetNumberOfSides(part)) 9096 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9097 {
9098 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9099 }
9100 else
8314 { 9101 {
8315 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9102 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8316 res.Add(new LSL_Integer((uint)texgen >> 1));
8317 } 9103 }
8318 } 9104 }
8319 break; 9105 break;
@@ -8337,24 +9123,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8337 if (remain < 1) 9123 if (remain < 1)
8338 return null; 9124 return null;
8339 9125
8340 face=(int)rules.GetLSLIntegerItem(idx++); 9126 face = (int)rules.GetLSLIntegerItem(idx++);
8341 9127
8342 tex = part.Shape.Textures; 9128 tex = part.Shape.Textures;
9129 float primglow;
8343 if (face == ScriptBaseClass.ALL_SIDES) 9130 if (face == ScriptBaseClass.ALL_SIDES)
8344 { 9131 {
8345 for (face = 0; face < GetNumberOfSides(part); face++) 9132 for (face = 0; face < GetNumberOfSides(part); face++)
8346 { 9133 {
8347 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9134 primglow = tex.GetFace((uint)face).Glow;
8348 res.Add(new LSL_Float(texface.Glow)); 9135 res.Add(new LSL_Float(primglow));
8349 } 9136 }
8350 } 9137 }
8351 else 9138 else
8352 { 9139 {
8353 if (face >= 0 && face < GetNumberOfSides(part)) 9140 primglow = tex.GetFace((uint)face).Glow;
8354 { 9141 res.Add(new LSL_Float(primglow));
8355 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8356 res.Add(new LSL_Float(texface.Glow));
8357 }
8358 } 9142 }
8359 break; 9143 break;
8360 9144
@@ -8366,15 +9150,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8366 textColor.B)); 9150 textColor.B));
8367 res.Add(new LSL_Float(textColor.A)); 9151 res.Add(new LSL_Float(textColor.A));
8368 break; 9152 break;
9153
8369 case (int)ScriptBaseClass.PRIM_NAME: 9154 case (int)ScriptBaseClass.PRIM_NAME:
8370 res.Add(new LSL_String(part.Name)); 9155 res.Add(new LSL_String(part.Name));
8371 break; 9156 break;
9157
8372 case (int)ScriptBaseClass.PRIM_DESC: 9158 case (int)ScriptBaseClass.PRIM_DESC:
8373 res.Add(new LSL_String(part.Description)); 9159 res.Add(new LSL_String(part.Description));
8374 break; 9160 break;
9161
8375 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9162 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8376 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9163 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8377 break; 9164 break;
9165
8378 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9166 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8379 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9167 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8380 break; 9168 break;
@@ -8985,8 +9773,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8985 // The function returns an ordered list 9773 // The function returns an ordered list
8986 // representing the tokens found in the supplied 9774 // representing the tokens found in the supplied
8987 // sources string. If two successive tokenizers 9775 // sources string. If two successive tokenizers
8988 // are encountered, then a NULL entry is added 9776 // are encountered, then a null-string entry is
8989 // to the list. 9777 // added to the list.
8990 // 9778 //
8991 // It is a precondition that the source and 9779 // It is a precondition that the source and
8992 // toekizer lisst are non-null. If they are null, 9780 // toekizer lisst are non-null. If they are null,
@@ -8994,7 +9782,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8994 // while their lengths are being determined. 9782 // while their lengths are being determined.
8995 // 9783 //
8996 // A small amount of working memoryis required 9784 // A small amount of working memoryis required
8997 // of approximately 8*#tokenizers. 9785 // of approximately 8*#tokenizers + 8*srcstrlen.
8998 // 9786 //
8999 // There are many ways in which this function 9787 // There are many ways in which this function
9000 // can be implemented, this implementation is 9788 // can be implemented, this implementation is
@@ -9010,155 +9798,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9010 // and eliminates redundant tokenizers as soon 9798 // and eliminates redundant tokenizers as soon
9011 // as is possible. 9799 // as is possible.
9012 // 9800 //
9013 // The implementation tries to avoid any copying 9801 // The implementation tries to minimize temporary
9014 // of arrays or other objects. 9802 // garbage generation.
9015 // </remarks> 9803 // </remarks>
9016 9804
9017 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9805 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9018 { 9806 {
9019 int beginning = 0; 9807 return ParseString2List(src, separators, spacers, true);
9020 int srclen = src.Length; 9808 }
9021 int seplen = separators.Length;
9022 object[] separray = separators.Data;
9023 int spclen = spacers.Length;
9024 object[] spcarray = spacers.Data;
9025 int mlen = seplen+spclen;
9026
9027 int[] offset = new int[mlen+1];
9028 bool[] active = new bool[mlen];
9029
9030 int best;
9031 int j;
9032
9033 // Initial capacity reduces resize cost
9034 9809
9035 LSL_List tokens = new LSL_List(); 9810 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9811 {
9812 int srclen = src.Length;
9813 int seplen = separators.Length;
9814 object[] separray = separators.Data;
9815 int spclen = spacers.Length;
9816 object[] spcarray = spacers.Data;
9817 int dellen = 0;
9818 string[] delarray = new string[seplen+spclen];
9036 9819
9037 // All entries are initially valid 9820 int outlen = 0;
9821 string[] outarray = new string[srclen*2+1];
9038 9822
9039 for (int i = 0; i < mlen; i++) 9823 int i, j;
9040 active[i] = true; 9824 string d;
9041 9825
9042 offset[mlen] = srclen; 9826 m_host.AddScriptLPS(1);
9043 9827
9044 while (beginning < srclen) 9828 /*
9829 * Convert separator and spacer lists to C# strings.
9830 * Also filter out null strings so we don't hang.
9831 */
9832 for (i = 0; i < seplen; i ++)
9045 { 9833 {
9834 d = separray[i].ToString();
9835 if (d.Length > 0)
9836 {
9837 delarray[dellen++] = d;
9838 }
9839 }
9840 seplen = dellen;
9046 9841
9047 best = mlen; // as bad as it gets 9842 for (i = 0; i < spclen; i ++)
9843 {
9844 d = spcarray[i].ToString();
9845 if (d.Length > 0)
9846 {
9847 delarray[dellen++] = d;
9848 }
9849 }
9048 9850
9049 // Scan for separators 9851 /*
9852 * Scan through source string from beginning to end.
9853 */
9854 for (i = 0;;)
9855 {
9050 9856
9051 for (j = 0; j < seplen; j++) 9857 /*
9858 * Find earliest delimeter in src starting at i (if any).
9859 */
9860 int earliestDel = -1;
9861 int earliestSrc = srclen;
9862 string earliestStr = null;
9863 for (j = 0; j < dellen; j ++)
9052 { 9864 {
9053 if (separray[j].ToString() == String.Empty) 9865 d = delarray[j];
9054 active[j] = false; 9866 if (d != null)
9055
9056 if (active[j])
9057 { 9867 {
9058 // scan all of the markers 9868 int index = src.IndexOf(d, i);
9059 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9869 if (index < 0)
9060 { 9870 {
9061 // not present at all 9871 delarray[j] = null; // delim nowhere in src, don't check it anymore
9062 active[j] = false;
9063 } 9872 }
9064 else 9873 else if (index < earliestSrc)
9065 { 9874 {
9066 // present and correct 9875 earliestSrc = index; // where delimeter starts in source string
9067 if (offset[j] < offset[best]) 9876 earliestDel = j; // where delimeter is in delarray[]
9068 { 9877 earliestStr = d; // the delimeter string from delarray[]
9069 // closest so far 9878 if (index == i) break; // can't do any better than found at beg of string
9070 best = j;
9071 if (offset[best] == beginning)
9072 break;
9073 }
9074 } 9879 }
9075 } 9880 }
9076 } 9881 }
9077 9882
9078 // Scan for spacers 9883 /*
9079 9884 * Output source string starting at i through start of earliest delimeter.
9080 if (offset[best] != beginning) 9885 */
9886 if (keepNulls || (earliestSrc > i))
9081 { 9887 {
9082 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9888 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9083 {
9084 if (spcarray[j-seplen].ToString() == String.Empty)
9085 active[j] = false;
9086
9087 if (active[j])
9088 {
9089 // scan all of the markers
9090 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9091 {
9092 // not present at all
9093 active[j] = false;
9094 }
9095 else
9096 {
9097 // present and correct
9098 if (offset[j] < offset[best])
9099 {
9100 // closest so far
9101 best = j;
9102 }
9103 }
9104 }
9105 }
9106 } 9889 }
9107 9890
9108 // This is the normal exit from the scanning loop 9891 /*
9892 * If no delimeter found at or after i, we're done scanning.
9893 */
9894 if (earliestDel < 0) break;
9109 9895
9110 if (best == mlen) 9896 /*
9897 * If delimeter was a spacer, output the spacer.
9898 */
9899 if (earliestDel >= seplen)
9111 { 9900 {
9112 // no markers were found on this pass 9901 outarray[outlen++] = earliestStr;
9113 // so we're pretty much done
9114 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9115 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9116 break;
9117 } 9902 }
9118 9903
9119 // Otherwise we just add the newly delimited token 9904 /*
9120 // and recalculate where the search should continue. 9905 * Look at rest of src string following delimeter.
9121 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9906 */
9122 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9907 i = earliestSrc + earliestStr.Length;
9123
9124 if (best < seplen)
9125 {
9126 beginning = offset[best] + (separray[best].ToString()).Length;
9127 }
9128 else
9129 {
9130 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9131 string str = spcarray[best - seplen].ToString();
9132 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9133 tokens.Add(new LSL_String(str));
9134 }
9135 } 9908 }
9136 9909
9137 // This an awkward an not very intuitive boundary case. If the 9910 /*
9138 // last substring is a tokenizer, then there is an implied trailing 9911 * Make up an exact-sized output array suitable for an LSL_List object.
9139 // null list entry. Hopefully the single comparison will not be too 9912 */
9140 // arduous. Alternatively the 'break' could be replced with a return 9913 object[] outlist = new object[outlen];
9141 // but that's shabby programming. 9914 for (i = 0; i < outlen; i ++)
9142
9143 if ((beginning == srclen) && (keepNulls))
9144 { 9915 {
9145 if (srclen != 0) 9916 outlist[i] = new LSL_String(outarray[i]);
9146 tokens.Add(new LSL_String(""));
9147 } 9917 }
9148 9918 return new LSL_List(outlist);
9149 return tokens;
9150 }
9151
9152 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9153 {
9154 m_host.AddScriptLPS(1);
9155 return this.ParseString(src, separators, spacers, false);
9156 }
9157
9158 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9159 {
9160 m_host.AddScriptLPS(1);
9161 return this.ParseString(src, separators, spacers, true);
9162 } 9919 }
9163 9920
9164 public LSL_Integer llGetObjectPermMask(int mask) 9921 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9253,6 +10010,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9253 case 4: 10010 case 4:
9254 return (int)item.NextPermissions; 10011 return (int)item.NextPermissions;
9255 } 10012 }
10013 m_host.TaskInventory.LockItemsForRead(false);
9256 10014
9257 return -1; 10015 return -1;
9258 } 10016 }
@@ -9455,31 +10213,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9455 UUID key = new UUID(); 10213 UUID key = new UUID();
9456 if (UUID.TryParse(id, out key)) 10214 if (UUID.TryParse(id, out key))
9457 { 10215 {
9458 try 10216 // return total object mass
9459 { 10217 SceneObjectPart part = World.GetSceneObjectPart(key);
9460 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10218 if (part != null)
9461 if (obj != null) 10219 return part.ParentGroup.GetMass();
9462 return (double)obj.GetMass(); 10220
9463 // the object is null so the key is for an avatar 10221 // the object is null so the key is for an avatar
9464 ScenePresence avatar = World.GetScenePresence(key); 10222 ScenePresence avatar = World.GetScenePresence(key);
9465 if (avatar != null) 10223 if (avatar != null)
9466 if (avatar.IsChildAgent)
9467 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9468 // child agents have a mass of 1.0
9469 return 1;
9470 else
9471 return (double)avatar.GetMass();
9472 }
9473 catch (KeyNotFoundException)
9474 { 10224 {
9475 return 0; // The Object/Agent not in the region so just return zero 10225 if (avatar.IsChildAgent)
10226 {
10227 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10228 // child agents have a mass of 1.0
10229 return 1;
10230 }
10231 else
10232 {
10233 return (double)avatar.GetMass();
10234 }
9476 } 10235 }
9477 } 10236 }
9478 return 0; 10237 return 0;
9479 } 10238 }
9480 10239
9481 /// <summary> 10240 /// <summary>
9482 /// illListReplaceList removes the sub-list defined by the inclusive indices 10241 /// llListReplaceList removes the sub-list defined by the inclusive indices
9483 /// start and end and inserts the src list in its place. The inclusive 10242 /// start and end and inserts the src list in its place. The inclusive
9484 /// nature of the indices means that at least one element must be deleted 10243 /// nature of the indices means that at least one element must be deleted
9485 /// if the indices are within the bounds of the existing list. I.e. 2,2 10244 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9536,16 +10295,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9536 // based upon end. Note that if end exceeds the upper 10295 // based upon end. Note that if end exceeds the upper
9537 // bound in this case, the entire destination list 10296 // bound in this case, the entire destination list
9538 // is removed. 10297 // is removed.
9539 else 10298 else if (start == 0)
9540 { 10299 {
9541 if (end + 1 < dest.Length) 10300 if (end + 1 < dest.Length)
9542 {
9543 return src + dest.GetSublist(end + 1, -1); 10301 return src + dest.GetSublist(end + 1, -1);
9544 }
9545 else 10302 else
9546 {
9547 return src; 10303 return src;
9548 } 10304 }
10305 else // Start < 0
10306 {
10307 if (end + 1 < dest.Length)
10308 return dest.GetSublist(end + 1, -1);
10309 else
10310 return new LSL_List();
9549 } 10311 }
9550 } 10312 }
9551 // Finally, if start > end, we strip away a prefix and 10313 // Finally, if start > end, we strip away a prefix and
@@ -9596,17 +10358,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9596 int width = 0; 10358 int width = 0;
9597 int height = 0; 10359 int height = 0;
9598 10360
9599 ParcelMediaCommandEnum? commandToSend = null; 10361 uint commandToSend = 0;
9600 float time = 0.0f; // default is from start 10362 float time = 0.0f; // default is from start
9601 10363
9602 ScenePresence presence = null; 10364 ScenePresence presence = null;
9603 10365
9604 for (int i = 0; i < commandList.Data.Length; i++) 10366 for (int i = 0; i < commandList.Data.Length; i++)
9605 { 10367 {
9606 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10368 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9607 switch (command) 10369 switch (command)
9608 { 10370 {
9609 case ParcelMediaCommandEnum.Agent: 10371 case (uint)ParcelMediaCommandEnum.Agent:
9610 // we send only to one agent 10372 // we send only to one agent
9611 if ((i + 1) < commandList.Length) 10373 if ((i + 1) < commandList.Length)
9612 { 10374 {
@@ -9623,25 +10385,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9623 } 10385 }
9624 break; 10386 break;
9625 10387
9626 case ParcelMediaCommandEnum.Loop: 10388 case (uint)ParcelMediaCommandEnum.Loop:
9627 loop = 1; 10389 loop = 1;
9628 commandToSend = command; 10390 commandToSend = command;
9629 update = true; //need to send the media update packet to set looping 10391 update = true; //need to send the media update packet to set looping
9630 break; 10392 break;
9631 10393
9632 case ParcelMediaCommandEnum.Play: 10394 case (uint)ParcelMediaCommandEnum.Play:
9633 loop = 0; 10395 loop = 0;
9634 commandToSend = command; 10396 commandToSend = command;
9635 update = true; //need to send the media update packet to make sure it doesn't loop 10397 update = true; //need to send the media update packet to make sure it doesn't loop
9636 break; 10398 break;
9637 10399
9638 case ParcelMediaCommandEnum.Pause: 10400 case (uint)ParcelMediaCommandEnum.Pause:
9639 case ParcelMediaCommandEnum.Stop: 10401 case (uint)ParcelMediaCommandEnum.Stop:
9640 case ParcelMediaCommandEnum.Unload: 10402 case (uint)ParcelMediaCommandEnum.Unload:
9641 commandToSend = command; 10403 commandToSend = command;
9642 break; 10404 break;
9643 10405
9644 case ParcelMediaCommandEnum.Url: 10406 case (uint)ParcelMediaCommandEnum.Url:
9645 if ((i + 1) < commandList.Length) 10407 if ((i + 1) < commandList.Length)
9646 { 10408 {
9647 if (commandList.Data[i + 1] is LSL_String) 10409 if (commandList.Data[i + 1] is LSL_String)
@@ -9654,7 +10416,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9654 } 10416 }
9655 break; 10417 break;
9656 10418
9657 case ParcelMediaCommandEnum.Texture: 10419 case (uint)ParcelMediaCommandEnum.Texture:
9658 if ((i + 1) < commandList.Length) 10420 if ((i + 1) < commandList.Length)
9659 { 10421 {
9660 if (commandList.Data[i + 1] is LSL_String) 10422 if (commandList.Data[i + 1] is LSL_String)
@@ -9667,7 +10429,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9667 } 10429 }
9668 break; 10430 break;
9669 10431
9670 case ParcelMediaCommandEnum.Time: 10432 case (uint)ParcelMediaCommandEnum.Time:
9671 if ((i + 1) < commandList.Length) 10433 if ((i + 1) < commandList.Length)
9672 { 10434 {
9673 if (commandList.Data[i + 1] is LSL_Float) 10435 if (commandList.Data[i + 1] is LSL_Float)
@@ -9679,7 +10441,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9679 } 10441 }
9680 break; 10442 break;
9681 10443
9682 case ParcelMediaCommandEnum.AutoAlign: 10444 case (uint)ParcelMediaCommandEnum.AutoAlign:
9683 if ((i + 1) < commandList.Length) 10445 if ((i + 1) < commandList.Length)
9684 { 10446 {
9685 if (commandList.Data[i + 1] is LSL_Integer) 10447 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9693,7 +10455,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9693 } 10455 }
9694 break; 10456 break;
9695 10457
9696 case ParcelMediaCommandEnum.Type: 10458 case (uint)ParcelMediaCommandEnum.Type:
9697 if ((i + 1) < commandList.Length) 10459 if ((i + 1) < commandList.Length)
9698 { 10460 {
9699 if (commandList.Data[i + 1] is LSL_String) 10461 if (commandList.Data[i + 1] is LSL_String)
@@ -9706,7 +10468,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9706 } 10468 }
9707 break; 10469 break;
9708 10470
9709 case ParcelMediaCommandEnum.Desc: 10471 case (uint)ParcelMediaCommandEnum.Desc:
9710 if ((i + 1) < commandList.Length) 10472 if ((i + 1) < commandList.Length)
9711 { 10473 {
9712 if (commandList.Data[i + 1] is LSL_String) 10474 if (commandList.Data[i + 1] is LSL_String)
@@ -9719,7 +10481,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9719 } 10481 }
9720 break; 10482 break;
9721 10483
9722 case ParcelMediaCommandEnum.Size: 10484 case (uint)ParcelMediaCommandEnum.Size:
9723 if ((i + 2) < commandList.Length) 10485 if ((i + 2) < commandList.Length)
9724 { 10486 {
9725 if (commandList.Data[i + 1] is LSL_Integer) 10487 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9789,7 +10551,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9789 } 10551 }
9790 } 10552 }
9791 10553
9792 if (commandToSend != null) 10554 if (commandToSend != 0)
9793 { 10555 {
9794 // the commandList contained a start/stop/... command, too 10556 // the commandList contained a start/stop/... command, too
9795 if (presence == null) 10557 if (presence == null)
@@ -9826,7 +10588,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9826 10588
9827 if (aList.Data[i] != null) 10589 if (aList.Data[i] != null)
9828 { 10590 {
9829 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10591 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9830 { 10592 {
9831 case ParcelMediaCommandEnum.Url: 10593 case ParcelMediaCommandEnum.Url:
9832 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10594 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9883,15 +10645,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9883 10645
9884 if (quick_pay_buttons.Data.Length < 4) 10646 if (quick_pay_buttons.Data.Length < 4)
9885 { 10647 {
9886 LSLError("List must have at least 4 elements"); 10648 int x;
9887 return; 10649 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10650 {
10651 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10652 }
9888 } 10653 }
9889 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10654 int[] nPrice = new int[5];
9890 10655 nPrice[0] = price;
9891 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10656 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9892 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10657 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9893 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10658 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9894 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10659 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10660 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9895 m_host.ParentGroup.HasGroupChanged = true; 10661 m_host.ParentGroup.HasGroupChanged = true;
9896 } 10662 }
9897 10663
@@ -9908,7 +10674,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9908 return new LSL_Vector(); 10674 return new LSL_Vector();
9909 } 10675 }
9910 10676
9911 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10677// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10678 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9912 if (presence != null) 10679 if (presence != null)
9913 { 10680 {
9914 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10681 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9930,7 +10697,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9930 return new LSL_Rotation(); 10697 return new LSL_Rotation();
9931 } 10698 }
9932 10699
9933 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10700// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10701 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9934 if (presence != null) 10702 if (presence != null)
9935 { 10703 {
9936 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10704 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9990,14 +10758,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9990 { 10758 {
9991 m_host.AddScriptLPS(1); 10759 m_host.AddScriptLPS(1);
9992 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10760 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9993 if (detectedParams == null) return; // only works on the first detected avatar 10761 if (detectedParams == null)
9994 10762 {
10763 if (m_host.ParentGroup.IsAttachment == true)
10764 {
10765 detectedParams = new DetectParams();
10766 detectedParams.Key = m_host.OwnerID;
10767 }
10768 else
10769 {
10770 return;
10771 }
10772 }
10773
9995 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10774 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9996 if (avatar != null) 10775 if (avatar != null)
9997 { 10776 {
9998 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10777 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9999 simname, pos, lookAt); 10778 simname, pos, lookAt);
10000 } 10779 }
10780
10001 ScriptSleep(1000); 10781 ScriptSleep(1000);
10002 } 10782 }
10003 10783
@@ -10121,12 +10901,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10121 10901
10122 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10902 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10123 object[] data = rules.Data; 10903 object[] data = rules.Data;
10124 for (int i = 0; i < data.Length; ++i) { 10904 for (int i = 0; i < data.Length; ++i)
10905 {
10125 int type = Convert.ToInt32(data[i++].ToString()); 10906 int type = Convert.ToInt32(data[i++].ToString());
10126 if (i >= data.Length) break; // odd number of entries => ignore the last 10907 if (i >= data.Length) break; // odd number of entries => ignore the last
10127 10908
10128 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10909 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10129 switch (type) { 10910 switch (type)
10911 {
10130 case ScriptBaseClass.CAMERA_FOCUS: 10912 case ScriptBaseClass.CAMERA_FOCUS:
10131 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10913 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10132 case ScriptBaseClass.CAMERA_POSITION: 10914 case ScriptBaseClass.CAMERA_POSITION:
@@ -10231,19 +11013,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10231 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11013 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10232 { 11014 {
10233 m_host.AddScriptLPS(1); 11015 m_host.AddScriptLPS(1);
10234 string ret = String.Empty; 11016
10235 string src1 = llBase64ToString(str1); 11017 if (str1 == String.Empty)
10236 string src2 = llBase64ToString(str2); 11018 return String.Empty;
10237 int c = 0; 11019 if (str2 == String.Empty)
10238 for (int i = 0; i < src1.Length; i++) 11020 return str1;
11021
11022 int len = str2.Length;
11023 if ((len % 4) != 0) // LL is EVIL!!!!
10239 { 11024 {
10240 ret += (char) (src1[i] ^ src2[c]); 11025 while (str2.EndsWith("="))
11026 str2 = str2.Substring(0, str2.Length - 1);
11027
11028 len = str2.Length;
11029 int mod = len % 4;
10241 11030
10242 c++; 11031 if (mod == 1)
10243 if (c >= src2.Length) 11032 str2 = str2.Substring(0, str2.Length - 1);
10244 c = 0; 11033 else if (mod == 2)
11034 str2 += "==";
11035 else if (mod == 3)
11036 str2 += "=";
11037 }
11038
11039 byte[] data1;
11040 byte[] data2;
11041 try
11042 {
11043 data1 = Convert.FromBase64String(str1);
11044 data2 = Convert.FromBase64String(str2);
11045 }
11046 catch (Exception)
11047 {
11048 return new LSL_String(String.Empty);
10245 } 11049 }
10246 return llStringToBase64(ret); 11050
11051 byte[] d2 = new Byte[data1.Length];
11052 int pos = 0;
11053
11054 if (data1.Length <= data2.Length)
11055 {
11056 Array.Copy(data2, 0, d2, 0, data1.Length);
11057 }
11058 else
11059 {
11060 while (pos < data1.Length)
11061 {
11062 len = data1.Length - pos;
11063 if (len > data2.Length)
11064 len = data2.Length;
11065
11066 Array.Copy(data2, 0, d2, pos, len);
11067 pos += len;
11068 }
11069 }
11070
11071 for (pos = 0 ; pos < data1.Length ; pos++ )
11072 data1[pos] ^= d2[pos];
11073
11074 return Convert.ToBase64String(data1);
10247 } 11075 }
10248 11076
10249 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11077 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10296,16 +11124,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10296 if (userAgent != null) 11124 if (userAgent != null)
10297 httpHeaders["User-Agent"] = userAgent; 11125 httpHeaders["User-Agent"] = userAgent;
10298 11126
11127 // See if the URL contains any header hacks
11128 string[] urlParts = url.Split(new char[] {'\n'});
11129 if (urlParts.Length > 1)
11130 {
11131 // Iterate the passed headers and parse them
11132 for (int i = 1 ; i < urlParts.Length ; i++ )
11133 {
11134 // The rest of those would be added to the body in SL.
11135 // Let's not do that.
11136 if (urlParts[i] == String.Empty)
11137 break;
11138
11139 // See if this could be a valid header
11140 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11141 if (headerParts.Length != 2)
11142 continue;
11143
11144 string headerName = headerParts[0].Trim();
11145 string headerValue = headerParts[1].Trim();
11146
11147 // Filter out headers that could be used to abuse
11148 // another system or cloak the request
11149 if (headerName.ToLower() == "x-secondlife-shard" ||
11150 headerName.ToLower() == "x-secondlife-object-name" ||
11151 headerName.ToLower() == "x-secondlife-object-key" ||
11152 headerName.ToLower() == "x-secondlife-region" ||
11153 headerName.ToLower() == "x-secondlife-local-position" ||
11154 headerName.ToLower() == "x-secondlife-local-velocity" ||
11155 headerName.ToLower() == "x-secondlife-local-rotation" ||
11156 headerName.ToLower() == "x-secondlife-owner-name" ||
11157 headerName.ToLower() == "x-secondlife-owner-key" ||
11158 headerName.ToLower() == "connection" ||
11159 headerName.ToLower() == "content-length" ||
11160 headerName.ToLower() == "from" ||
11161 headerName.ToLower() == "host" ||
11162 headerName.ToLower() == "proxy-authorization" ||
11163 headerName.ToLower() == "referer" ||
11164 headerName.ToLower() == "trailer" ||
11165 headerName.ToLower() == "transfer-encoding" ||
11166 headerName.ToLower() == "via" ||
11167 headerName.ToLower() == "authorization")
11168 continue;
11169
11170 httpHeaders[headerName] = headerValue;
11171 }
11172
11173 // Finally, strip any protocol specifier from the URL
11174 url = urlParts[0].Trim();
11175 int idx = url.IndexOf(" HTTP/");
11176 if (idx != -1)
11177 url = url.Substring(0, idx);
11178 }
11179
10299 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11180 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10300 Regex r = new Regex(authregex); 11181 Regex r = new Regex(authregex);
10301 int[] gnums = r.GetGroupNumbers(); 11182 int[] gnums = r.GetGroupNumbers();
10302 Match m = r.Match(url); 11183 Match m = r.Match(url);
10303 if (m.Success) { 11184 if (m.Success)
10304 for (int i = 1; i < gnums.Length; i++) { 11185 {
11186 for (int i = 1; i < gnums.Length; i++)
11187 {
10305 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11188 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10306 //CaptureCollection cc = g.Captures; 11189 //CaptureCollection cc = g.Captures;
10307 } 11190 }
10308 if (m.Groups.Count == 5) { 11191 if (m.Groups.Count == 5)
11192 {
10309 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11193 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10310 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11194 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10311 } 11195 }
@@ -10508,6 +11392,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10508 11392
10509 LSL_List ret = new LSL_List(); 11393 LSL_List ret = new LSL_List();
10510 UUID key = new UUID(); 11394 UUID key = new UUID();
11395
11396
10511 if (UUID.TryParse(id, out key)) 11397 if (UUID.TryParse(id, out key))
10512 { 11398 {
10513 ScenePresence av = World.GetScenePresence(key); 11399 ScenePresence av = World.GetScenePresence(key);
@@ -10525,13 +11411,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10525 ret.Add(new LSL_String("")); 11411 ret.Add(new LSL_String(""));
10526 break; 11412 break;
10527 case ScriptBaseClass.OBJECT_POS: 11413 case ScriptBaseClass.OBJECT_POS:
10528 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11414 Vector3 avpos;
11415
11416 if (av.ParentID != 0 && av.ParentPart != null)
11417 {
11418 avpos = av.OffsetPosition;
11419
11420 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11421 avpos -= sitOffset;
11422
11423 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11424 }
11425 else
11426 avpos = av.AbsolutePosition;
11427
11428 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10529 break; 11429 break;
10530 case ScriptBaseClass.OBJECT_ROT: 11430 case ScriptBaseClass.OBJECT_ROT:
10531 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11431 Quaternion avrot = av.Rotation;
11432 if (av.ParentID != 0 && av.ParentPart != null)
11433 {
11434 avrot = av.ParentPart.GetWorldRotation() * avrot;
11435 }
11436 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10532 break; 11437 break;
10533 case ScriptBaseClass.OBJECT_VELOCITY: 11438 case ScriptBaseClass.OBJECT_VELOCITY:
10534 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11439 Vector3 avvel = av.Velocity;
11440 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10535 break; 11441 break;
10536 case ScriptBaseClass.OBJECT_OWNER: 11442 case ScriptBaseClass.OBJECT_OWNER:
10537 ret.Add(new LSL_String(id)); 11443 ret.Add(new LSL_String(id));
@@ -10587,11 +11493,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10587 case ScriptBaseClass.OBJECT_NAME: 11493 case ScriptBaseClass.OBJECT_NAME:
10588 ret.Add(new LSL_String(obj.Name)); 11494 ret.Add(new LSL_String(obj.Name));
10589 break; 11495 break;
10590 case ScriptBaseClass.OBJECT_DESC: 11496 case ScriptBaseClass.OBJECT_DESC:
10591 ret.Add(new LSL_String(obj.Description)); 11497 ret.Add(new LSL_String(obj.Description));
10592 break; 11498 break;
10593 case ScriptBaseClass.OBJECT_POS: 11499 case ScriptBaseClass.OBJECT_POS:
10594 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11500 Vector3 opos = obj.AbsolutePosition;
11501 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10595 break; 11502 break;
10596 case ScriptBaseClass.OBJECT_ROT: 11503 case ScriptBaseClass.OBJECT_ROT:
10597 { 11504 {
@@ -10641,9 +11548,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10641 // The value returned in SL for normal prims is prim count 11548 // The value returned in SL for normal prims is prim count
10642 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11549 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10643 break; 11550 break;
10644 // The following 3 costs I have intentionaly coded to return zero. They are part of 11551
10645 // "Land Impact" calculations. These calculations are probably not applicable 11552 // costs below may need to be diferent for root parts, need to check
10646 // to OpenSim and are not yet complete in SL
10647 case ScriptBaseClass.OBJECT_SERVER_COST: 11553 case ScriptBaseClass.OBJECT_SERVER_COST:
10648 // The linden calculation is here 11554 // The linden calculation is here
10649 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11555 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10651,16 +11557,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10651 ret.Add(new LSL_Float(0)); 11557 ret.Add(new LSL_Float(0));
10652 break; 11558 break;
10653 case ScriptBaseClass.OBJECT_STREAMING_COST: 11559 case ScriptBaseClass.OBJECT_STREAMING_COST:
10654 // The linden calculation is here 11560 // The value returned in SL for normal prims is prim count * 0.06
10655 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11561 ret.Add(new LSL_Float(obj.StreamingCost));
10656 // The value returned in SL for normal prims looks like the prim count * 0.06
10657 ret.Add(new LSL_Float(0));
10658 break; 11562 break;
10659 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11563 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10660 // The linden calculation is here 11564 // The value returned in SL for normal prims is prim count
10661 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11565 ret.Add(new LSL_Float(obj.PhysicsCost));
10662 // The value returned in SL for normal prims looks like the prim count
10663 ret.Add(new LSL_Float(0));
10664 break; 11566 break;
10665 default: 11567 default:
10666 // Invalid or unhandled constant. 11568 // Invalid or unhandled constant.
@@ -10871,15 +11773,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10871 return result; 11773 return result;
10872 } 11774 }
10873 11775
10874 public void print(string str) 11776 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10875 { 11777 {
10876 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11778 List<SceneObjectPart> parts = GetLinkParts(link);
10877 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11779 if (parts.Count < 1)
10878 if (ossl != null) 11780 return 0;
10879 { 11781
10880 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11782 return GetNumberOfSides(parts[0]);
10881 m_log.Info("LSL print():" + str);
10882 }
10883 } 11783 }
10884 11784
10885 private string Name2Username(string name) 11785 private string Name2Username(string name)
@@ -10924,7 +11824,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10924 11824
10925 return rq.ToString(); 11825 return rq.ToString();
10926 } 11826 }
10927 11827/*
11828 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11829 {
11830 m_SayShoutCount = 0;
11831 }
11832*/
10928 private struct Tri 11833 private struct Tri
10929 { 11834 {
10930 public Vector3 p1; 11835 public Vector3 p1;
@@ -11064,9 +11969,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11064 11969
11065 ContactResult result = new ContactResult (); 11970 ContactResult result = new ContactResult ();
11066 result.ConsumerID = group.LocalId; 11971 result.ConsumerID = group.LocalId;
11067 result.Depth = intersection.distance; 11972// result.Depth = intersection.distance;
11068 result.Normal = intersection.normal; 11973 result.Normal = intersection.normal;
11069 result.Pos = intersection.ipoint; 11974 result.Pos = intersection.ipoint;
11975 result.Depth = Vector3.Mag(rayStart - result.Pos);
11070 11976
11071 contacts.Add(result); 11977 contacts.Add(result);
11072 }); 11978 });
@@ -11199,6 +12105,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11199 12105
11200 return contacts[0]; 12106 return contacts[0];
11201 } 12107 }
12108/*
12109 // not done:
12110 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12111 {
12112 ContactResult[] contacts = null;
12113 World.ForEachSOG(delegate(SceneObjectGroup group)
12114 {
12115 if (m_host.ParentGroup == group)
12116 return;
12117
12118 if (group.IsAttachment)
12119 return;
12120
12121 if(group.RootPart.PhysActor != null)
12122 return;
12123
12124 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12125 });
12126 return contacts;
12127 }
12128*/
11202 12129
11203 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12130 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11204 { 12131 {
@@ -11240,32 +12167,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11240 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12167 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11241 12168
11242 12169
11243 if (checkTerrain) 12170 if (World.SuportsRayCastFiltered())
11244 { 12171 {
11245 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12172 if (dist == 0)
11246 if (groundContact != null) 12173 return list;
11247 results.Add((ContactResult)groundContact);
11248 }
11249 12174
11250 if (checkAgents) 12175 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11251 { 12176 if (checkTerrain)
11252 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12177 rayfilter |= RayFilterFlags.land;
11253 foreach (ContactResult r in agentHits) 12178// if (checkAgents)
11254 results.Add(r); 12179// rayfilter |= RayFilterFlags.agent;
11255 } 12180 if (checkPhysical)
12181 rayfilter |= RayFilterFlags.physical;
12182 if (checkNonPhysical)
12183 rayfilter |= RayFilterFlags.nonphysical;
12184 if (detectPhantom)
12185 rayfilter |= RayFilterFlags.LSLPhanton;
12186
12187 Vector3 direction = dir * ( 1/dist);
12188
12189 if(rayfilter == 0)
12190 {
12191 list.Add(new LSL_Integer(0));
12192 return list;
12193 }
12194
12195 // get some more contacts to sort ???
12196 int physcount = 4 * count;
12197 if (physcount > 20)
12198 physcount = 20;
11256 12199
11257 if (checkPhysical || checkNonPhysical || detectPhantom) 12200 object physresults;
12201 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12202
12203 if (physresults == null)
12204 {
12205 list.Add(new LSL_Integer(-3)); // timeout error
12206 return list;
12207 }
12208
12209 results = (List<ContactResult>)physresults;
12210
12211 // for now physics doesn't detect sitted avatars so do it outside physics
12212 if (checkAgents)
12213 {
12214 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12215 foreach (ContactResult r in agentHits)
12216 results.Add(r);
12217 }
12218
12219 // TODO: Replace this with a better solution. ObjectIntersection can only
12220 // detect nonphysical phantoms. They are detected by virtue of being
12221 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12222 // physicsl phantoms as done by the physics scene
12223 // We don't want anything else but phantoms here.
12224 if (detectPhantom)
12225 {
12226 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12227 foreach (ContactResult r in objectHits)
12228 results.Add(r);
12229 }
12230 }
12231 else
11258 { 12232 {
11259 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12233 if (checkTerrain)
11260 foreach (ContactResult r in objectHits) 12234 {
11261 results.Add(r); 12235 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12236 if (groundContact != null)
12237 results.Add((ContactResult)groundContact);
12238 }
12239
12240 if (checkAgents)
12241 {
12242 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12243 foreach (ContactResult r in agentHits)
12244 results.Add(r);
12245 }
12246
12247 if (checkPhysical || checkNonPhysical || detectPhantom)
12248 {
12249 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12250 foreach (ContactResult r in objectHits)
12251 results.Add(r);
12252 }
11262 } 12253 }
11263 12254
11264 results.Sort(delegate(ContactResult a, ContactResult b) 12255 results.Sort(delegate(ContactResult a, ContactResult b)
11265 { 12256 {
11266 return a.Depth.CompareTo(b.Depth); 12257 return a.Depth.CompareTo(b.Depth);
11267 }); 12258 });
11268 12259
11269 int values = 0; 12260 int values = 0;
11270 SceneObjectGroup thisgrp = m_host.ParentGroup; 12261 SceneObjectGroup thisgrp = m_host.ParentGroup;
11271 12262
@@ -11358,7 +12349,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11358 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12349 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11359 if (!isAccount) return 0; 12350 if (!isAccount) return 0;
11360 if (estate.HasAccess(id)) return 1; 12351 if (estate.HasAccess(id)) return 1;
11361 if (estate.IsBanned(id)) 12352 if (estate.IsBanned(id, World.GetUserFlags(id)))
11362 estate.RemoveBan(id); 12353 estate.RemoveBan(id);
11363 estate.AddEstateUser(id); 12354 estate.AddEstateUser(id);
11364 break; 12355 break;
@@ -11377,14 +12368,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11377 break; 12368 break;
11378 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12369 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11379 if (!isAccount) return 0; 12370 if (!isAccount) return 0;
11380 if (estate.IsBanned(id)) return 1; 12371 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11381 EstateBan ban = new EstateBan(); 12372 EstateBan ban = new EstateBan();
11382 ban.EstateID = estate.EstateID; 12373 ban.EstateID = estate.EstateID;
11383 ban.BannedUserID = id; 12374 ban.BannedUserID = id;
11384 estate.AddBan(ban); 12375 estate.AddBan(ban);
11385 break; 12376 break;
11386 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12377 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11387 if (!isAccount || !estate.IsBanned(id)) return 0; 12378 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11388 estate.RemoveBan(id); 12379 estate.RemoveBan(id);
11389 break; 12380 break;
11390 default: return 0; 12381 default: return 0;
@@ -11413,7 +12404,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11413 return 16384; 12404 return 16384;
11414 } 12405 }
11415 12406
11416 public LSL_Integer llGetUsedMemory() 12407 public virtual LSL_Integer llGetUsedMemory()
11417 { 12408 {
11418 m_host.AddScriptLPS(1); 12409 m_host.AddScriptLPS(1);
11419 // The value returned for LSO scripts in SL 12410 // The value returned for LSO scripts in SL
@@ -11441,22 +12432,734 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11441 public void llSetSoundQueueing(int queue) 12432 public void llSetSoundQueueing(int queue)
11442 { 12433 {
11443 m_host.AddScriptLPS(1); 12434 m_host.AddScriptLPS(1);
11444 NotImplemented("llSetSoundQueueing");
11445 } 12435 }
11446 12436
11447 public void llCollisionSprite(string impact_sprite) 12437 public void llCollisionSprite(string impact_sprite)
11448 { 12438 {
11449 m_host.AddScriptLPS(1); 12439 m_host.AddScriptLPS(1);
11450 NotImplemented("llCollisionSprite"); 12440 // Viewer 2.0 broke this and it's likely LL has no intention
12441 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11451 } 12442 }
11452 12443
11453 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12444 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11454 { 12445 {
11455 m_host.AddScriptLPS(1); 12446 m_host.AddScriptLPS(1);
11456 NotImplemented("llGodLikeRezObject"); 12447
12448 if (!World.Permissions.IsGod(m_host.OwnerID))
12449 NotImplemented("llGodLikeRezObject");
12450
12451 AssetBase rezAsset = World.AssetService.Get(inventory);
12452 if (rezAsset == null)
12453 {
12454 llSay(0, "Asset not found");
12455 return;
12456 }
12457
12458 SceneObjectGroup group = null;
12459
12460 try
12461 {
12462 string xmlData = Utils.BytesToString(rezAsset.Data);
12463 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12464 }
12465 catch
12466 {
12467 llSay(0, "Asset not found");
12468 return;
12469 }
12470
12471 if (group == null)
12472 {
12473 llSay(0, "Asset not found");
12474 return;
12475 }
12476
12477 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12478 group.RootPart.AttachOffset = group.AbsolutePosition;
12479
12480 group.ResetIDs();
12481
12482 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12483 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12484 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12485 group.ScheduleGroupForFullUpdate();
12486
12487 // objects rezzed with this method are die_at_edge by default.
12488 group.RootPart.SetDieAtEdge(true);
12489
12490 group.ResumeScripts();
12491
12492 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12493 "object_rez", new Object[] {
12494 new LSL_String(
12495 group.RootPart.UUID.ToString()) },
12496 new DetectParams[0]));
12497 }
12498
12499 public LSL_String llTransferLindenDollars(string destination, int amount)
12500 {
12501 UUID txn = UUID.Random();
12502
12503 Util.FireAndForget(delegate(object x)
12504 {
12505 int replycode = 0;
12506 string replydata = destination + "," + amount.ToString();
12507
12508 try
12509 {
12510 TaskInventoryItem item = m_item;
12511 if (item == null)
12512 {
12513 replydata = "SERVICE_ERROR";
12514 return;
12515 }
12516
12517 m_host.AddScriptLPS(1);
12518
12519 if (item.PermsGranter == UUID.Zero)
12520 {
12521 replydata = "MISSING_PERMISSION_DEBIT";
12522 return;
12523 }
12524
12525 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12526 {
12527 replydata = "MISSING_PERMISSION_DEBIT";
12528 return;
12529 }
12530
12531 UUID toID = new UUID();
12532
12533 if (!UUID.TryParse(destination, out toID))
12534 {
12535 replydata = "INVALID_AGENT";
12536 return;
12537 }
12538
12539 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12540
12541 if (money == null)
12542 {
12543 replydata = "TRANSFERS_DISABLED";
12544 return;
12545 }
12546
12547 bool result = money.ObjectGiveMoney(
12548 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
12549
12550 if (result)
12551 {
12552 replycode = 1;
12553 return;
12554 }
12555
12556 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12557 }
12558 finally
12559 {
12560 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12561 "transaction_result", new Object[] {
12562 new LSL_String(txn.ToString()),
12563 new LSL_Integer(replycode),
12564 new LSL_String(replydata) },
12565 new DetectParams[0]));
12566 }
12567 });
12568
12569 return txn.ToString();
11457 } 12570 }
11458 12571
11459 #endregion 12572 #endregion
12573
12574 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12575 {
12576 SceneObjectGroup group = m_host.ParentGroup;
12577
12578 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12579 return;
12580 if (group.IsAttachment)
12581 return;
12582
12583 if (frames.Data.Length > 0) // We are getting a new motion
12584 {
12585 if (group.RootPart.KeyframeMotion != null)
12586 group.RootPart.KeyframeMotion.Delete();
12587 group.RootPart.KeyframeMotion = null;
12588
12589 int idx = 0;
12590
12591 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12592 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12593
12594 while (idx < options.Data.Length)
12595 {
12596 int option = (int)options.GetLSLIntegerItem(idx++);
12597 int remain = options.Data.Length - idx;
12598
12599 switch (option)
12600 {
12601 case ScriptBaseClass.KFM_MODE:
12602 if (remain < 1)
12603 break;
12604 int modeval = (int)options.GetLSLIntegerItem(idx++);
12605 switch(modeval)
12606 {
12607 case ScriptBaseClass.KFM_FORWARD:
12608 mode = KeyframeMotion.PlayMode.Forward;
12609 break;
12610 case ScriptBaseClass.KFM_REVERSE:
12611 mode = KeyframeMotion.PlayMode.Reverse;
12612 break;
12613 case ScriptBaseClass.KFM_LOOP:
12614 mode = KeyframeMotion.PlayMode.Loop;
12615 break;
12616 case ScriptBaseClass.KFM_PING_PONG:
12617 mode = KeyframeMotion.PlayMode.PingPong;
12618 break;
12619 }
12620 break;
12621 case ScriptBaseClass.KFM_DATA:
12622 if (remain < 1)
12623 break;
12624 int dataval = (int)options.GetLSLIntegerItem(idx++);
12625 data = (KeyframeMotion.DataFormat)dataval;
12626 break;
12627 }
12628 }
12629
12630 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12631
12632 idx = 0;
12633
12634 int elemLength = 2;
12635 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12636 elemLength = 3;
12637
12638 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12639 while (idx < frames.Data.Length)
12640 {
12641 int remain = frames.Data.Length - idx;
12642
12643 if (remain < elemLength)
12644 break;
12645
12646 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12647 frame.Position = null;
12648 frame.Rotation = null;
12649
12650 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12651 {
12652 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12653 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12654 }
12655 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12656 {
12657 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12658 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12659 }
12660
12661 float tempf = (float)frames.GetLSLFloatItem(idx++);
12662 frame.TimeMS = (int)(tempf * 1000.0f);
12663
12664 keyframes.Add(frame);
12665 }
12666
12667 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12668 group.RootPart.KeyframeMotion.Start();
12669 }
12670 else
12671 {
12672 if (group.RootPart.KeyframeMotion == null)
12673 return;
12674
12675 if (options.Data.Length == 0)
12676 {
12677 group.RootPart.KeyframeMotion.Stop();
12678 return;
12679 }
12680
12681 int code = (int)options.GetLSLIntegerItem(0);
12682
12683 int idx = 0;
12684
12685 while (idx < options.Data.Length)
12686 {
12687 int option = (int)options.GetLSLIntegerItem(idx++);
12688 int remain = options.Data.Length - idx;
12689
12690 switch (option)
12691 {
12692 case ScriptBaseClass.KFM_COMMAND:
12693 int cmd = (int)options.GetLSLIntegerItem(idx++);
12694 switch (cmd)
12695 {
12696 case ScriptBaseClass.KFM_CMD_PLAY:
12697 group.RootPart.KeyframeMotion.Start();
12698 break;
12699 case ScriptBaseClass.KFM_CMD_STOP:
12700 group.RootPart.KeyframeMotion.Stop();
12701 break;
12702 case ScriptBaseClass.KFM_CMD_PAUSE:
12703 group.RootPart.KeyframeMotion.Pause();
12704 break;
12705 }
12706 break;
12707 }
12708 }
12709 }
12710 }
12711
12712 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12713 {
12714 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12715
12716 int idx = 0;
12717 int idxStart = 0;
12718
12719 bool positionChanged = false;
12720 Vector3 finalPos = Vector3.Zero;
12721
12722 try
12723 {
12724 while (idx < rules.Length)
12725 {
12726 ++rulesParsed;
12727 int code = rules.GetLSLIntegerItem(idx++);
12728
12729 int remain = rules.Length - idx;
12730 idxStart = idx;
12731
12732 switch (code)
12733 {
12734 case (int)ScriptBaseClass.PRIM_POSITION:
12735 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12736 {
12737 if (remain < 1)
12738 return null;
12739
12740 LSL_Vector v;
12741 v = rules.GetVector3Item(idx++);
12742
12743 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12744 if (part == null)
12745 break;
12746
12747 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12748 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12749 if (part.LinkNum > 1)
12750 {
12751 localRot = GetPartLocalRot(part);
12752 localPos = GetPartLocalPos(part);
12753 }
12754
12755 v -= localPos;
12756 v /= localRot;
12757
12758 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12759
12760 v = v + 2 * sitOffset;
12761
12762 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12763 av.SendAvatarDataToAllAgents();
12764
12765 }
12766 break;
12767
12768 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12769 case (int)ScriptBaseClass.PRIM_ROTATION:
12770 {
12771 if (remain < 1)
12772 return null;
12773
12774 LSL_Rotation r;
12775 r = rules.GetQuaternionItem(idx++);
12776
12777 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12778 if (part == null)
12779 break;
12780
12781 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12782 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12783
12784 if (part.LinkNum > 1)
12785 localRot = GetPartLocalRot(part);
12786
12787 r = r * llGetRootRotation() / localRot;
12788 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12789 av.SendAvatarDataToAllAgents();
12790 }
12791 break;
12792
12793 // parse rest doing nothing but number of parameters error check
12794 case (int)ScriptBaseClass.PRIM_SIZE:
12795 case (int)ScriptBaseClass.PRIM_MATERIAL:
12796 case (int)ScriptBaseClass.PRIM_PHANTOM:
12797 case (int)ScriptBaseClass.PRIM_PHYSICS:
12798 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12799 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12800 case (int)ScriptBaseClass.PRIM_NAME:
12801 case (int)ScriptBaseClass.PRIM_DESC:
12802 if (remain < 1)
12803 return null;
12804 idx++;
12805 break;
12806
12807 case (int)ScriptBaseClass.PRIM_GLOW:
12808 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12809 case (int)ScriptBaseClass.PRIM_TEXGEN:
12810 if (remain < 2)
12811 return null;
12812 idx += 2;
12813 break;
12814
12815 case (int)ScriptBaseClass.PRIM_TYPE:
12816 if (remain < 3)
12817 return null;
12818 code = (int)rules.GetLSLIntegerItem(idx++);
12819 remain = rules.Length - idx;
12820 switch (code)
12821 {
12822 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12823 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12824 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12825 if (remain < 6)
12826 return null;
12827 idx += 6;
12828 break;
12829
12830 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12831 if (remain < 5)
12832 return null;
12833 idx += 5;
12834 break;
12835
12836 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12837 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12838 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12839 if (remain < 11)
12840 return null;
12841 idx += 11;
12842 break;
12843
12844 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12845 if (remain < 2)
12846 return null;
12847 idx += 2;
12848 break;
12849 }
12850 break;
12851
12852 case (int)ScriptBaseClass.PRIM_COLOR:
12853 case (int)ScriptBaseClass.PRIM_TEXT:
12854 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12855 case (int)ScriptBaseClass.PRIM_OMEGA:
12856 if (remain < 3)
12857 return null;
12858 idx += 3;
12859 break;
12860
12861 case (int)ScriptBaseClass.PRIM_TEXTURE:
12862 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12863 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12864 if (remain < 5)
12865 return null;
12866 idx += 5;
12867 break;
12868
12869 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12870 if (remain < 7)
12871 return null;
12872
12873 idx += 7;
12874 break;
12875
12876 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12877 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12878 return null;
12879
12880 return rules.GetSublist(idx, -1);
12881 }
12882 }
12883 }
12884 catch (InvalidCastException e)
12885 {
12886 ShoutError(string.Format(
12887 "{0} error running rule #{1}: arg #{2} ",
12888 originFunc, rulesParsed, idx - idxStart) + e.Message);
12889 }
12890 finally
12891 {
12892 if (positionChanged)
12893 {
12894 av.OffsetPosition = finalPos;
12895// av.SendAvatarDataToAllAgents();
12896 av.SendTerseUpdateToAllClients();
12897 positionChanged = false;
12898 }
12899 }
12900 return null;
12901 }
12902
12903 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12904 {
12905 // avatars case
12906 // replies as SL wiki
12907
12908// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12909 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12910
12911 int idx = 0;
12912 while (idx < rules.Length)
12913 {
12914 int code = (int)rules.GetLSLIntegerItem(idx++);
12915 int remain = rules.Length - idx;
12916
12917 switch (code)
12918 {
12919 case (int)ScriptBaseClass.PRIM_MATERIAL:
12920 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12921 break;
12922
12923 case (int)ScriptBaseClass.PRIM_PHYSICS:
12924 res.Add(new LSL_Integer(0));
12925 break;
12926
12927 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12928 res.Add(new LSL_Integer(0));
12929 break;
12930
12931 case (int)ScriptBaseClass.PRIM_PHANTOM:
12932 res.Add(new LSL_Integer(0));
12933 break;
12934
12935 case (int)ScriptBaseClass.PRIM_POSITION:
12936
12937 Vector3 pos = avatar.OffsetPosition;
12938
12939 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12940 pos -= sitOffset;
12941
12942 if( sitPart != null)
12943 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12944
12945 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12946 break;
12947
12948 case (int)ScriptBaseClass.PRIM_SIZE:
12949 // as in llGetAgentSize above
12950// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12951 Vector3 s = avatar.Appearance.AvatarSize;
12952 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
12953
12954 break;
12955
12956 case (int)ScriptBaseClass.PRIM_ROTATION:
12957 Quaternion rot = avatar.Rotation;
12958 if (sitPart != null)
12959 {
12960 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12961 }
12962
12963 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12964 break;
12965
12966 case (int)ScriptBaseClass.PRIM_TYPE:
12967 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12968 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12969 res.Add(new LSL_Vector(0f,1.0f,0f));
12970 res.Add(new LSL_Float(0.0f));
12971 res.Add(new LSL_Vector(0, 0, 0));
12972 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12973 res.Add(new LSL_Vector(0, 0, 0));
12974 break;
12975
12976 case (int)ScriptBaseClass.PRIM_TEXTURE:
12977 if (remain < 1)
12978 return null;
12979
12980 int face = (int)rules.GetLSLIntegerItem(idx++);
12981 if (face == ScriptBaseClass.ALL_SIDES)
12982 {
12983 for (face = 0; face < 21; face++)
12984 {
12985 res.Add(new LSL_String(""));
12986 res.Add(new LSL_Vector(0,0,0));
12987 res.Add(new LSL_Vector(0,0,0));
12988 res.Add(new LSL_Float(0.0));
12989 }
12990 }
12991 else
12992 {
12993 if (face >= 0 && face < 21)
12994 {
12995 res.Add(new LSL_String(""));
12996 res.Add(new LSL_Vector(0,0,0));
12997 res.Add(new LSL_Vector(0,0,0));
12998 res.Add(new LSL_Float(0.0));
12999 }
13000 }
13001 break;
13002
13003 case (int)ScriptBaseClass.PRIM_COLOR:
13004 if (remain < 1)
13005 return null;
13006
13007 face = (int)rules.GetLSLIntegerItem(idx++);
13008
13009 if (face == ScriptBaseClass.ALL_SIDES)
13010 {
13011 for (face = 0; face < 21; face++)
13012 {
13013 res.Add(new LSL_Vector(0,0,0));
13014 res.Add(new LSL_Float(0));
13015 }
13016 }
13017 else
13018 {
13019 res.Add(new LSL_Vector(0,0,0));
13020 res.Add(new LSL_Float(0));
13021 }
13022 break;
13023
13024 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13025 if (remain < 1)
13026 return null;
13027 face = (int)rules.GetLSLIntegerItem(idx++);
13028
13029 if (face == ScriptBaseClass.ALL_SIDES)
13030 {
13031 for (face = 0; face < 21; face++)
13032 {
13033 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13034 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13035 }
13036 }
13037 else
13038 {
13039 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13040 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13041 }
13042 break;
13043
13044 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13045 if (remain < 1)
13046 return null;
13047 face = (int)rules.GetLSLIntegerItem(idx++);
13048
13049 if (face == ScriptBaseClass.ALL_SIDES)
13050 {
13051 for (face = 0; face < 21; face++)
13052 {
13053 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13054 }
13055 }
13056 else
13057 {
13058 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13059 }
13060 break;
13061
13062 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13063 res.Add(new LSL_Integer(0));
13064 res.Add(new LSL_Integer(0));// softness
13065 res.Add(new LSL_Float(0.0f)); // gravity
13066 res.Add(new LSL_Float(0.0f)); // friction
13067 res.Add(new LSL_Float(0.0f)); // wind
13068 res.Add(new LSL_Float(0.0f)); // tension
13069 res.Add(new LSL_Vector(0f,0f,0f));
13070 break;
13071
13072 case (int)ScriptBaseClass.PRIM_TEXGEN:
13073 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13074 if (remain < 1)
13075 return null;
13076 face = (int)rules.GetLSLIntegerItem(idx++);
13077
13078 if (face == ScriptBaseClass.ALL_SIDES)
13079 {
13080 for (face = 0; face < 21; face++)
13081 {
13082 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13083 }
13084 }
13085 else
13086 {
13087 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13088 }
13089 break;
13090
13091 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13092 res.Add(new LSL_Integer(0));
13093 res.Add(new LSL_Vector(0f,0f,0f));
13094 res.Add(new LSL_Float(0f)); // intensity
13095 res.Add(new LSL_Float(0f)); // radius
13096 res.Add(new LSL_Float(0f)); // falloff
13097 break;
13098
13099 case (int)ScriptBaseClass.PRIM_GLOW:
13100 if (remain < 1)
13101 return null;
13102 face = (int)rules.GetLSLIntegerItem(idx++);
13103
13104 if (face == ScriptBaseClass.ALL_SIDES)
13105 {
13106 for (face = 0; face < 21; face++)
13107 {
13108 res.Add(new LSL_Float(0f));
13109 }
13110 }
13111 else
13112 {
13113 res.Add(new LSL_Float(0f));
13114 }
13115 break;
13116
13117 case (int)ScriptBaseClass.PRIM_TEXT:
13118 res.Add(new LSL_String(""));
13119 res.Add(new LSL_Vector(0f,0f,0f));
13120 res.Add(new LSL_Float(1.0f));
13121 break;
13122
13123 case (int)ScriptBaseClass.PRIM_NAME:
13124 res.Add(new LSL_String(avatar.Name));
13125 break;
13126
13127 case (int)ScriptBaseClass.PRIM_DESC:
13128 res.Add(new LSL_String(""));
13129 break;
13130
13131 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13132 Quaternion lrot = avatar.Rotation;
13133
13134 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13135 {
13136 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13137 }
13138 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13139 break;
13140
13141 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13142 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13143 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13144 lpos -= lsitOffset;
13145
13146 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13147 {
13148 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13149 }
13150 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13151 break;
13152
13153 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13154 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13155 return null;
13156
13157 return rules.GetSublist(idx, -1);
13158 }
13159 }
13160
13161 return null;
13162 }
11460 } 13163 }
11461 13164
11462 public class NotecardCache 13165 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 33c02ef..637d83a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -138,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
139 internal float m_ScriptDelayFactor = 1.0f; 139 internal float m_ScriptDelayFactor = 1.0f;
140 internal float m_ScriptDistanceFactor = 1.0f; 140 internal float m_ScriptDistanceFactor = 1.0f;
141 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 143
143 protected IUrlModule m_UrlModule = null; 144 protected IUrlModule m_UrlModule = null;
@@ -147,6 +148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
147 m_ScriptEngine = ScriptEngine; 148 m_ScriptEngine = ScriptEngine;
148 m_host = host; 149 m_host = host;
149 m_item = item; 150 m_item = item;
151 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
150 152
151 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 153 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
152 154
@@ -210,7 +212,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
210 212
211 internal void OSSLError(string msg) 213 internal void OSSLError(string msg)
212 { 214 {
213 throw new ScriptException("OSSL Runtime Error: " + msg); 215 if (m_debuggerSafe)
216 {
217 OSSLShoutError(msg);
218 }
219 else
220 {
221 throw new ScriptException("OSSL Runtime Error: " + msg);
222 }
214 } 223 }
215 224
216 /// <summary> 225 /// <summary>
@@ -918,18 +927,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
918 if (target != null) 927 if (target != null)
919 { 928 {
920 UUID animID=UUID.Zero; 929 UUID animID=UUID.Zero;
921 lock (m_host.TaskInventory) 930 m_host.TaskInventory.LockItemsForRead(true);
931 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
922 { 932 {
923 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 933 if (inv.Value.Name == animation)
924 { 934 {
925 if (inv.Value.Name == animation) 935 if (inv.Value.Type == (int)AssetType.Animation)
926 { 936 animID = inv.Value.AssetID;
927 if (inv.Value.Type == (int)AssetType.Animation) 937 continue;
928 animID = inv.Value.AssetID;
929 continue;
930 }
931 } 938 }
932 } 939 }
940 m_host.TaskInventory.LockItemsForRead(false);
933 if (animID == UUID.Zero) 941 if (animID == UUID.Zero)
934 target.Animator.AddAnimation(animation, m_host.UUID); 942 target.Animator.AddAnimation(animation, m_host.UUID);
935 else 943 else
@@ -970,6 +978,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
970 else 978 else
971 animID = UUID.Zero; 979 animID = UUID.Zero;
972 } 980 }
981 m_host.TaskInventory.LockItemsForRead(false);
973 982
974 if (animID == UUID.Zero) 983 if (animID == UUID.Zero)
975 target.Animator.RemoveAnimation(animation); 984 target.Animator.RemoveAnimation(animation);
@@ -1812,6 +1821,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1812 1821
1813 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1822 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1814 { 1823 {
1824 m_host.TaskInventory.LockItemsForRead(true);
1815 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1825 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1816 { 1826 {
1817 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1827 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1819,6 +1829,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1819 assetID = item.AssetID; 1829 assetID = item.AssetID;
1820 } 1830 }
1821 } 1831 }
1832 m_host.TaskInventory.LockItemsForRead(false);
1822 } 1833 }
1823 1834
1824 if (assetID == UUID.Zero) 1835 if (assetID == UUID.Zero)
@@ -2304,7 +2315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2304 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2315 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2305 m_host.AddScriptLPS(1); 2316 m_host.AddScriptLPS(1);
2306 2317
2307 return NpcCreate(firstname, lastname, position, notecard, false, false); 2318 return NpcCreate(firstname, lastname, position, notecard, true, false);
2308 } 2319 }
2309 2320
2310 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2321 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2315,24 +2326,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2315 return NpcCreate( 2326 return NpcCreate(
2316 firstname, lastname, position, notecard, 2327 firstname, lastname, position, notecard,
2317 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2328 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2318 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2329 false);
2330// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2319 } 2331 }
2320 2332
2321 private LSL_Key NpcCreate( 2333 private LSL_Key NpcCreate(
2322 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2334 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2323 { 2335 {
2336 if (!owned)
2337 OSSLError("Unowned NPCs are unsupported");
2338
2339 string groupTitle = String.Empty;
2340
2341 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2342 return new LSL_Key(UUID.Zero.ToString());
2343
2344 if (firstname != String.Empty || lastname != String.Empty)
2345 {
2346 if (firstname != "Shown outfit:")
2347 groupTitle = "- NPC -";
2348 }
2349
2324 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2350 INPCModule module = World.RequestModuleInterface<INPCModule>();
2325 if (module != null) 2351 if (module != null)
2326 { 2352 {
2327 AvatarAppearance appearance = null; 2353 AvatarAppearance appearance = null;
2328 2354
2329 UUID id; 2355// UUID id;
2330 if (UUID.TryParse(notecard, out id)) 2356// if (UUID.TryParse(notecard, out id))
2331 { 2357// {
2332 ScenePresence clonePresence = World.GetScenePresence(id); 2358// ScenePresence clonePresence = World.GetScenePresence(id);
2333 if (clonePresence != null) 2359// if (clonePresence != null)
2334 appearance = clonePresence.Appearance; 2360// appearance = clonePresence.Appearance;
2335 } 2361// }
2336 2362
2337 if (appearance == null) 2363 if (appearance == null)
2338 { 2364 {
@@ -2340,9 +2366,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2340 2366
2341 if (appearanceSerialized != null) 2367 if (appearanceSerialized != null)
2342 { 2368 {
2343 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2369 try
2344 appearance = new AvatarAppearance(); 2370 {
2345 appearance.Unpack(appearanceOsd); 2371 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2372 appearance = new AvatarAppearance();
2373 appearance.Unpack(appearanceOsd);
2374 }
2375 catch
2376 {
2377 return UUID.Zero.ToString();
2378 }
2346 } 2379 }
2347 else 2380 else
2348 { 2381 {
@@ -2361,6 +2394,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2361 World, 2394 World,
2362 appearance); 2395 appearance);
2363 2396
2397 ScenePresence sp;
2398 if (World.TryGetScenePresence(x, out sp))
2399 {
2400 sp.Grouptitle = groupTitle;
2401 sp.SendAvatarDataToAllAgents();
2402 }
2364 return new LSL_Key(x.ToString()); 2403 return new LSL_Key(x.ToString());
2365 } 2404 }
2366 2405
@@ -2664,16 +2703,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2664 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2703 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2665 m_host.AddScriptLPS(1); 2704 m_host.AddScriptLPS(1);
2666 2705
2667 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2706 ManualResetEvent ev = new ManualResetEvent(false);
2668 if (module != null)
2669 {
2670 UUID npcId = new UUID(npc.m_string);
2671 2707
2672 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2708 Util.FireAndForget(delegate(object x) {
2673 return; 2709 try
2710 {
2711 INPCModule module = World.RequestModuleInterface<INPCModule>();
2712 if (module != null)
2713 {
2714 UUID npcId = new UUID(npc.m_string);
2674 2715
2675 module.DeleteNPC(npcId, World); 2716 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2676 } 2717 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2718 {
2719 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2720 return;
2721 }
2722
2723 module.DeleteNPC(npcId, World);
2724 }
2725 }
2726 finally
2727 {
2728 ev.Set();
2729 }
2730 });
2731 ev.WaitOne();
2677 } 2732 }
2678 2733
2679 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2734 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 24cceea..4dd795d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -70,7 +70,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
70 private const int AGENT = 1; 70 private const int AGENT = 1;
71 private const int AGENT_BY_USERNAME = 0x10; 71 private const int AGENT_BY_USERNAME = 0x10;
72 private const int NPC = 0x20; 72 private const int NPC = 0x20;
73 private const int OS_NPC = 0x01000000;
74 private const int ACTIVE = 2; 73 private const int ACTIVE = 2;
75 private const int PASSIVE = 4; 74 private const int PASSIVE = 4;
76 private const int SCRIPTED = 8; 75 private const int SCRIPTED = 8;
@@ -235,7 +234,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
235 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 234 List<SensedEntity> sensedEntities = new List<SensedEntity>();
236 235
237 // Is the sensor type is AGENT and not SCRIPTED then include agents 236 // Is the sensor type is AGENT and not SCRIPTED then include agents
238 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 237 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
239 { 238 {
240 sensedEntities.AddRange(doAgentSensor(ts)); 239 sensedEntities.AddRange(doAgentSensor(ts));
241 } 240 }
@@ -334,7 +333,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
334 float dy; 333 float dy;
335 float dz; 334 float dz;
336 335
337 Quaternion q = SensePoint.GetWorldRotation(); 336// Quaternion q = SensePoint.RotationOffset;
337 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
338 if (SensePoint.ParentGroup.IsAttachment) 338 if (SensePoint.ParentGroup.IsAttachment)
339 { 339 {
340 // In attachments, rotate the sensor cone with the 340 // In attachments, rotate the sensor cone with the
@@ -348,7 +348,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
348 // Position of a sensor in a child prim attached to an avatar 348 // Position of a sensor in a child prim attached to an avatar
349 // will be still wrong. 349 // will be still wrong.
350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
351 q = avatar.Rotation * q; 351 fromRegionPos = avatar.AbsolutePosition;
352 q = avatar.Rotation;
352 } 353 }
353 354
354 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -475,7 +476,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
475 // Position of a sensor in a child prim attached to an avatar 476 // Position of a sensor in a child prim attached to an avatar
476 // will be still wrong. 477 // will be still wrong.
477 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 478 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
478 q = avatar.Rotation * q; 479 if (avatar == null)
480 return sensedEntities;
481 fromRegionPos = avatar.AbsolutePosition;
482 q = avatar.Rotation;
479 } 483 }
480 484
481 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 485 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -491,7 +495,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
491// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 495// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
492// presence.Name, presence.PresenceType, ts.name, ts.type); 496// presence.Name, presence.PresenceType, ts.name, ts.type);
493 497
494 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 498 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
495 { 499 {
496 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 500 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
497 if (npcData == null || !npcData.SenseAsAgent) 501 if (npcData == null || !npcData.SenseAsAgent)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index bc63030..9ee6946 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -118,25 +118,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
118 if (Timers.Count == 0) 118 if (Timers.Count == 0)
119 return; 119 return;
120 120
121 Dictionary<string, TimerClass>.ValueCollection tvals;
121 lock (TimerListLock) 122 lock (TimerListLock)
122 { 123 {
123 // Go through all timers 124 // Go through all timers
124 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 125 tvals = Timers.Values;
125 foreach (TimerClass ts in tvals) 126 }
127
128 foreach (TimerClass ts in tvals)
129 {
130 // Time has passed?
131 if (ts.next < DateTime.Now.Ticks)
126 { 132 {
127 // Time has passed? 133 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
128 if (ts.next < DateTime.Now.Ticks) 134 // Add it to queue
129 { 135 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
130 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 136 new EventParams("timer", new Object[0],
131 // Add it to queue 137 new DetectParams[0]));
132 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 138 // set next interval
133 new EventParams("timer", new Object[0], 139
134 new DetectParams[0])); 140 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 // set next interval 141 ts.next = DateTime.Now.Ticks + ts.interval;
136
137 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
138 ts.next = DateTime.Now.Ticks + ts.interval;
139 }
140 } 142 }
141 } 143 }
142 } 144 }