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.cs3271
-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, 2754 insertions, 817 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..9ae9b59 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);
@@ -2128,8 +2359,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2128 { 2359 {
2129 m_host.AddScriptLPS(1); 2360 m_host.AddScriptLPS(1);
2130 2361
2362
2363 // Teravus: if (m_host.ParentID == 0) is bug code because the ParentID for the Avatar will cause this to be nonzero for root prim attachments
2364 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2365 // to fix the scripted rotations we also have to check to see if the root part localid is the same as the host's localid.
2366 // RootPart != null should shortcircuit
2367
2131 // try to let this work as in SL... 2368 // try to let this work as in SL...
2132 if (m_host.ParentID == 0) 2369 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2133 { 2370 {
2134 // special case: If we are root, rotate complete SOG to new rotation 2371 // special case: If we are root, rotate complete SOG to new rotation
2135 SetRot(m_host, rot); 2372 SetRot(m_host, rot);
@@ -2156,25 +2393,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2156 2393
2157 protected void SetRot(SceneObjectPart part, Quaternion rot) 2394 protected void SetRot(SceneObjectPart part, Quaternion rot)
2158 { 2395 {
2159 part.UpdateRotation(rot); 2396 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. 2397 return;
2161 2398
2162//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2399 bool isroot = (part == part.ParentGroup.RootPart);
2163// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2400 bool isphys;
2164 2401
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; 2402 PhysicsActor pa = part.PhysActor;
2173 2403
2174 if (pa != null && !pa.IsPhysical) 2404 // keep using physactor ideia of isphysical
2405 // it should be SOP ideia of that
2406 // not much of a issue with ubitODE
2407 if (pa != null && pa.IsPhysical)
2408 isphys = true;
2409 else
2410 isphys = false;
2411
2412 // SL doesn't let scripts rotate root of physical linksets
2413 if (isroot && isphys)
2414 return;
2415
2416 part.UpdateRotation(rot);
2417
2418 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2419 // so do a nasty update of parts positions if is a root part rotation
2420 if (isroot && pa != null) // with if above implies non physical root part
2175 { 2421 {
2176 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2422 part.ParentGroup.ResetChildPrimPhysicsPositions();
2177 } 2423 }
2424 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2425 {
2426 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2427 if (sittingavas.Count > 0)
2428 {
2429 foreach (ScenePresence av in sittingavas)
2430 {
2431 if (isroot || part.LocalId == av.ParentID)
2432 av.SendTerseUpdateToAllClients();
2433 }
2434 }
2435 }
2178 } 2436 }
2179 2437
2180 /// <summary> 2438 /// <summary>
@@ -2191,6 +2449,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2191 2449
2192 m_host.AddScriptLPS(1); 2450 m_host.AddScriptLPS(1);
2193 Quaternion q = m_host.GetWorldRotation(); 2451 Quaternion q = m_host.GetWorldRotation();
2452
2453 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2454 {
2455 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2456 if (avatar != null)
2457 {
2458 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2459 q = avatar.CameraRotation * q; // Mouselook
2460 else
2461 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2462 }
2463 }
2464
2194 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2465 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2195 } 2466 }
2196 2467
@@ -2216,14 +2487,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2216 q = part.ParentGroup.GroupRotation; // just the group rotation 2487 q = part.ParentGroup.GroupRotation; // just the group rotation
2217 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2488 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2218 } 2489 }
2490
2219 q = part.GetWorldRotation(); 2491 q = part.GetWorldRotation();
2492 if (part.ParentGroup.AttachmentPoint != 0)
2493 {
2494 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2495 if (avatar != null)
2496 {
2497 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2498 q = avatar.CameraRotation * q; // Mouselook
2499 else
2500 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2501 }
2502 }
2503
2220 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2504 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2221 } 2505 }
2222 2506
2223 public LSL_Rotation llGetLocalRot() 2507 public LSL_Rotation llGetLocalRot()
2224 { 2508 {
2509 return GetPartLocalRot(m_host);
2510 }
2511
2512 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2513 {
2225 m_host.AddScriptLPS(1); 2514 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); 2515 Quaternion rot = part.RotationOffset;
2516 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2227 } 2517 }
2228 2518
2229 public void llSetForce(LSL_Vector force, int local) 2519 public void llSetForce(LSL_Vector force, int local)
@@ -2303,16 +2593,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2303 m_host.ApplyImpulse(v, local != 0); 2593 m_host.ApplyImpulse(v, local != 0);
2304 } 2594 }
2305 2595
2596
2306 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2597 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2307 { 2598 {
2308 m_host.AddScriptLPS(1); 2599 m_host.AddScriptLPS(1);
2309 m_host.ApplyAngularImpulse(force, local != 0); 2600 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2310 } 2601 }
2311 2602
2312 public void llSetTorque(LSL_Vector torque, int local) 2603 public void llSetTorque(LSL_Vector torque, int local)
2313 { 2604 {
2314 m_host.AddScriptLPS(1); 2605 m_host.AddScriptLPS(1);
2315 m_host.SetAngularImpulse(torque, local != 0); 2606 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2316 } 2607 }
2317 2608
2318 public LSL_Vector llGetTorque() 2609 public LSL_Vector llGetTorque()
@@ -2329,20 +2620,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2329 llSetTorque(torque, local); 2620 llSetTorque(torque, local);
2330 } 2621 }
2331 2622
2623 public void llSetVelocity(LSL_Vector vel, int local)
2624 {
2625 m_host.AddScriptLPS(1);
2626 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2627 }
2628
2332 public LSL_Vector llGetVel() 2629 public LSL_Vector llGetVel()
2333 { 2630 {
2334 m_host.AddScriptLPS(1); 2631 m_host.AddScriptLPS(1);
2335 2632
2336 Vector3 vel; 2633 Vector3 vel = Vector3.Zero;
2337 2634
2338 if (m_host.ParentGroup.IsAttachment) 2635 if (m_host.ParentGroup.IsAttachment)
2339 { 2636 {
2340 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2637 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2341 vel = avatar.Velocity; 2638 if (avatar != null)
2639 vel = avatar.Velocity;
2342 } 2640 }
2343 else 2641 else
2344 { 2642 {
2345 vel = m_host.Velocity; 2643 vel = m_host.ParentGroup.RootPart.Velocity;
2346 } 2644 }
2347 2645
2348 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2646 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2354,10 +2652,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2354 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2652 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2355 } 2653 }
2356 2654
2655 public void llSetAngularVelocity(LSL_Vector avel, int local)
2656 {
2657 m_host.AddScriptLPS(1);
2658 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2659 }
2660
2357 public LSL_Vector llGetOmega() 2661 public LSL_Vector llGetOmega()
2358 { 2662 {
2359 m_host.AddScriptLPS(1); 2663 m_host.AddScriptLPS(1);
2360 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2664 Vector3 avel = m_host.AngularVelocity;
2665 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2361 } 2666 }
2362 2667
2363 public LSL_Float llGetTimeOfDay() 2668 public LSL_Float llGetTimeOfDay()
@@ -2746,7 +3051,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2746 } 3051 }
2747 3052
2748 bool result = money.ObjectGiveMoney( 3053 bool result = money.ObjectGiveMoney(
2749 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3054 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2750 3055
2751 if (result) 3056 if (result)
2752 return 1; 3057 return 1;
@@ -2830,13 +3135,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2830 new_group.RootPart.UUID.ToString()) }, 3135 new_group.RootPart.UUID.ToString()) },
2831 new DetectParams[0])); 3136 new DetectParams[0]));
2832 3137
2833 float groupmass = new_group.GetMass(); 3138 // do recoil
3139 SceneObjectGroup hostgrp = m_host.ParentGroup;
3140 if (hostgrp == null)
3141 return;
3142
3143 if (hostgrp.IsAttachment) // don't recoil avatars
3144 return;
2834 3145
2835 PhysicsActor pa = new_group.RootPart.PhysActor; 3146 PhysicsActor pa = new_group.RootPart.PhysActor;
2836 3147
2837 //Recoil. 3148 //Recoil.
2838 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3149 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2839 { 3150 {
3151 float groupmass = new_group.GetMass();
2840 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3152 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2841 if (recoil != Vector3.Zero) 3153 if (recoil != Vector3.Zero)
2842 { 3154 {
@@ -2844,6 +3156,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2844 } 3156 }
2845 } 3157 }
2846 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3158 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3159 return;
3160
2847 }); 3161 });
2848 3162
2849 //ScriptSleep((int)((groupmass * velmag) / 10)); 3163 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2858,35 +3172,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2858 public void llLookAt(LSL_Vector target, double strength, double damping) 3172 public void llLookAt(LSL_Vector target, double strength, double damping)
2859 { 3173 {
2860 m_host.AddScriptLPS(1); 3174 m_host.AddScriptLPS(1);
2861 // Determine where we are looking from
2862 LSL_Vector from = llGetPos();
2863 3175
2864 // Work out the normalised vector from the source to the target 3176 // Get the normalized vector to the target
2865 LSL_Vector delta = llVecNorm(target - from); 3177 LSL_Vector d1 = llVecNorm(target - llGetPos());
2866 LSL_Vector angle = new LSL_Vector(0,0,0);
2867 3178
2868 // Calculate the yaw 3179 // Get the bearing (yaw)
2869 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3180 LSL_Vector a1 = new LSL_Vector(0,0,0);
2870 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3181 a1.z = llAtan2(d1.y, d1.x);
2871 3182
2872 // Calculate pitch 3183 // Get the elevation (pitch)
2873 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3184 LSL_Vector a2 = new LSL_Vector(0,0,0);
3185 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2874 3186
2875 // we need to convert from a vector describing 3187 LSL_Rotation r1 = llEuler2Rot(a1);
2876 // the angles of rotation in radians into rotation value 3188 LSL_Rotation r2 = llEuler2Rot(a2);
2877 LSL_Rotation rot = llEuler2Rot(angle); 3189 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 3190
2883 if (strength == 0 || pa == null || !pa.IsPhysical) 3191 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2884 { 3192 {
2885 llSetRot(rot); 3193 // Do nothing if either value is 0 (this has been checked in SL)
3194 if (strength <= 0.0 || damping <= 0.0)
3195 return;
3196
3197 llSetRot(r3 * r2 * r1);
2886 } 3198 }
2887 else 3199 else
2888 { 3200 {
2889 m_host.StartLookAt(rot, (float)strength, (float)damping); 3201 if (strength == 0)
3202 {
3203 llSetRot(r3 * r2 * r1);
3204 return;
3205 }
3206
3207 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2890 } 3208 }
2891 } 3209 }
2892 3210
@@ -2932,17 +3250,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2932 } 3250 }
2933 else 3251 else
2934 { 3252 {
2935 if (m_host.IsRoot) 3253 // new SL always returns object mass
2936 { 3254// if (m_host.IsRoot)
3255// {
2937 return m_host.ParentGroup.GetMass(); 3256 return m_host.ParentGroup.GetMass();
2938 } 3257// }
2939 else 3258// else
2940 { 3259// {
2941 return m_host.GetMass(); 3260// return m_host.GetMass();
2942 } 3261// }
2943 } 3262 }
2944 } 3263 }
2945 3264
3265
3266 public LSL_Float llGetMassMKS()
3267 {
3268 return 100f * llGetMass();
3269 }
3270
2946 public void llCollisionFilter(string name, string id, int accept) 3271 public void llCollisionFilter(string name, string id, int accept)
2947 { 3272 {
2948 m_host.AddScriptLPS(1); 3273 m_host.AddScriptLPS(1);
@@ -2990,8 +3315,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2990 { 3315 {
2991 // Unregister controls from Presence 3316 // Unregister controls from Presence
2992 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3317 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2993 // Remove Take Control permission.
2994 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
2995 } 3318 }
2996 } 3319 }
2997 } 3320 }
@@ -3019,7 +3342,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3019 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3342 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3020 3343
3021 if (attachmentsModule != null) 3344 if (attachmentsModule != null)
3022 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3345 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3023 else 3346 else
3024 return false; 3347 return false;
3025 } 3348 }
@@ -3049,9 +3372,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3049 { 3372 {
3050 m_host.AddScriptLPS(1); 3373 m_host.AddScriptLPS(1);
3051 3374
3052// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3053// return;
3054
3055 if (m_item.PermsGranter != m_host.OwnerID) 3375 if (m_item.PermsGranter != m_host.OwnerID)
3056 return; 3376 return;
3057 3377
@@ -3094,6 +3414,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3094 3414
3095 public void llInstantMessage(string user, string message) 3415 public void llInstantMessage(string user, string message)
3096 { 3416 {
3417 UUID result;
3418 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3419 {
3420 ShoutError("An invalid key was passed to llInstantMessage");
3421 ScriptSleep(2000);
3422 return;
3423 }
3424
3425
3097 m_host.AddScriptLPS(1); 3426 m_host.AddScriptLPS(1);
3098 3427
3099 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3428 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3108,14 +3437,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3108 UUID friendTransactionID = UUID.Random(); 3437 UUID friendTransactionID = UUID.Random();
3109 3438
3110 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3439 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3111 3440
3112 GridInstantMessage msg = new GridInstantMessage(); 3441 GridInstantMessage msg = new GridInstantMessage();
3113 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3442 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3114 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3443 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3115 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3444 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); 3445// 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()); 3446// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3118 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3447// DateTime dt = DateTime.UtcNow;
3448//
3449// // Ticks from UtcNow, but make it look like local. Evil, huh?
3450// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3451//
3452// try
3453// {
3454// // Convert that to the PST timezone
3455// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3456// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3457// }
3458// catch
3459// {
3460// // No logging here, as it could be VERY spammy
3461// }
3462//
3463// // And make it look local again to fool the unix time util
3464// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3465
3466 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3467
3119 //if (client != null) 3468 //if (client != null)
3120 //{ 3469 //{
3121 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3470 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3129,12 +3478,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3129 msg.message = message.Substring(0, 1024); 3478 msg.message = message.Substring(0, 1024);
3130 else 3479 else
3131 msg.message = message; 3480 msg.message = message;
3132 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3481 msg.dialog = (byte)19; // MessageFromObject
3133 msg.fromGroup = false;// fromGroup; 3482 msg.fromGroup = false;// fromGroup;
3134 msg.offline = (byte)0; //offline; 3483 msg.offline = (byte)0; //offline;
3135 msg.ParentEstateID = 0; //ParentEstateID; 3484 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3136 msg.Position = new Vector3(m_host.AbsolutePosition); 3485 msg.Position = new Vector3(m_host.AbsolutePosition);
3137 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3486 msg.RegionID = World.RegionInfo.RegionID.Guid;
3138 msg.binaryBucket 3487 msg.binaryBucket
3139 = Util.StringToBytes256( 3488 = Util.StringToBytes256(
3140 "{0}/{1}/{2}/{3}", 3489 "{0}/{1}/{2}/{3}",
@@ -3162,7 +3511,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3162 } 3511 }
3163 3512
3164 emailModule.SendEmail(m_host.UUID, address, subject, message); 3513 emailModule.SendEmail(m_host.UUID, address, subject, message);
3165 llSleep(EMAIL_PAUSE_TIME); 3514 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3166 } 3515 }
3167 3516
3168 public void llGetNextEmail(string address, string subject) 3517 public void llGetNextEmail(string address, string subject)
@@ -3408,7 +3757,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3408 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3757 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3409 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3758 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3410 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3759 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3760 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3411 ScriptBaseClass.PERMISSION_ATTACH; 3761 ScriptBaseClass.PERMISSION_ATTACH;
3762
3412 } 3763 }
3413 else 3764 else
3414 { 3765 {
@@ -3425,15 +3776,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3425 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3776 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3426 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3777 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3427 } 3778 }
3779 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3780 {
3781 implicitPerms = perm;
3782 }
3428 } 3783 }
3429 3784
3430 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3785 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3431 { 3786 {
3432 lock (m_host.TaskInventory) 3787 m_host.TaskInventory.LockItemsForWrite(true);
3433 { 3788 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3434 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3789 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3435 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3790 m_host.TaskInventory.LockItemsForWrite(false);
3436 }
3437 3791
3438 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3792 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3439 "run_time_permissions", new Object[] { 3793 "run_time_permissions", new Object[] {
@@ -3476,11 +3830,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3476 3830
3477 if (!m_waitingForScriptAnswer) 3831 if (!m_waitingForScriptAnswer)
3478 { 3832 {
3479 lock (m_host.TaskInventory) 3833 m_host.TaskInventory.LockItemsForWrite(true);
3480 { 3834 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3481 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3835 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3482 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3836 m_host.TaskInventory.LockItemsForWrite(false);
3483 }
3484 3837
3485 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3838 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3486 m_waitingForScriptAnswer=true; 3839 m_waitingForScriptAnswer=true;
@@ -3509,14 +3862,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3509 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3862 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3510 llReleaseControls(); 3863 llReleaseControls();
3511 3864
3512 lock (m_host.TaskInventory) 3865 m_host.TaskInventory.LockItemsForWrite(true);
3513 { 3866 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3514 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3867 m_host.TaskInventory.LockItemsForWrite(false);
3515 } 3868
3516 3869 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3517 m_ScriptEngine.PostScriptEvent( 3870 "run_time_permissions", new Object[] {
3518 m_item.ItemID, 3871 new LSL_Integer(answer) },
3519 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3872 new DetectParams[0]));
3520 } 3873 }
3521 3874
3522 public LSL_String llGetPermissionsKey() 3875 public LSL_String llGetPermissionsKey()
@@ -3555,14 +3908,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3555 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3908 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3556 { 3909 {
3557 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3910 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3558 3911 if (parts.Count > 0)
3559 foreach (SceneObjectPart part in parts) 3912 {
3560 part.SetFaceColorAlpha(face, color, null); 3913 try
3914 {
3915 foreach (SceneObjectPart part in parts)
3916 part.SetFaceColorAlpha(face, color, null);
3917 }
3918 finally
3919 {
3920 }
3921 }
3561 } 3922 }
3562 3923
3563 public void llCreateLink(string target, int parent) 3924 public void llCreateLink(string target, int parent)
3564 { 3925 {
3565 m_host.AddScriptLPS(1); 3926 m_host.AddScriptLPS(1);
3927
3566 UUID targetID; 3928 UUID targetID;
3567 3929
3568 if (!UUID.TryParse(target, out targetID)) 3930 if (!UUID.TryParse(target, out targetID))
@@ -3668,10 +4030,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3668 // Restructuring Multiple Prims. 4030 // Restructuring Multiple Prims.
3669 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4031 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3670 parts.Remove(parentPrim.RootPart); 4032 parts.Remove(parentPrim.RootPart);
3671 foreach (SceneObjectPart part in parts) 4033 if (parts.Count > 0)
3672 { 4034 {
3673 parentPrim.DelinkFromGroup(part.LocalId, true); 4035 try
4036 {
4037 foreach (SceneObjectPart part in parts)
4038 {
4039 parentPrim.DelinkFromGroup(part.LocalId, true);
4040 }
4041 }
4042 finally
4043 {
4044 }
3674 } 4045 }
4046
3675 parentPrim.HasGroupChanged = true; 4047 parentPrim.HasGroupChanged = true;
3676 parentPrim.ScheduleGroupForFullUpdate(); 4048 parentPrim.ScheduleGroupForFullUpdate();
3677 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4049 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3680,12 +4052,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3680 { 4052 {
3681 SceneObjectPart newRoot = parts[0]; 4053 SceneObjectPart newRoot = parts[0];
3682 parts.Remove(newRoot); 4054 parts.Remove(newRoot);
3683 foreach (SceneObjectPart part in parts) 4055
4056 try
3684 { 4057 {
3685 // Required for linking 4058 foreach (SceneObjectPart part in parts)
3686 part.ClearUpdateSchedule(); 4059 {
3687 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4060 part.ClearUpdateSchedule();
4061 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4062 }
3688 } 4063 }
4064 finally
4065 {
4066 }
4067
4068
3689 newRoot.ParentGroup.HasGroupChanged = true; 4069 newRoot.ParentGroup.HasGroupChanged = true;
3690 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4070 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3691 } 4071 }
@@ -3705,6 +4085,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3705 public void llBreakAllLinks() 4085 public void llBreakAllLinks()
3706 { 4086 {
3707 m_host.AddScriptLPS(1); 4087 m_host.AddScriptLPS(1);
4088
4089 TaskInventoryItem item = m_item;
4090
4091 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4092 && !m_automaticLinkPermission)
4093 {
4094 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4095 return;
4096 }
4097
3708 SceneObjectGroup parentPrim = m_host.ParentGroup; 4098 SceneObjectGroup parentPrim = m_host.ParentGroup;
3709 if (parentPrim.AttachmentPoint != 0) 4099 if (parentPrim.AttachmentPoint != 0)
3710 return; // Fail silently if attached 4100 return; // Fail silently if attached
@@ -3724,47 +4114,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3724 public LSL_String llGetLinkKey(int linknum) 4114 public LSL_String llGetLinkKey(int linknum)
3725 { 4115 {
3726 m_host.AddScriptLPS(1); 4116 m_host.AddScriptLPS(1);
3727 4117 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3728 if (linknum < 0) 4118 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 { 4119 {
3760 if (linknum <= actualPrimCount) 4120 return part.UUID.ToString();
3761 return m_host.ParentGroup.GetLinkNumPart(linknum).UUID.ToString();
3762 else
3763 return sittingAvatarIds[linknum - actualPrimCount - 1].ToString();
3764 } 4121 }
3765 else 4122 else
3766 { 4123 {
3767 return ScriptBaseClass.NULL_KEY; 4124 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4125 {
4126 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4127
4128 if (linknum < 0)
4129 return UUID.Zero.ToString();
4130
4131 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4132 if (avatars.Count > linknum)
4133 {
4134 return avatars[linknum].UUID.ToString();
4135 }
4136 }
4137 return UUID.Zero.ToString();
3768 } 4138 }
3769 } 4139 }
3770 4140
@@ -3867,17 +4237,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3867 m_host.AddScriptLPS(1); 4237 m_host.AddScriptLPS(1);
3868 int count = 0; 4238 int count = 0;
3869 4239
3870 lock (m_host.TaskInventory) 4240 m_host.TaskInventory.LockItemsForRead(true);
4241 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3871 { 4242 {
3872 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4243 if (inv.Value.Type == type || type == -1)
3873 { 4244 {
3874 if (inv.Value.Type == type || type == -1) 4245 count = count + 1;
3875 {
3876 count = count + 1;
3877 }
3878 } 4246 }
3879 } 4247 }
3880 4248
4249 m_host.TaskInventory.LockItemsForRead(false);
3881 return count; 4250 return count;
3882 } 4251 }
3883 4252
@@ -3886,16 +4255,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3886 m_host.AddScriptLPS(1); 4255 m_host.AddScriptLPS(1);
3887 ArrayList keys = new ArrayList(); 4256 ArrayList keys = new ArrayList();
3888 4257
3889 lock (m_host.TaskInventory) 4258 m_host.TaskInventory.LockItemsForRead(true);
4259 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3890 { 4260 {
3891 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4261 if (inv.Value.Type == type || type == -1)
3892 { 4262 {
3893 if (inv.Value.Type == type || type == -1) 4263 keys.Add(inv.Value.Name);
3894 {
3895 keys.Add(inv.Value.Name);
3896 }
3897 } 4264 }
3898 } 4265 }
4266 m_host.TaskInventory.LockItemsForRead(false);
3899 4267
3900 if (keys.Count == 0) 4268 if (keys.Count == 0)
3901 { 4269 {
@@ -3933,7 +4301,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3933 if (item == null) 4301 if (item == null)
3934 { 4302 {
3935 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4303 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)); 4304 return;
4305// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3937 } 4306 }
3938 4307
3939 UUID objId = item.ItemID; 4308 UUID objId = item.ItemID;
@@ -3961,33 +4330,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3961 return; 4330 return;
3962 } 4331 }
3963 } 4332 }
4333
3964 // destination is an avatar 4334 // destination is an avatar
3965 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4335 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3966 4336
3967 if (agentItem == null) 4337 if (agentItem == null)
3968 return; 4338 return;
3969 4339
3970 if (m_TransferModule != null) 4340 byte[] bucket = new byte[1];
3971 { 4341 bucket[0] = (byte)item.Type;
3972 byte[] bucket = new byte[1]; 4342 //byte[] objBytes = agentItem.ID.GetBytes();
3973 bucket[0] = (byte)item.Type; 4343 //Array.Copy(objBytes, 0, bucket, 1, 16);
3974 4344
3975 GridInstantMessage msg = new GridInstantMessage(World, 4345 GridInstantMessage msg = new GridInstantMessage(World,
3976 m_host.OwnerID, m_host.Name, destId, 4346 m_host.OwnerID, m_host.Name, destId,
3977 (byte)InstantMessageDialog.TaskInventoryOffered, 4347 (byte)InstantMessageDialog.TaskInventoryOffered,
3978 false, item.Name+". "+m_host.Name+" is located at "+ 4348 false, item.Name+". "+m_host.Name+" is located at "+
3979 World.RegionInfo.RegionName+" "+ 4349 World.RegionInfo.RegionName+" "+
3980 m_host.AbsolutePosition.ToString(), 4350 m_host.AbsolutePosition.ToString(),
3981 agentItem.ID, true, m_host.AbsolutePosition, 4351 agentItem.ID, true, m_host.AbsolutePosition,
3982 bucket, true); 4352 bucket, true);
3983 4353
3984 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4354 ScenePresence sp;
3985 }
3986 4355
4356 if (World.TryGetScenePresence(destId, out sp))
4357 {
4358 sp.ControllingClient.SendInstantMessage(msg);
4359 }
4360 else
4361 {
4362 if (m_TransferModule != null)
4363 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4364 }
4365
4366 //This delay should only occur when giving inventory to avatars.
3987 ScriptSleep(3000); 4367 ScriptSleep(3000);
3988 } 4368 }
3989 } 4369 }
3990 4370
4371 [DebuggerNonUserCode]
3991 public void llRemoveInventory(string name) 4372 public void llRemoveInventory(string name)
3992 { 4373 {
3993 m_host.AddScriptLPS(1); 4374 m_host.AddScriptLPS(1);
@@ -4042,109 +4423,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4042 { 4423 {
4043 m_host.AddScriptLPS(1); 4424 m_host.AddScriptLPS(1);
4044 4425
4045 UUID uuid = (UUID)id; 4426 UUID uuid;
4046 PresenceInfo pinfo = null; 4427 if (UUID.TryParse(id, out uuid))
4047 UserAccount account;
4048
4049 UserInfoCacheEntry ce;
4050 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4051 { 4428 {
4052 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4429 PresenceInfo pinfo = null;
4053 if (account == null) 4430 UserAccount account;
4431
4432 UserInfoCacheEntry ce;
4433 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4054 { 4434 {
4055 m_userInfoCache[uuid] = null; // Cache negative 4435 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4056 return UUID.Zero.ToString(); 4436 if (account == null)
4057 } 4437 {
4438 m_userInfoCache[uuid] = null; // Cache negative
4439 return UUID.Zero.ToString();
4440 }
4058 4441
4059 4442
4060 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4443 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4061 if (pinfos != null && pinfos.Length > 0) 4444 if (pinfos != null && pinfos.Length > 0)
4062 {
4063 foreach (PresenceInfo p in pinfos)
4064 { 4445 {
4065 if (p.RegionID != UUID.Zero) 4446 foreach (PresenceInfo p in pinfos)
4066 { 4447 {
4067 pinfo = p; 4448 if (p.RegionID != UUID.Zero)
4449 {
4450 pinfo = p;
4451 }
4068 } 4452 }
4069 } 4453 }
4070 }
4071 4454
4072 ce = new UserInfoCacheEntry(); 4455 ce = new UserInfoCacheEntry();
4073 ce.time = Util.EnvironmentTickCount(); 4456 ce.time = Util.EnvironmentTickCount();
4074 ce.account = account; 4457 ce.account = account;
4075 ce.pinfo = pinfo; 4458 ce.pinfo = pinfo;
4076 } 4459 m_userInfoCache[uuid] = ce;
4077 else 4460 }
4078 { 4461 else
4079 if (ce == null) 4462 {
4080 return UUID.Zero.ToString(); 4463 if (ce == null)
4464 return UUID.Zero.ToString();
4081 4465
4082 account = ce.account; 4466 account = ce.account;
4083 pinfo = ce.pinfo; 4467 pinfo = ce.pinfo;
4084 } 4468 }
4085 4469
4086 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4470 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 { 4471 {
4091 foreach (PresenceInfo p in pinfos) 4472 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4473 if (pinfos != null && pinfos.Length > 0)
4092 { 4474 {
4093 if (p.RegionID != UUID.Zero) 4475 foreach (PresenceInfo p in pinfos)
4094 { 4476 {
4095 pinfo = p; 4477 if (p.RegionID != UUID.Zero)
4478 {
4479 pinfo = p;
4480 }
4096 } 4481 }
4097 } 4482 }
4098 } 4483 else
4099 else 4484 pinfo = null;
4100 pinfo = null;
4101 4485
4102 ce.time = Util.EnvironmentTickCount(); 4486 ce.time = Util.EnvironmentTickCount();
4103 ce.pinfo = pinfo; 4487 ce.pinfo = pinfo;
4104 } 4488 }
4105 4489
4106 string reply = String.Empty; 4490 string reply = String.Empty;
4107 4491
4108 switch (data) 4492 switch (data)
4109 { 4493 {
4110 case 1: // DATA_ONLINE (0|1) 4494 case 1: // DATA_ONLINE (0|1)
4111 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4495 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4112 reply = "1"; 4496 reply = "1";
4113 else 4497 else
4114 reply = "0"; 4498 reply = "0";
4115 break; 4499 break;
4116 case 2: // DATA_NAME (First Last) 4500 case 2: // DATA_NAME (First Last)
4117 reply = account.FirstName + " " + account.LastName; 4501 reply = account.FirstName + " " + account.LastName;
4118 break; 4502 break;
4119 case 3: // DATA_BORN (YYYY-MM-DD) 4503 case 3: // DATA_BORN (YYYY-MM-DD)
4120 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4504 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4121 born = born.AddSeconds(account.Created); 4505 born = born.AddSeconds(account.Created);
4122 reply = born.ToString("yyyy-MM-dd"); 4506 reply = born.ToString("yyyy-MM-dd");
4123 break; 4507 break;
4124 case 4: // DATA_RATING (0,0,0,0,0,0) 4508 case 4: // DATA_RATING (0,0,0,0,0,0)
4125 reply = "0,0,0,0,0,0"; 4509 reply = "0,0,0,0,0,0";
4126 break; 4510 break;
4127 case 7: // DATA_USERLEVEL (integer) 4511 case 8: // DATA_PAYINFO (0|1|2|3)
4128 reply = account.UserLevel.ToString(); 4512 reply = "0";
4129 break; 4513 break;
4130 case 8: // DATA_PAYINFO (0|1|2|3) 4514 default:
4131 reply = "0"; 4515 return UUID.Zero.ToString(); // Raise no event
4132 break; 4516 }
4133 default:
4134 return UUID.Zero.ToString(); // Raise no event
4135 }
4136 4517
4137 UUID rq = UUID.Random(); 4518 UUID rq = UUID.Random();
4138 4519
4139 UUID tid = AsyncCommands. 4520 UUID tid = AsyncCommands.
4140 DataserverPlugin.RegisterRequest(m_host.LocalId, 4521 DataserverPlugin.RegisterRequest(m_host.LocalId,
4141 m_item.ItemID, rq.ToString()); 4522 m_item.ItemID, rq.ToString());
4142 4523
4143 AsyncCommands. 4524 AsyncCommands.
4144 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4525 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4145 4526
4146 ScriptSleep(100); 4527 ScriptSleep(100);
4147 return tid.ToString(); 4528 return tid.ToString();
4529 }
4530 else
4531 {
4532 ShoutError("Invalid UUID passed to llRequestAgentData.");
4533 }
4534 return "";
4148 } 4535 }
4149 4536
4150 public LSL_String llRequestInventoryData(string name) 4537 public LSL_String llRequestInventoryData(string name)
@@ -4201,13 +4588,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4201 if (UUID.TryParse(agent, out agentId)) 4588 if (UUID.TryParse(agent, out agentId))
4202 { 4589 {
4203 ScenePresence presence = World.GetScenePresence(agentId); 4590 ScenePresence presence = World.GetScenePresence(agentId);
4204 if (presence != null) 4591 if (presence != null && presence.PresenceType != PresenceType.Npc)
4205 { 4592 {
4593 // agent must not be a god
4594 if (presence.UserLevel >= 200) return;
4595
4206 // agent must be over the owners land 4596 // agent must be over the owners land
4207 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4597 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4208 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4598 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4209 { 4599 {
4210 World.TeleportClientHome(agentId, presence.ControllingClient); 4600 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4601 {
4602 // They can't be teleported home for some reason
4603 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4604 if (regionInfo != null)
4605 {
4606 World.RequestTeleportLocation(
4607 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4608 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4609 }
4610 }
4211 } 4611 }
4212 } 4612 }
4213 } 4613 }
@@ -4314,7 +4714,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4314 UUID av = new UUID(); 4714 UUID av = new UUID();
4315 if (!UUID.TryParse(agent,out av)) 4715 if (!UUID.TryParse(agent,out av))
4316 { 4716 {
4317 LSLError("First parameter to llDialog needs to be a key"); 4717 //LSLError("First parameter to llDialog needs to be a key");
4318 return; 4718 return;
4319 } 4719 }
4320 4720
@@ -4346,10 +4746,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4346 public void llCollisionSound(string impact_sound, double impact_volume) 4746 public void llCollisionSound(string impact_sound, double impact_volume)
4347 { 4747 {
4348 m_host.AddScriptLPS(1); 4748 m_host.AddScriptLPS(1);
4349 4749
4750 if(impact_sound == "")
4751 {
4752 m_host.CollisionSoundVolume = (float)impact_volume;
4753 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4754 m_host.CollisionSoundType = 0;
4755 return;
4756 }
4350 // TODO: Parameter check logic required. 4757 // TODO: Parameter check logic required.
4351 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4758 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound);
4352 m_host.CollisionSoundVolume = (float)impact_volume; 4759 m_host.CollisionSoundVolume = (float)impact_volume;
4760 m_host.CollisionSoundType = 1;
4353 } 4761 }
4354 4762
4355 public LSL_String llGetAnimation(string id) 4763 public LSL_String llGetAnimation(string id)
@@ -4363,14 +4771,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4363 4771
4364 if (m_host.RegionHandle == presence.RegionHandle) 4772 if (m_host.RegionHandle == presence.RegionHandle)
4365 { 4773 {
4366 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4367
4368 if (presence != null) 4774 if (presence != null)
4369 { 4775 {
4370 AnimationSet currentAnims = presence.Animator.Animations; 4776 if (presence.SitGround)
4371 string currentAnimationState = String.Empty; 4777 return "Sitting on Ground";
4372 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4778 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4373 return currentAnimationState; 4779 return "Sitting";
4780
4781 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4782 string lslMovementAnimation;
4783
4784 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4785 return lslMovementAnimation;
4374 } 4786 }
4375 } 4787 }
4376 4788
@@ -4517,7 +4929,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4517 { 4929 {
4518 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4930 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4519 float distance_term = distance * distance * distance; // Script Energy 4931 float distance_term = distance * distance * distance; // Script Energy
4520 float pusher_mass = m_host.GetMass(); 4932 // use total object mass and not part
4933 float pusher_mass = m_host.ParentGroup.GetMass();
4521 4934
4522 float PUSH_ATTENUATION_DISTANCE = 17f; 4935 float PUSH_ATTENUATION_DISTANCE = 17f;
4523 float PUSH_ATTENUATION_SCALE = 5f; 4936 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4767,6 +5180,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4767 { 5180 {
4768 return item.AssetID.ToString(); 5181 return item.AssetID.ToString();
4769 } 5182 }
5183 m_host.TaskInventory.LockItemsForRead(false);
4770 5184
4771 return UUID.Zero.ToString(); 5185 return UUID.Zero.ToString();
4772 } 5186 }
@@ -4900,7 +5314,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4900 public LSL_Vector llGetCenterOfMass() 5314 public LSL_Vector llGetCenterOfMass()
4901 { 5315 {
4902 m_host.AddScriptLPS(1); 5316 m_host.AddScriptLPS(1);
4903 Vector3 center = m_host.GetGeometricCenter(); 5317 Vector3 center = m_host.GetCenterOfMass();
4904 return new LSL_Vector(center.X,center.Y,center.Z); 5318 return new LSL_Vector(center.X,center.Y,center.Z);
4905 } 5319 }
4906 5320
@@ -4919,14 +5333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4919 { 5333 {
4920 m_host.AddScriptLPS(1); 5334 m_host.AddScriptLPS(1);
4921 5335
4922 if (src == null) 5336 return src.Length;
4923 {
4924 return 0;
4925 }
4926 else
4927 {
4928 return src.Length;
4929 }
4930 } 5337 }
4931 5338
4932 public LSL_Integer llList2Integer(LSL_List src, int index) 5339 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4997,7 +5404,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4997 else if (src.Data[index] is LSL_Float) 5404 else if (src.Data[index] is LSL_Float)
4998 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5405 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4999 else if (src.Data[index] is LSL_String) 5406 else if (src.Data[index] is LSL_String)
5000 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5407 {
5408 string str = ((LSL_String) src.Data[index]).m_string;
5409 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5410 if (m != Match.Empty)
5411 {
5412 str = m.Value;
5413 double d = 0.0;
5414 if (!Double.TryParse(str, out d))
5415 return 0.0;
5416
5417 return d;
5418 }
5419 return 0.0;
5420 }
5001 return Convert.ToDouble(src.Data[index]); 5421 return Convert.ToDouble(src.Data[index]);
5002 } 5422 }
5003 catch (FormatException) 5423 catch (FormatException)
@@ -5039,7 +5459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5039 // for completion and should LSL_Key ever be implemented 5459 // for completion and should LSL_Key ever be implemented
5040 // as it's own struct 5460 // as it's own struct
5041 else if (!(src.Data[index] is LSL_String || 5461 else if (!(src.Data[index] is LSL_String ||
5042 src.Data[index] is LSL_Key)) 5462 src.Data[index] is LSL_Key ||
5463 src.Data[index] is String))
5043 { 5464 {
5044 return ""; 5465 return "";
5045 } 5466 }
@@ -5297,7 +5718,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5297 } 5718 }
5298 } 5719 }
5299 } 5720 }
5300 else { 5721 else
5722 {
5301 object[] array = new object[src.Length]; 5723 object[] array = new object[src.Length];
5302 Array.Copy(src.Data, 0, array, 0, src.Length); 5724 Array.Copy(src.Data, 0, array, 0, src.Length);
5303 result = new LSL_List(array); 5725 result = new LSL_List(array);
@@ -5404,7 +5826,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5404 public LSL_Integer llGetRegionAgentCount() 5826 public LSL_Integer llGetRegionAgentCount()
5405 { 5827 {
5406 m_host.AddScriptLPS(1); 5828 m_host.AddScriptLPS(1);
5407 return new LSL_Integer(World.GetRootAgentCount()); 5829
5830 int count = 0;
5831 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5832 count++;
5833 });
5834
5835 return new LSL_Integer(count);
5408 } 5836 }
5409 5837
5410 public LSL_Vector llGetRegionCorner() 5838 public LSL_Vector llGetRegionCorner()
@@ -5645,6 +6073,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5645 flags |= ScriptBaseClass.AGENT_AWAY; 6073 flags |= ScriptBaseClass.AGENT_AWAY;
5646 } 6074 }
5647 6075
6076 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6077 UUID[] anims = agent.Animator.GetAnimationArray();
6078 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6079 {
6080 flags |= ScriptBaseClass.AGENT_BUSY;
6081 }
6082
5648 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6083 // 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) 6084 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5650 { 6085 {
@@ -5692,6 +6127,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5692 flags |= ScriptBaseClass.AGENT_SITTING; 6127 flags |= ScriptBaseClass.AGENT_SITTING;
5693 } 6128 }
5694 6129
6130 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6131 {
6132 flags |= ScriptBaseClass.AGENT_MALE;
6133 }
6134
5695 return flags; 6135 return flags;
5696 } 6136 }
5697 6137
@@ -5839,9 +6279,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5839 6279
5840 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6280 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5841 6281
5842 foreach (SceneObjectPart part in parts) 6282 try
6283 {
6284 foreach (SceneObjectPart part in parts)
6285 {
6286 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6287 }
6288 }
6289 finally
5843 { 6290 {
5844 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5845 } 6291 }
5846 } 6292 }
5847 6293
@@ -5895,13 +6341,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5895 6341
5896 if (m_host.OwnerID == land.LandData.OwnerID) 6342 if (m_host.OwnerID == land.LandData.OwnerID)
5897 { 6343 {
5898 World.TeleportClientHome(agentID, presence.ControllingClient); 6344 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6345 presence.TeleportWithMomentum(pos, null);
6346 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5899 } 6347 }
5900 } 6348 }
5901 } 6349 }
5902 ScriptSleep(5000); 6350 ScriptSleep(5000);
5903 } 6351 }
5904 6352
6353 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6354 {
6355 return ParseString2List(str, separators, in_spacers, false);
6356 }
6357
5905 public LSL_Integer llOverMyLand(string id) 6358 public LSL_Integer llOverMyLand(string id)
5906 { 6359 {
5907 m_host.AddScriptLPS(1); 6360 m_host.AddScriptLPS(1);
@@ -5955,25 +6408,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5955 } 6408 }
5956 else 6409 else
5957 { 6410 {
5958 agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); 6411// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6412 Vector3 s = avatar.Appearance.AvatarSize;
6413 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5959 } 6414 }
5960 return agentSize; 6415 return agentSize;
5961 } 6416 }
5962 6417
5963 public LSL_Integer llSameGroup(string agent) 6418 public LSL_Integer llSameGroup(string id)
5964 { 6419 {
5965 m_host.AddScriptLPS(1); 6420 m_host.AddScriptLPS(1);
5966 UUID agentId = new UUID(); 6421 UUID uuid = new UUID();
5967 if (!UUID.TryParse(agent, out agentId)) 6422 if (!UUID.TryParse(id, out uuid))
5968 return new LSL_Integer(0); 6423 return new LSL_Integer(0);
5969 ScenePresence presence = World.GetScenePresence(agentId); 6424
5970 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6425 // Check if it's a group key
5971 return new LSL_Integer(0); 6426 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5972 IClientAPI client = presence.ControllingClient;
5973 if (m_host.GroupID == client.ActiveGroupId)
5974 return new LSL_Integer(1); 6427 return new LSL_Integer(1);
5975 else 6428
6429 // We got passed a UUID.Zero
6430 if (uuid == UUID.Zero)
5976 return new LSL_Integer(0); 6431 return new LSL_Integer(0);
6432
6433 // Handle the case where id names an avatar
6434 ScenePresence presence = World.GetScenePresence(uuid);
6435 if (presence != null)
6436 {
6437 if (presence.IsChildAgent)
6438 return new LSL_Integer(0);
6439
6440 IClientAPI client = presence.ControllingClient;
6441 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6442 return new LSL_Integer(1);
6443
6444 return new LSL_Integer(0);
6445 }
6446
6447 // Handle object case
6448 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6449 if (part != null)
6450 {
6451 // This will handle both deed and non-deed and also the no
6452 // group case
6453 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6454 return new LSL_Integer(1);
6455
6456 return new LSL_Integer(0);
6457 }
6458
6459 return new LSL_Integer(0);
5977 } 6460 }
5978 6461
5979 public void llUnSit(string id) 6462 public void llUnSit(string id)
@@ -6098,7 +6581,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6098 return m_host.ParentGroup.AttachmentPoint; 6581 return m_host.ParentGroup.AttachmentPoint;
6099 } 6582 }
6100 6583
6101 public LSL_Integer llGetFreeMemory() 6584 public virtual LSL_Integer llGetFreeMemory()
6102 { 6585 {
6103 m_host.AddScriptLPS(1); 6586 m_host.AddScriptLPS(1);
6104 // Make scripts designed for LSO happy 6587 // Make scripts designed for LSO happy
@@ -6530,6 +7013,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6530 7013
6531 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7014 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6532 { 7015 {
7016 // LSL quaternions can normalize to 0, normal Quaternions can't.
7017 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7018 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7019
6533 part.SitTargetPosition = offset; 7020 part.SitTargetPosition = offset;
6534 part.SitTargetOrientation = rot; 7021 part.SitTargetOrientation = rot;
6535 part.ParentGroup.HasGroupChanged = true; 7022 part.ParentGroup.HasGroupChanged = true;
@@ -6715,13 +7202,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6715 UUID av = new UUID(); 7202 UUID av = new UUID();
6716 if (!UUID.TryParse(avatar,out av)) 7203 if (!UUID.TryParse(avatar,out av))
6717 { 7204 {
6718 LSLError("First parameter to llDialog needs to be a key"); 7205 //LSLError("First parameter to llDialog needs to be a key");
6719 return; 7206 return;
6720 } 7207 }
6721 if (buttons.Length < 1) 7208 if (buttons.Length < 1)
6722 { 7209 {
6723 LSLError("No less than 1 button can be shown"); 7210 buttons.Add("OK");
6724 return;
6725 } 7211 }
6726 if (buttons.Length > 12) 7212 if (buttons.Length > 12)
6727 { 7213 {
@@ -6738,7 +7224,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6738 } 7224 }
6739 if (buttons.Data[i].ToString().Length > 24) 7225 if (buttons.Data[i].ToString().Length > 24)
6740 { 7226 {
6741 LSLError("button label cannot be longer than 24 characters"); 7227 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6742 return; 7228 return;
6743 } 7229 }
6744 buts[i] = buttons.Data[i].ToString(); 7230 buts[i] = buttons.Data[i].ToString();
@@ -6805,9 +7291,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6805 return; 7291 return;
6806 } 7292 }
6807 7293
6808 // the rest of the permission checks are done in RezScript, so check the pin there as well 7294 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6809 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7295 if (dest != null)
7296 {
7297 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7298 {
7299 // the rest of the permission checks are done in RezScript, so check the pin there as well
7300 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6810 7301
7302 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7303 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7304 }
7305 }
6811 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7306 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6812 ScriptSleep(3000); 7307 ScriptSleep(3000);
6813 } 7308 }
@@ -6877,19 +7372,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6877 public LSL_String llMD5String(string src, int nonce) 7372 public LSL_String llMD5String(string src, int nonce)
6878 { 7373 {
6879 m_host.AddScriptLPS(1); 7374 m_host.AddScriptLPS(1);
6880 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7375 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6881 } 7376 }
6882 7377
6883 public LSL_String llSHA1String(string src) 7378 public LSL_String llSHA1String(string src)
6884 { 7379 {
6885 m_host.AddScriptLPS(1); 7380 m_host.AddScriptLPS(1);
6886 return Util.SHA1Hash(src).ToLower(); 7381 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6887 } 7382 }
6888 7383
6889 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7384 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6890 { 7385 {
6891 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7386 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6892 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7387 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7388 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7389 return shapeBlock;
6893 7390
6894 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7391 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6895 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7392 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6994,6 +7491,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6994 // Prim type box, cylinder and prism. 7491 // 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) 7492 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 { 7493 {
7494 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7495 return;
7496
6997 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7497 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6998 ObjectShapePacket.ObjectDataBlock shapeBlock; 7498 ObjectShapePacket.ObjectDataBlock shapeBlock;
6999 7499
@@ -7047,6 +7547,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7047 // Prim type sphere. 7547 // 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) 7548 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7049 { 7549 {
7550 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7551 return;
7552
7050 ObjectShapePacket.ObjectDataBlock shapeBlock; 7553 ObjectShapePacket.ObjectDataBlock shapeBlock;
7051 7554
7052 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7555 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7088,6 +7591,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7088 // Prim type torus, tube and ring. 7591 // 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) 7592 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 { 7593 {
7594 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7595 return;
7596
7091 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7597 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7092 ObjectShapePacket.ObjectDataBlock shapeBlock; 7598 ObjectShapePacket.ObjectDataBlock shapeBlock;
7093 7599
@@ -7223,6 +7729,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7223 // Prim type sculpt. 7729 // Prim type sculpt.
7224 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7730 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7225 { 7731 {
7732 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7733 return;
7734
7226 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7735 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7227 UUID sculptId; 7736 UUID sculptId;
7228 7737
@@ -7247,7 +7756,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7247 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7756 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7248 { 7757 {
7249 // default 7758 // default
7250 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7759 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7251 } 7760 }
7252 7761
7253 part.Shape.SetSculptProperties((byte)type, sculptId); 7762 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7264,48 +7773,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7264 ScriptSleep(200); 7773 ScriptSleep(200);
7265 } 7774 }
7266 7775
7267 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7776 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7268 { 7777 {
7269 m_host.AddScriptLPS(1); 7778 m_host.AddScriptLPS(1);
7270 7779
7271 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7780 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7272 7781
7273 ScriptSleep(200); 7782 ScriptSleep(200);
7274 } 7783 }
7275 7784
7276 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7785 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7277 { 7786 {
7278 m_host.AddScriptLPS(1); 7787 List<object> parts = new List<object>();
7788 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7789 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7790 foreach (SceneObjectPart p in prims)
7791 parts.Add(p);
7792 foreach (ScenePresence p in avatars)
7793 parts.Add(p);
7279 7794
7280 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7795 LSL_List remaining = null;
7796 uint rulesParsed = 0;
7797
7798 if (parts.Count > 0)
7799 {
7800 foreach (object part in parts)
7801 {
7802 if (part is SceneObjectPart)
7803 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7804 else
7805 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7806 }
7807
7808 while ((object)remaining != null && remaining.Length > 2)
7809 {
7810 linknumber = remaining.GetLSLIntegerItem(0);
7811 rules = remaining.GetSublist(1, -1);
7812 parts.Clear();
7813 prims = GetLinkParts(linknumber);
7814 avatars = GetLinkAvatars(linknumber);
7815 foreach (SceneObjectPart p in prims)
7816 parts.Add(p);
7817 foreach (ScenePresence p in avatars)
7818 parts.Add(p);
7819
7820 remaining = null;
7821 foreach (object part in parts)
7822 {
7823 if (part is SceneObjectPart)
7824 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7825 else
7826 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7827 }
7828 }
7829 }
7281 } 7830 }
7282 7831
7283 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7832 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7833 float material_density, float material_friction,
7834 float material_restitution, float material_gravity_modifier)
7284 { 7835 {
7285 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7836 ExtraPhysicsData physdata = new ExtraPhysicsData();
7837 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7838 physdata.Density = part.Density;
7839 physdata.Friction = part.Friction;
7840 physdata.Bounce = part.Bounciness;
7841 physdata.GravitationModifier = part.GravityModifier;
7286 7842
7287 LSL_List remaining = null; 7843 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7288 uint rulesParsed = 0; 7844 physdata.Density = material_density;
7845 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7846 physdata.Friction = material_friction;
7847 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7848 physdata.Bounce = material_restitution;
7849 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7850 physdata.GravitationModifier = material_gravity_modifier;
7289 7851
7290 foreach (SceneObjectPart part in parts) 7852 part.UpdateExtraPhysics(physdata);
7291 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7853 }
7292 7854
7293 while (remaining != null && remaining.Length > 2) 7855 public void llSetPhysicsMaterial(int material_bits,
7294 { 7856 float material_gravity_modifier, float material_restitution,
7295 linknumber = remaining.GetLSLIntegerItem(0); 7857 float material_friction, float material_density)
7296 rules = remaining.GetSublist(1, -1); 7858 {
7297 parts = GetLinkParts(linknumber); 7859 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7860 }
7298 7861
7299 foreach (SceneObjectPart part in parts) 7862 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7300 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7863 {
7864 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7865 llSetLinkPrimitiveParamsFast(linknumber, rules);
7866 ScriptSleep(200);
7867 }
7868
7869 // vector up using libomv (c&p from sop )
7870 // vector up rotated by r
7871 private Vector3 Zrot(Quaternion r)
7872 {
7873 double x, y, z, m;
7874
7875 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7876 if (Math.Abs(1.0 - m) > 0.000001)
7877 {
7878 m = 1.0 / Math.Sqrt(m);
7879 r.X *= (float)m;
7880 r.Y *= (float)m;
7881 r.Z *= (float)m;
7882 r.W *= (float)m;
7301 } 7883 }
7884
7885 x = 2 * (r.X * r.Z + r.Y * r.W);
7886 y = 2 * (-r.X * r.W + r.Y * r.Z);
7887 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7888
7889 return new Vector3((float)x, (float)y, (float)z);
7302 } 7890 }
7303 7891
7304 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7892 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7305 { 7893 {
7894 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7895 return null;
7896
7306 int idx = 0; 7897 int idx = 0;
7307 int idxStart = 0; 7898 int idxStart = 0;
7308 7899
7900 SceneObjectGroup parentgrp = part.ParentGroup;
7901
7309 bool positionChanged = false; 7902 bool positionChanged = false;
7310 LSL_Vector currentPosition = GetPartLocalPos(part); 7903 LSL_Vector currentPosition = GetPartLocalPos(part);
7311 7904
@@ -7330,8 +7923,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7330 return null; 7923 return null;
7331 7924
7332 v=rules.GetVector3Item(idx++); 7925 v=rules.GetVector3Item(idx++);
7333 positionChanged = true;
7334 currentPosition = GetSetPosTarget(part, v, currentPosition); 7926 currentPosition = GetSetPosTarget(part, v, currentPosition);
7927 positionChanged = true;
7335 7928
7336 break; 7929 break;
7337 case (int)ScriptBaseClass.PRIM_SIZE: 7930 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7348,7 +7941,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7348 7941
7349 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7942 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7350 // try to let this work as in SL... 7943 // try to let this work as in SL...
7351 if (part.ParentID == 0) 7944 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7352 { 7945 {
7353 // special case: If we are root, rotate complete SOG to new rotation 7946 // special case: If we are root, rotate complete SOG to new rotation
7354 SetRot(part, q); 7947 SetRot(part, q);
@@ -7608,7 +8201,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7608 return null; 8201 return null;
7609 8202
7610 string ph = rules.Data[idx++].ToString(); 8203 string ph = rules.Data[idx++].ToString();
7611 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8204 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7612 8205
7613 break; 8206 break;
7614 8207
@@ -7626,12 +8219,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7626 part.ScriptSetPhysicsStatus(physics); 8219 part.ScriptSetPhysicsStatus(physics);
7627 break; 8220 break;
7628 8221
8222 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8223 if (remain < 1)
8224 return null;
8225
8226 int shape_type = rules.GetLSLIntegerItem(idx++);
8227
8228 ExtraPhysicsData physdata = new ExtraPhysicsData();
8229 physdata.Density = part.Density;
8230 physdata.Bounce = part.Bounciness;
8231 physdata.GravitationModifier = part.GravityModifier;
8232 physdata.PhysShapeType = (PhysShapeType)shape_type;
8233
8234 part.UpdateExtraPhysics(physdata);
8235
8236 break;
8237
8238 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8239 if (remain < 5)
8240 return null;
8241
8242 int material_bits = rules.GetLSLIntegerItem(idx++);
8243 float material_density = (float)rules.GetLSLFloatItem(idx++);
8244 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8245 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8246 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8247
8248 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8249
8250 break;
8251
7629 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8252 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7630 if (remain < 1) 8253 if (remain < 1)
7631 return null; 8254 return null;
7632 string temp = rules.Data[idx++].ToString(); 8255 string temp = rules.Data[idx++].ToString();
7633 8256
7634 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8257 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7635 8258
7636 break; 8259 break;
7637 8260
@@ -7705,7 +8328,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7705 if (part.ParentGroup.RootPart == part) 8328 if (part.ParentGroup.RootPart == part)
7706 { 8329 {
7707 SceneObjectGroup parent = part.ParentGroup; 8330 SceneObjectGroup parent = part.ParentGroup;
7708 parent.UpdateGroupPosition(currentPosition); 8331 Util.FireAndForget(delegate(object x) {
8332 parent.UpdateGroupPosition(currentPosition);
8333 });
7709 } 8334 }
7710 else 8335 else
7711 { 8336 {
@@ -7750,10 +8375,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7750 8375
7751 public LSL_String llXorBase64Strings(string str1, string str2) 8376 public LSL_String llXorBase64Strings(string str1, string str2)
7752 { 8377 {
7753 m_host.AddScriptLPS(1); 8378 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7754 Deprecated("llXorBase64Strings"); 8379
7755 ScriptSleep(300); 8380 ScriptSleep(300);
7756 return String.Empty; 8381 m_host.AddScriptLPS(1);
8382
8383 if (str1 == String.Empty)
8384 return String.Empty;
8385 if (str2 == String.Empty)
8386 return str1;
8387
8388 int len = str2.Length;
8389 if ((len % 4) != 0) // LL is EVIL!!!!
8390 {
8391 while (str2.EndsWith("="))
8392 str2 = str2.Substring(0, str2.Length - 1);
8393
8394 len = str2.Length;
8395 int mod = len % 4;
8396
8397 if (mod == 1)
8398 str2 = str2.Substring(0, str2.Length - 1);
8399 else if (mod == 2)
8400 str2 += "==";
8401 else if (mod == 3)
8402 str2 += "=";
8403 }
8404
8405 byte[] data1;
8406 byte[] data2;
8407 try
8408 {
8409 data1 = Convert.FromBase64String(str1);
8410 data2 = Convert.FromBase64String(str2);
8411 }
8412 catch (Exception)
8413 {
8414 return new LSL_String(String.Empty);
8415 }
8416
8417 // For cases where the decoded length of s2 is greater
8418 // than the decoded length of s1, simply perform a normal
8419 // decode and XOR
8420 //
8421 if (data2.Length >= data1.Length)
8422 {
8423 for (int pos = 0 ; pos < data1.Length ; pos++ )
8424 data1[pos] ^= data2[pos];
8425
8426 return Convert.ToBase64String(data1);
8427 }
8428
8429 // Remove padding
8430 while (str1.EndsWith("="))
8431 str1 = str1.Substring(0, str1.Length - 1);
8432 while (str2.EndsWith("="))
8433 str2 = str2.Substring(0, str2.Length - 1);
8434
8435 byte[] d1 = new byte[str1.Length];
8436 byte[] d2 = new byte[str2.Length];
8437
8438 for (int i = 0 ; i < str1.Length ; i++)
8439 {
8440 int idx = b64.IndexOf(str1.Substring(i, 1));
8441 if (idx == -1)
8442 idx = 0;
8443 d1[i] = (byte)idx;
8444 }
8445
8446 for (int i = 0 ; i < str2.Length ; i++)
8447 {
8448 int idx = b64.IndexOf(str2.Substring(i, 1));
8449 if (idx == -1)
8450 idx = 0;
8451 d2[i] = (byte)idx;
8452 }
8453
8454 string output = String.Empty;
8455
8456 for (int pos = 0 ; pos < d1.Length ; pos++)
8457 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8458
8459 while (output.Length % 3 > 0)
8460 output += "=";
8461
8462 return output;
7757 } 8463 }
7758 8464
7759 public void llRemoteDataSetRegion() 8465 public void llRemoteDataSetRegion()
@@ -7877,8 +8583,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7877 public LSL_Integer llGetNumberOfPrims() 8583 public LSL_Integer llGetNumberOfPrims()
7878 { 8584 {
7879 m_host.AddScriptLPS(1); 8585 m_host.AddScriptLPS(1);
7880 8586 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7881 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8587
8588 return m_host.ParentGroup.PrimCount + avatarCount;
7882 } 8589 }
7883 8590
7884 /// <summary> 8591 /// <summary>
@@ -7893,55 +8600,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7893 m_host.AddScriptLPS(1); 8600 m_host.AddScriptLPS(1);
7894 UUID objID = UUID.Zero; 8601 UUID objID = UUID.Zero;
7895 LSL_List result = new LSL_List(); 8602 LSL_List result = new LSL_List();
8603
8604 // If the ID is not valid, return null result
7896 if (!UUID.TryParse(obj, out objID)) 8605 if (!UUID.TryParse(obj, out objID))
7897 { 8606 {
7898 result.Add(new LSL_Vector()); 8607 result.Add(new LSL_Vector());
7899 result.Add(new LSL_Vector()); 8608 result.Add(new LSL_Vector());
7900 return result; 8609 return result;
7901 } 8610 }
8611
8612 // Check if this is an attached prim. If so, replace
8613 // the UUID with the avatar UUID and report it's bounding box
8614 SceneObjectPart part = World.GetSceneObjectPart(objID);
8615 if (part != null && part.ParentGroup.IsAttachment)
8616 objID = part.ParentGroup.AttachedAvatar;
8617
8618 // Find out if this is an avatar ID. If so, return it's box
7902 ScenePresence presence = World.GetScenePresence(objID); 8619 ScenePresence presence = World.GetScenePresence(objID);
7903 if (presence != null) 8620 if (presence != null)
7904 { 8621 {
7905 if (presence.ParentID == 0) // not sat on an object 8622 // As per LSL Wiki, there is no difference between sitting
8623 // and standing avatar since server 1.36
8624 LSL_Vector lower;
8625 LSL_Vector upper;
8626
8627 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8628
8629 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8630 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8631/*
7906 { 8632 {
7907 LSL_Vector lower; 8633 // This is for ground sitting avatars
7908 LSL_Vector upper; 8634 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7909 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8635 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7910 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8636 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7911 { 8637 }
7912 // This is for ground sitting avatars 8638 else
7913 float height = presence.Appearance.AvatarHeight / 2.66666667f; 8639 {
7914 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); 8640 // This is for standing/flying avatars
7915 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); 8641 float height = presence.Appearance.AvatarHeight / 2.0f;
7916 } 8642 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7917 else 8643 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7918 { 8644 }
7919 // This is for standing/flying avatars 8645
7920 float height = presence.Appearance.AvatarHeight / 2.0f; 8646 // Adjust to the documented error offsets (see LSL Wiki)
7921 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); 8647 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7922 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); 8648 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7923 } 8649*/
7924 result.Add(lower); 8650 {
7925 result.Add(upper); 8651 // This is for ground sitting avatars TODO!
7926 return result; 8652 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8653 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
7927 } 8654 }
7928 else 8655 else
7929 { 8656 {
7930 // sitting on an object so we need the bounding box of that 8657 // This is for standing/flying avatars
7931 // which should include the avatar so set the UUID to the 8658 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 8659 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 } 8660 }
8661
8662 if (lower.x > upper.x)
8663 lower.x = upper.x;
8664 if (lower.y > upper.y)
8665 lower.y = upper.y;
8666 if (lower.z > upper.z)
8667 lower.z = upper.z;
8668
8669 result.Add(lower);
8670 result.Add(upper);
8671 return result;
7937 } 8672 }
7938 SceneObjectPart part = World.GetSceneObjectPart(objID); 8673
8674 part = World.GetSceneObjectPart(objID);
7939 // Currently only works for single prims without a sitting avatar 8675 // Currently only works for single prims without a sitting avatar
7940 if (part != null) 8676 if (part != null)
7941 { 8677 {
7942 Vector3 halfSize = part.Scale / 2.0f; 8678 float minX;
7943 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8679 float maxX;
7944 LSL_Vector upper = new LSL_Vector(halfSize); 8680 float minY;
8681 float maxY;
8682 float minZ;
8683 float maxZ;
8684
8685 // This BBox is in sim coordinates, with the offset being
8686 // a contained point.
8687 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8688 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8689
8690 minX -= offsets[0].X;
8691 maxX -= offsets[0].X;
8692 minY -= offsets[0].Y;
8693 maxY -= offsets[0].Y;
8694 minZ -= offsets[0].Z;
8695 maxZ -= offsets[0].Z;
8696
8697 LSL_Vector lower;
8698 LSL_Vector upper;
8699
8700 // Adjust to the documented error offsets (see LSL Wiki)
8701 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8702 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8703
8704 if (lower.x > upper.x)
8705 lower.x = upper.x;
8706 if (lower.y > upper.y)
8707 lower.y = upper.y;
8708 if (lower.z > upper.z)
8709 lower.z = upper.z;
8710
7945 result.Add(lower); 8711 result.Add(lower);
7946 result.Add(upper); 8712 result.Add(upper);
7947 return result; 8713 return result;
@@ -7955,7 +8721,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7955 8721
7956 public LSL_Vector llGetGeometricCenter() 8722 public LSL_Vector llGetGeometricCenter()
7957 { 8723 {
7958 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8724 Vector3 tmp = m_host.GetGeometricCenter();
8725 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7959 } 8726 }
7960 8727
7961 public LSL_List llGetPrimitiveParams(LSL_List rules) 8728 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7966,7 +8733,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7966 8733
7967 LSL_List remaining = GetPrimParams(m_host, rules, ref result); 8734 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
7968 8735
7969 while (remaining != null && remaining.Length > 2) 8736 while ((object)remaining != null && remaining.Length > 2)
7970 { 8737 {
7971 int linknumber = remaining.GetLSLIntegerItem(0); 8738 int linknumber = remaining.GetLSLIntegerItem(0);
7972 rules = remaining.GetSublist(1, -1); 8739 rules = remaining.GetSublist(1, -1);
@@ -7983,24 +8750,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7983 { 8750 {
7984 m_host.AddScriptLPS(1); 8751 m_host.AddScriptLPS(1);
7985 8752
7986 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8753 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8754 // keep other options as before
7987 8755
8756 List<SceneObjectPart> parts;
8757 List<ScenePresence> avatars;
8758
7988 LSL_List res = new LSL_List(); 8759 LSL_List res = new LSL_List();
7989 LSL_List remaining = null; 8760 LSL_List remaining = null;
7990 8761
7991 foreach (SceneObjectPart part in parts) 8762 while (rules.Length > 0)
7992 { 8763 {
7993 remaining = GetPrimParams(part, rules, ref res);
7994 }
7995
7996 while (remaining != null && remaining.Length > 2)
7997 {
7998 linknumber = remaining.GetLSLIntegerItem(0);
7999 rules = remaining.GetSublist(1, -1);
8000 parts = GetLinkParts(linknumber); 8764 parts = GetLinkParts(linknumber);
8765 avatars = GetLinkAvatars(linknumber);
8001 8766
8767 remaining = null;
8002 foreach (SceneObjectPart part in parts) 8768 foreach (SceneObjectPart part in parts)
8769 {
8003 remaining = GetPrimParams(part, rules, ref res); 8770 remaining = GetPrimParams(part, rules, ref res);
8771 }
8772 foreach (ScenePresence avatar in avatars)
8773 {
8774 remaining = GetPrimParams(avatar, rules, ref res);
8775 }
8776
8777 if ((object)remaining != null && remaining.Length > 0)
8778 {
8779 linknumber = remaining.GetLSLIntegerItem(0);
8780 rules = remaining.GetSublist(1, -1);
8781 }
8782 else
8783 break;
8004 } 8784 }
8005 8785
8006 return res; 8786 return res;
@@ -8045,13 +8825,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8045 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8825 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8046 part.AbsolutePosition.Y, 8826 part.AbsolutePosition.Y,
8047 part.AbsolutePosition.Z); 8827 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); 8828 res.Add(v);
8056 break; 8829 break;
8057 8830
@@ -8223,30 +8996,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8223 if (remain < 1) 8996 if (remain < 1)
8224 return null; 8997 return null;
8225 8998
8226 face=(int)rules.GetLSLIntegerItem(idx++); 8999 face = (int)rules.GetLSLIntegerItem(idx++);
8227 9000
8228 tex = part.Shape.Textures; 9001 tex = part.Shape.Textures;
9002 int shiny;
8229 if (face == ScriptBaseClass.ALL_SIDES) 9003 if (face == ScriptBaseClass.ALL_SIDES)
8230 { 9004 {
8231 for (face = 0; face < GetNumberOfSides(part); face++) 9005 for (face = 0; face < GetNumberOfSides(part); face++)
8232 { 9006 {
8233 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9007 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8234 // Convert Shininess to PRIM_SHINY_* 9008 if (shinyness == Shininess.High)
8235 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9009 {
8236 // PRIM_BUMP_* 9010 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8237 res.Add(new LSL_Integer((int)texface.Bump)); 9011 }
9012 else if (shinyness == Shininess.Medium)
9013 {
9014 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9015 }
9016 else if (shinyness == Shininess.Low)
9017 {
9018 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9019 }
9020 else
9021 {
9022 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9023 }
9024 res.Add(new LSL_Integer(shiny));
9025 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8238 } 9026 }
8239 } 9027 }
8240 else 9028 else
8241 { 9029 {
8242 if (face >= 0 && face < GetNumberOfSides(part)) 9030 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9031 if (shinyness == Shininess.High)
8243 { 9032 {
8244 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9033 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8245 // Convert Shininess to PRIM_SHINY_* 9034 }
8246 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9035 else if (shinyness == Shininess.Medium)
8247 // PRIM_BUMP_* 9036 {
8248 res.Add(new LSL_Integer((int)texface.Bump)); 9037 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9038 }
9039 else if (shinyness == Shininess.Low)
9040 {
9041 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9042 }
9043 else
9044 {
9045 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8249 } 9046 }
9047 res.Add(new LSL_Integer(shiny));
9048 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8250 } 9049 }
8251 break; 9050 break;
8252 9051
@@ -8254,24 +9053,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8254 if (remain < 1) 9053 if (remain < 1)
8255 return null; 9054 return null;
8256 9055
8257 face=(int)rules.GetLSLIntegerItem(idx++); 9056 face = (int)rules.GetLSLIntegerItem(idx++);
8258 9057
8259 tex = part.Shape.Textures; 9058 tex = part.Shape.Textures;
9059 int fullbright;
8260 if (face == ScriptBaseClass.ALL_SIDES) 9060 if (face == ScriptBaseClass.ALL_SIDES)
8261 { 9061 {
8262 for (face = 0; face < GetNumberOfSides(part); face++) 9062 for (face = 0; face < GetNumberOfSides(part); face++)
8263 { 9063 {
8264 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9064 if (tex.GetFace((uint)face).Fullbright == true)
8265 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9065 {
9066 fullbright = ScriptBaseClass.TRUE;
9067 }
9068 else
9069 {
9070 fullbright = ScriptBaseClass.FALSE;
9071 }
9072 res.Add(new LSL_Integer(fullbright));
8266 } 9073 }
8267 } 9074 }
8268 else 9075 else
8269 { 9076 {
8270 if (face >= 0 && face < GetNumberOfSides(part)) 9077 if (tex.GetFace((uint)face).Fullbright == true)
8271 { 9078 {
8272 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9079 fullbright = ScriptBaseClass.TRUE;
8273 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9080 }
9081 else
9082 {
9083 fullbright = ScriptBaseClass.FALSE;
8274 } 9084 }
9085 res.Add(new LSL_Integer(fullbright));
8275 } 9086 }
8276 break; 9087 break;
8277 9088
@@ -8293,27 +9104,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8293 break; 9104 break;
8294 9105
8295 case (int)ScriptBaseClass.PRIM_TEXGEN: 9106 case (int)ScriptBaseClass.PRIM_TEXGEN:
9107 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8296 if (remain < 1) 9108 if (remain < 1)
8297 return null; 9109 return null;
8298 9110
8299 face=(int)rules.GetLSLIntegerItem(idx++); 9111 face = (int)rules.GetLSLIntegerItem(idx++);
8300 9112
8301 tex = part.Shape.Textures; 9113 tex = part.Shape.Textures;
8302 if (face == ScriptBaseClass.ALL_SIDES) 9114 if (face == ScriptBaseClass.ALL_SIDES)
8303 { 9115 {
8304 for (face = 0; face < GetNumberOfSides(part); face++) 9116 for (face = 0; face < GetNumberOfSides(part); face++)
8305 { 9117 {
8306 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9118 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8307 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9119 {
8308 res.Add(new LSL_Integer((uint)texgen >> 1)); 9120 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9121 }
9122 else
9123 {
9124 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9125 }
8309 } 9126 }
8310 } 9127 }
8311 else 9128 else
8312 { 9129 {
8313 if (face >= 0 && face < GetNumberOfSides(part)) 9130 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9131 {
9132 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9133 }
9134 else
8314 { 9135 {
8315 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9136 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8316 res.Add(new LSL_Integer((uint)texgen >> 1));
8317 } 9137 }
8318 } 9138 }
8319 break; 9139 break;
@@ -8337,24 +9157,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8337 if (remain < 1) 9157 if (remain < 1)
8338 return null; 9158 return null;
8339 9159
8340 face=(int)rules.GetLSLIntegerItem(idx++); 9160 face = (int)rules.GetLSLIntegerItem(idx++);
8341 9161
8342 tex = part.Shape.Textures; 9162 tex = part.Shape.Textures;
9163 float primglow;
8343 if (face == ScriptBaseClass.ALL_SIDES) 9164 if (face == ScriptBaseClass.ALL_SIDES)
8344 { 9165 {
8345 for (face = 0; face < GetNumberOfSides(part); face++) 9166 for (face = 0; face < GetNumberOfSides(part); face++)
8346 { 9167 {
8347 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9168 primglow = tex.GetFace((uint)face).Glow;
8348 res.Add(new LSL_Float(texface.Glow)); 9169 res.Add(new LSL_Float(primglow));
8349 } 9170 }
8350 } 9171 }
8351 else 9172 else
8352 { 9173 {
8353 if (face >= 0 && face < GetNumberOfSides(part)) 9174 primglow = tex.GetFace((uint)face).Glow;
8354 { 9175 res.Add(new LSL_Float(primglow));
8355 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8356 res.Add(new LSL_Float(texface.Glow));
8357 }
8358 } 9176 }
8359 break; 9177 break;
8360 9178
@@ -8366,15 +9184,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8366 textColor.B)); 9184 textColor.B));
8367 res.Add(new LSL_Float(textColor.A)); 9185 res.Add(new LSL_Float(textColor.A));
8368 break; 9186 break;
9187
8369 case (int)ScriptBaseClass.PRIM_NAME: 9188 case (int)ScriptBaseClass.PRIM_NAME:
8370 res.Add(new LSL_String(part.Name)); 9189 res.Add(new LSL_String(part.Name));
8371 break; 9190 break;
9191
8372 case (int)ScriptBaseClass.PRIM_DESC: 9192 case (int)ScriptBaseClass.PRIM_DESC:
8373 res.Add(new LSL_String(part.Description)); 9193 res.Add(new LSL_String(part.Description));
8374 break; 9194 break;
9195
8375 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9196 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8376 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9197 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8377 break; 9198 break;
9199
8378 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9200 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8379 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9201 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8380 break; 9202 break;
@@ -8985,8 +9807,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8985 // The function returns an ordered list 9807 // The function returns an ordered list
8986 // representing the tokens found in the supplied 9808 // representing the tokens found in the supplied
8987 // sources string. If two successive tokenizers 9809 // sources string. If two successive tokenizers
8988 // are encountered, then a NULL entry is added 9810 // are encountered, then a null-string entry is
8989 // to the list. 9811 // added to the list.
8990 // 9812 //
8991 // It is a precondition that the source and 9813 // It is a precondition that the source and
8992 // toekizer lisst are non-null. If they are null, 9814 // toekizer lisst are non-null. If they are null,
@@ -8994,7 +9816,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8994 // while their lengths are being determined. 9816 // while their lengths are being determined.
8995 // 9817 //
8996 // A small amount of working memoryis required 9818 // A small amount of working memoryis required
8997 // of approximately 8*#tokenizers. 9819 // of approximately 8*#tokenizers + 8*srcstrlen.
8998 // 9820 //
8999 // There are many ways in which this function 9821 // There are many ways in which this function
9000 // can be implemented, this implementation is 9822 // can be implemented, this implementation is
@@ -9010,155 +9832,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9010 // and eliminates redundant tokenizers as soon 9832 // and eliminates redundant tokenizers as soon
9011 // as is possible. 9833 // as is possible.
9012 // 9834 //
9013 // The implementation tries to avoid any copying 9835 // The implementation tries to minimize temporary
9014 // of arrays or other objects. 9836 // garbage generation.
9015 // </remarks> 9837 // </remarks>
9016 9838
9017 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9839 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9018 { 9840 {
9019 int beginning = 0; 9841 return ParseString2List(src, separators, spacers, true);
9020 int srclen = src.Length; 9842 }
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 9843
9035 LSL_List tokens = new LSL_List(); 9844 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9845 {
9846 int srclen = src.Length;
9847 int seplen = separators.Length;
9848 object[] separray = separators.Data;
9849 int spclen = spacers.Length;
9850 object[] spcarray = spacers.Data;
9851 int dellen = 0;
9852 string[] delarray = new string[seplen+spclen];
9036 9853
9037 // All entries are initially valid 9854 int outlen = 0;
9855 string[] outarray = new string[srclen*2+1];
9038 9856
9039 for (int i = 0; i < mlen; i++) 9857 int i, j;
9040 active[i] = true; 9858 string d;
9041 9859
9042 offset[mlen] = srclen; 9860 m_host.AddScriptLPS(1);
9043 9861
9044 while (beginning < srclen) 9862 /*
9863 * Convert separator and spacer lists to C# strings.
9864 * Also filter out null strings so we don't hang.
9865 */
9866 for (i = 0; i < seplen; i ++)
9045 { 9867 {
9868 d = separray[i].ToString();
9869 if (d.Length > 0)
9870 {
9871 delarray[dellen++] = d;
9872 }
9873 }
9874 seplen = dellen;
9046 9875
9047 best = mlen; // as bad as it gets 9876 for (i = 0; i < spclen; i ++)
9877 {
9878 d = spcarray[i].ToString();
9879 if (d.Length > 0)
9880 {
9881 delarray[dellen++] = d;
9882 }
9883 }
9048 9884
9049 // Scan for separators 9885 /*
9886 * Scan through source string from beginning to end.
9887 */
9888 for (i = 0;;)
9889 {
9050 9890
9051 for (j = 0; j < seplen; j++) 9891 /*
9892 * Find earliest delimeter in src starting at i (if any).
9893 */
9894 int earliestDel = -1;
9895 int earliestSrc = srclen;
9896 string earliestStr = null;
9897 for (j = 0; j < dellen; j ++)
9052 { 9898 {
9053 if (separray[j].ToString() == String.Empty) 9899 d = delarray[j];
9054 active[j] = false; 9900 if (d != null)
9055
9056 if (active[j])
9057 { 9901 {
9058 // scan all of the markers 9902 int index = src.IndexOf(d, i);
9059 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9903 if (index < 0)
9060 { 9904 {
9061 // not present at all 9905 delarray[j] = null; // delim nowhere in src, don't check it anymore
9062 active[j] = false;
9063 } 9906 }
9064 else 9907 else if (index < earliestSrc)
9065 { 9908 {
9066 // present and correct 9909 earliestSrc = index; // where delimeter starts in source string
9067 if (offset[j] < offset[best]) 9910 earliestDel = j; // where delimeter is in delarray[]
9068 { 9911 earliestStr = d; // the delimeter string from delarray[]
9069 // closest so far 9912 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 } 9913 }
9075 } 9914 }
9076 } 9915 }
9077 9916
9078 // Scan for spacers 9917 /*
9079 9918 * Output source string starting at i through start of earliest delimeter.
9080 if (offset[best] != beginning) 9919 */
9920 if (keepNulls || (earliestSrc > i))
9081 { 9921 {
9082 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9922 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 } 9923 }
9107 9924
9108 // This is the normal exit from the scanning loop 9925 /*
9926 * If no delimeter found at or after i, we're done scanning.
9927 */
9928 if (earliestDel < 0) break;
9109 9929
9110 if (best == mlen) 9930 /*
9931 * If delimeter was a spacer, output the spacer.
9932 */
9933 if (earliestDel >= seplen)
9111 { 9934 {
9112 // no markers were found on this pass 9935 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 } 9936 }
9118 9937
9119 // Otherwise we just add the newly delimited token 9938 /*
9120 // and recalculate where the search should continue. 9939 * Look at rest of src string following delimeter.
9121 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9940 */
9122 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9941 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 } 9942 }
9136 9943
9137 // This an awkward an not very intuitive boundary case. If the 9944 /*
9138 // last substring is a tokenizer, then there is an implied trailing 9945 * 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 9946 */
9140 // arduous. Alternatively the 'break' could be replced with a return 9947 object[] outlist = new object[outlen];
9141 // but that's shabby programming. 9948 for (i = 0; i < outlen; i ++)
9142
9143 if ((beginning == srclen) && (keepNulls))
9144 { 9949 {
9145 if (srclen != 0) 9950 outlist[i] = new LSL_String(outarray[i]);
9146 tokens.Add(new LSL_String(""));
9147 } 9951 }
9148 9952 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 } 9953 }
9163 9954
9164 public LSL_Integer llGetObjectPermMask(int mask) 9955 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9253,6 +10044,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9253 case 4: 10044 case 4:
9254 return (int)item.NextPermissions; 10045 return (int)item.NextPermissions;
9255 } 10046 }
10047 m_host.TaskInventory.LockItemsForRead(false);
9256 10048
9257 return -1; 10049 return -1;
9258 } 10050 }
@@ -9455,31 +10247,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9455 UUID key = new UUID(); 10247 UUID key = new UUID();
9456 if (UUID.TryParse(id, out key)) 10248 if (UUID.TryParse(id, out key))
9457 { 10249 {
9458 try 10250 // return total object mass
9459 { 10251 SceneObjectPart part = World.GetSceneObjectPart(key);
9460 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10252 if (part != null)
9461 if (obj != null) 10253 return part.ParentGroup.GetMass();
9462 return (double)obj.GetMass(); 10254
9463 // the object is null so the key is for an avatar 10255 // the object is null so the key is for an avatar
9464 ScenePresence avatar = World.GetScenePresence(key); 10256 ScenePresence avatar = World.GetScenePresence(key);
9465 if (avatar != null) 10257 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 { 10258 {
9475 return 0; // The Object/Agent not in the region so just return zero 10259 if (avatar.IsChildAgent)
10260 {
10261 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10262 // child agents have a mass of 1.0
10263 return 1;
10264 }
10265 else
10266 {
10267 return (double)avatar.GetMass();
10268 }
9476 } 10269 }
9477 } 10270 }
9478 return 0; 10271 return 0;
9479 } 10272 }
9480 10273
9481 /// <summary> 10274 /// <summary>
9482 /// illListReplaceList removes the sub-list defined by the inclusive indices 10275 /// llListReplaceList removes the sub-list defined by the inclusive indices
9483 /// start and end and inserts the src list in its place. The inclusive 10276 /// 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 10277 /// 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 10278 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9536,16 +10329,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9536 // based upon end. Note that if end exceeds the upper 10329 // based upon end. Note that if end exceeds the upper
9537 // bound in this case, the entire destination list 10330 // bound in this case, the entire destination list
9538 // is removed. 10331 // is removed.
9539 else 10332 else if (start == 0)
9540 { 10333 {
9541 if (end + 1 < dest.Length) 10334 if (end + 1 < dest.Length)
9542 {
9543 return src + dest.GetSublist(end + 1, -1); 10335 return src + dest.GetSublist(end + 1, -1);
9544 }
9545 else 10336 else
9546 {
9547 return src; 10337 return src;
9548 } 10338 }
10339 else // Start < 0
10340 {
10341 if (end + 1 < dest.Length)
10342 return dest.GetSublist(end + 1, -1);
10343 else
10344 return new LSL_List();
9549 } 10345 }
9550 } 10346 }
9551 // Finally, if start > end, we strip away a prefix and 10347 // Finally, if start > end, we strip away a prefix and
@@ -9596,17 +10392,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9596 int width = 0; 10392 int width = 0;
9597 int height = 0; 10393 int height = 0;
9598 10394
9599 ParcelMediaCommandEnum? commandToSend = null; 10395 uint commandToSend = 0;
9600 float time = 0.0f; // default is from start 10396 float time = 0.0f; // default is from start
9601 10397
9602 ScenePresence presence = null; 10398 ScenePresence presence = null;
9603 10399
9604 for (int i = 0; i < commandList.Data.Length; i++) 10400 for (int i = 0; i < commandList.Data.Length; i++)
9605 { 10401 {
9606 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10402 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9607 switch (command) 10403 switch (command)
9608 { 10404 {
9609 case ParcelMediaCommandEnum.Agent: 10405 case (uint)ParcelMediaCommandEnum.Agent:
9610 // we send only to one agent 10406 // we send only to one agent
9611 if ((i + 1) < commandList.Length) 10407 if ((i + 1) < commandList.Length)
9612 { 10408 {
@@ -9623,25 +10419,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9623 } 10419 }
9624 break; 10420 break;
9625 10421
9626 case ParcelMediaCommandEnum.Loop: 10422 case (uint)ParcelMediaCommandEnum.Loop:
9627 loop = 1; 10423 loop = 1;
9628 commandToSend = command; 10424 commandToSend = command;
9629 update = true; //need to send the media update packet to set looping 10425 update = true; //need to send the media update packet to set looping
9630 break; 10426 break;
9631 10427
9632 case ParcelMediaCommandEnum.Play: 10428 case (uint)ParcelMediaCommandEnum.Play:
9633 loop = 0; 10429 loop = 0;
9634 commandToSend = command; 10430 commandToSend = command;
9635 update = true; //need to send the media update packet to make sure it doesn't loop 10431 update = true; //need to send the media update packet to make sure it doesn't loop
9636 break; 10432 break;
9637 10433
9638 case ParcelMediaCommandEnum.Pause: 10434 case (uint)ParcelMediaCommandEnum.Pause:
9639 case ParcelMediaCommandEnum.Stop: 10435 case (uint)ParcelMediaCommandEnum.Stop:
9640 case ParcelMediaCommandEnum.Unload: 10436 case (uint)ParcelMediaCommandEnum.Unload:
9641 commandToSend = command; 10437 commandToSend = command;
9642 break; 10438 break;
9643 10439
9644 case ParcelMediaCommandEnum.Url: 10440 case (uint)ParcelMediaCommandEnum.Url:
9645 if ((i + 1) < commandList.Length) 10441 if ((i + 1) < commandList.Length)
9646 { 10442 {
9647 if (commandList.Data[i + 1] is LSL_String) 10443 if (commandList.Data[i + 1] is LSL_String)
@@ -9654,7 +10450,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9654 } 10450 }
9655 break; 10451 break;
9656 10452
9657 case ParcelMediaCommandEnum.Texture: 10453 case (uint)ParcelMediaCommandEnum.Texture:
9658 if ((i + 1) < commandList.Length) 10454 if ((i + 1) < commandList.Length)
9659 { 10455 {
9660 if (commandList.Data[i + 1] is LSL_String) 10456 if (commandList.Data[i + 1] is LSL_String)
@@ -9667,7 +10463,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9667 } 10463 }
9668 break; 10464 break;
9669 10465
9670 case ParcelMediaCommandEnum.Time: 10466 case (uint)ParcelMediaCommandEnum.Time:
9671 if ((i + 1) < commandList.Length) 10467 if ((i + 1) < commandList.Length)
9672 { 10468 {
9673 if (commandList.Data[i + 1] is LSL_Float) 10469 if (commandList.Data[i + 1] is LSL_Float)
@@ -9679,7 +10475,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9679 } 10475 }
9680 break; 10476 break;
9681 10477
9682 case ParcelMediaCommandEnum.AutoAlign: 10478 case (uint)ParcelMediaCommandEnum.AutoAlign:
9683 if ((i + 1) < commandList.Length) 10479 if ((i + 1) < commandList.Length)
9684 { 10480 {
9685 if (commandList.Data[i + 1] is LSL_Integer) 10481 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9693,7 +10489,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9693 } 10489 }
9694 break; 10490 break;
9695 10491
9696 case ParcelMediaCommandEnum.Type: 10492 case (uint)ParcelMediaCommandEnum.Type:
9697 if ((i + 1) < commandList.Length) 10493 if ((i + 1) < commandList.Length)
9698 { 10494 {
9699 if (commandList.Data[i + 1] is LSL_String) 10495 if (commandList.Data[i + 1] is LSL_String)
@@ -9706,7 +10502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9706 } 10502 }
9707 break; 10503 break;
9708 10504
9709 case ParcelMediaCommandEnum.Desc: 10505 case (uint)ParcelMediaCommandEnum.Desc:
9710 if ((i + 1) < commandList.Length) 10506 if ((i + 1) < commandList.Length)
9711 { 10507 {
9712 if (commandList.Data[i + 1] is LSL_String) 10508 if (commandList.Data[i + 1] is LSL_String)
@@ -9719,7 +10515,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9719 } 10515 }
9720 break; 10516 break;
9721 10517
9722 case ParcelMediaCommandEnum.Size: 10518 case (uint)ParcelMediaCommandEnum.Size:
9723 if ((i + 2) < commandList.Length) 10519 if ((i + 2) < commandList.Length)
9724 { 10520 {
9725 if (commandList.Data[i + 1] is LSL_Integer) 10521 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9789,7 +10585,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9789 } 10585 }
9790 } 10586 }
9791 10587
9792 if (commandToSend != null) 10588 if (commandToSend != 0)
9793 { 10589 {
9794 // the commandList contained a start/stop/... command, too 10590 // the commandList contained a start/stop/... command, too
9795 if (presence == null) 10591 if (presence == null)
@@ -9826,7 +10622,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9826 10622
9827 if (aList.Data[i] != null) 10623 if (aList.Data[i] != null)
9828 { 10624 {
9829 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10625 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9830 { 10626 {
9831 case ParcelMediaCommandEnum.Url: 10627 case ParcelMediaCommandEnum.Url:
9832 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10628 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9883,15 +10679,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9883 10679
9884 if (quick_pay_buttons.Data.Length < 4) 10680 if (quick_pay_buttons.Data.Length < 4)
9885 { 10681 {
9886 LSLError("List must have at least 4 elements"); 10682 int x;
9887 return; 10683 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10684 {
10685 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10686 }
9888 } 10687 }
9889 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10688 int[] nPrice = new int[5];
9890 10689 nPrice[0] = price;
9891 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10690 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9892 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10691 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9893 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10692 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9894 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10693 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10694 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9895 m_host.ParentGroup.HasGroupChanged = true; 10695 m_host.ParentGroup.HasGroupChanged = true;
9896 } 10696 }
9897 10697
@@ -9908,7 +10708,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9908 return new LSL_Vector(); 10708 return new LSL_Vector();
9909 } 10709 }
9910 10710
9911 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10711// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10712 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9912 if (presence != null) 10713 if (presence != null)
9913 { 10714 {
9914 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10715 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9930,7 +10731,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9930 return new LSL_Rotation(); 10731 return new LSL_Rotation();
9931 } 10732 }
9932 10733
9933 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10734// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10735 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9934 if (presence != null) 10736 if (presence != null)
9935 { 10737 {
9936 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10738 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9990,14 +10792,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9990 { 10792 {
9991 m_host.AddScriptLPS(1); 10793 m_host.AddScriptLPS(1);
9992 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10794 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9993 if (detectedParams == null) return; // only works on the first detected avatar 10795 if (detectedParams == null)
9994 10796 {
10797 if (m_host.ParentGroup.IsAttachment == true)
10798 {
10799 detectedParams = new DetectParams();
10800 detectedParams.Key = m_host.OwnerID;
10801 }
10802 else
10803 {
10804 return;
10805 }
10806 }
10807
9995 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10808 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9996 if (avatar != null) 10809 if (avatar != null)
9997 { 10810 {
9998 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10811 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9999 simname, pos, lookAt); 10812 simname, pos, lookAt);
10000 } 10813 }
10814
10001 ScriptSleep(1000); 10815 ScriptSleep(1000);
10002 } 10816 }
10003 10817
@@ -10121,12 +10935,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10121 10935
10122 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10936 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10123 object[] data = rules.Data; 10937 object[] data = rules.Data;
10124 for (int i = 0; i < data.Length; ++i) { 10938 for (int i = 0; i < data.Length; ++i)
10939 {
10125 int type = Convert.ToInt32(data[i++].ToString()); 10940 int type = Convert.ToInt32(data[i++].ToString());
10126 if (i >= data.Length) break; // odd number of entries => ignore the last 10941 if (i >= data.Length) break; // odd number of entries => ignore the last
10127 10942
10128 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10943 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10129 switch (type) { 10944 switch (type)
10945 {
10130 case ScriptBaseClass.CAMERA_FOCUS: 10946 case ScriptBaseClass.CAMERA_FOCUS:
10131 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10947 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10132 case ScriptBaseClass.CAMERA_POSITION: 10948 case ScriptBaseClass.CAMERA_POSITION:
@@ -10231,19 +11047,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10231 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11047 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10232 { 11048 {
10233 m_host.AddScriptLPS(1); 11049 m_host.AddScriptLPS(1);
10234 string ret = String.Empty; 11050
10235 string src1 = llBase64ToString(str1); 11051 if (str1 == String.Empty)
10236 string src2 = llBase64ToString(str2); 11052 return String.Empty;
10237 int c = 0; 11053 if (str2 == String.Empty)
10238 for (int i = 0; i < src1.Length; i++) 11054 return str1;
11055
11056 int len = str2.Length;
11057 if ((len % 4) != 0) // LL is EVIL!!!!
10239 { 11058 {
10240 ret += (char) (src1[i] ^ src2[c]); 11059 while (str2.EndsWith("="))
11060 str2 = str2.Substring(0, str2.Length - 1);
11061
11062 len = str2.Length;
11063 int mod = len % 4;
11064
11065 if (mod == 1)
11066 str2 = str2.Substring(0, str2.Length - 1);
11067 else if (mod == 2)
11068 str2 += "==";
11069 else if (mod == 3)
11070 str2 += "=";
11071 }
10241 11072
10242 c++; 11073 byte[] data1;
10243 if (c >= src2.Length) 11074 byte[] data2;
10244 c = 0; 11075 try
11076 {
11077 data1 = Convert.FromBase64String(str1);
11078 data2 = Convert.FromBase64String(str2);
10245 } 11079 }
10246 return llStringToBase64(ret); 11080 catch (Exception)
11081 {
11082 return new LSL_String(String.Empty);
11083 }
11084
11085 byte[] d2 = new Byte[data1.Length];
11086 int pos = 0;
11087
11088 if (data1.Length <= data2.Length)
11089 {
11090 Array.Copy(data2, 0, d2, 0, data1.Length);
11091 }
11092 else
11093 {
11094 while (pos < data1.Length)
11095 {
11096 len = data1.Length - pos;
11097 if (len > data2.Length)
11098 len = data2.Length;
11099
11100 Array.Copy(data2, 0, d2, pos, len);
11101 pos += len;
11102 }
11103 }
11104
11105 for (pos = 0 ; pos < data1.Length ; pos++ )
11106 data1[pos] ^= d2[pos];
11107
11108 return Convert.ToBase64String(data1);
10247 } 11109 }
10248 11110
10249 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11111 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10296,16 +11158,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10296 if (userAgent != null) 11158 if (userAgent != null)
10297 httpHeaders["User-Agent"] = userAgent; 11159 httpHeaders["User-Agent"] = userAgent;
10298 11160
11161 // See if the URL contains any header hacks
11162 string[] urlParts = url.Split(new char[] {'\n'});
11163 if (urlParts.Length > 1)
11164 {
11165 // Iterate the passed headers and parse them
11166 for (int i = 1 ; i < urlParts.Length ; i++ )
11167 {
11168 // The rest of those would be added to the body in SL.
11169 // Let's not do that.
11170 if (urlParts[i] == String.Empty)
11171 break;
11172
11173 // See if this could be a valid header
11174 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11175 if (headerParts.Length != 2)
11176 continue;
11177
11178 string headerName = headerParts[0].Trim();
11179 string headerValue = headerParts[1].Trim();
11180
11181 // Filter out headers that could be used to abuse
11182 // another system or cloak the request
11183 if (headerName.ToLower() == "x-secondlife-shard" ||
11184 headerName.ToLower() == "x-secondlife-object-name" ||
11185 headerName.ToLower() == "x-secondlife-object-key" ||
11186 headerName.ToLower() == "x-secondlife-region" ||
11187 headerName.ToLower() == "x-secondlife-local-position" ||
11188 headerName.ToLower() == "x-secondlife-local-velocity" ||
11189 headerName.ToLower() == "x-secondlife-local-rotation" ||
11190 headerName.ToLower() == "x-secondlife-owner-name" ||
11191 headerName.ToLower() == "x-secondlife-owner-key" ||
11192 headerName.ToLower() == "connection" ||
11193 headerName.ToLower() == "content-length" ||
11194 headerName.ToLower() == "from" ||
11195 headerName.ToLower() == "host" ||
11196 headerName.ToLower() == "proxy-authorization" ||
11197 headerName.ToLower() == "referer" ||
11198 headerName.ToLower() == "trailer" ||
11199 headerName.ToLower() == "transfer-encoding" ||
11200 headerName.ToLower() == "via" ||
11201 headerName.ToLower() == "authorization")
11202 continue;
11203
11204 httpHeaders[headerName] = headerValue;
11205 }
11206
11207 // Finally, strip any protocol specifier from the URL
11208 url = urlParts[0].Trim();
11209 int idx = url.IndexOf(" HTTP/");
11210 if (idx != -1)
11211 url = url.Substring(0, idx);
11212 }
11213
10299 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11214 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10300 Regex r = new Regex(authregex); 11215 Regex r = new Regex(authregex);
10301 int[] gnums = r.GetGroupNumbers(); 11216 int[] gnums = r.GetGroupNumbers();
10302 Match m = r.Match(url); 11217 Match m = r.Match(url);
10303 if (m.Success) { 11218 if (m.Success)
10304 for (int i = 1; i < gnums.Length; i++) { 11219 {
11220 for (int i = 1; i < gnums.Length; i++)
11221 {
10305 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11222 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10306 //CaptureCollection cc = g.Captures; 11223 //CaptureCollection cc = g.Captures;
10307 } 11224 }
10308 if (m.Groups.Count == 5) { 11225 if (m.Groups.Count == 5)
11226 {
10309 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11227 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(); 11228 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10311 } 11229 }
@@ -10508,6 +11426,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10508 11426
10509 LSL_List ret = new LSL_List(); 11427 LSL_List ret = new LSL_List();
10510 UUID key = new UUID(); 11428 UUID key = new UUID();
11429
11430
10511 if (UUID.TryParse(id, out key)) 11431 if (UUID.TryParse(id, out key))
10512 { 11432 {
10513 ScenePresence av = World.GetScenePresence(key); 11433 ScenePresence av = World.GetScenePresence(key);
@@ -10525,13 +11445,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10525 ret.Add(new LSL_String("")); 11445 ret.Add(new LSL_String(""));
10526 break; 11446 break;
10527 case ScriptBaseClass.OBJECT_POS: 11447 case ScriptBaseClass.OBJECT_POS:
10528 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11448 Vector3 avpos;
11449
11450 if (av.ParentID != 0 && av.ParentPart != null)
11451 {
11452 avpos = av.OffsetPosition;
11453
11454 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11455 avpos -= sitOffset;
11456
11457 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11458 }
11459 else
11460 avpos = av.AbsolutePosition;
11461
11462 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10529 break; 11463 break;
10530 case ScriptBaseClass.OBJECT_ROT: 11464 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)); 11465 Quaternion avrot = av.Rotation;
11466 if (av.ParentID != 0 && av.ParentPart != null)
11467 {
11468 avrot = av.ParentPart.GetWorldRotation() * avrot;
11469 }
11470 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10532 break; 11471 break;
10533 case ScriptBaseClass.OBJECT_VELOCITY: 11472 case ScriptBaseClass.OBJECT_VELOCITY:
10534 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11473 Vector3 avvel = av.Velocity;
11474 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10535 break; 11475 break;
10536 case ScriptBaseClass.OBJECT_OWNER: 11476 case ScriptBaseClass.OBJECT_OWNER:
10537 ret.Add(new LSL_String(id)); 11477 ret.Add(new LSL_String(id));
@@ -10587,11 +11527,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10587 case ScriptBaseClass.OBJECT_NAME: 11527 case ScriptBaseClass.OBJECT_NAME:
10588 ret.Add(new LSL_String(obj.Name)); 11528 ret.Add(new LSL_String(obj.Name));
10589 break; 11529 break;
10590 case ScriptBaseClass.OBJECT_DESC: 11530 case ScriptBaseClass.OBJECT_DESC:
10591 ret.Add(new LSL_String(obj.Description)); 11531 ret.Add(new LSL_String(obj.Description));
10592 break; 11532 break;
10593 case ScriptBaseClass.OBJECT_POS: 11533 case ScriptBaseClass.OBJECT_POS:
10594 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11534 Vector3 opos = obj.AbsolutePosition;
11535 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10595 break; 11536 break;
10596 case ScriptBaseClass.OBJECT_ROT: 11537 case ScriptBaseClass.OBJECT_ROT:
10597 { 11538 {
@@ -10641,9 +11582,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10641 // The value returned in SL for normal prims is prim count 11582 // The value returned in SL for normal prims is prim count
10642 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11583 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10643 break; 11584 break;
10644 // The following 3 costs I have intentionaly coded to return zero. They are part of 11585
10645 // "Land Impact" calculations. These calculations are probably not applicable 11586 // 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: 11587 case ScriptBaseClass.OBJECT_SERVER_COST:
10648 // The linden calculation is here 11588 // The linden calculation is here
10649 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11589 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10651,16 +11591,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10651 ret.Add(new LSL_Float(0)); 11591 ret.Add(new LSL_Float(0));
10652 break; 11592 break;
10653 case ScriptBaseClass.OBJECT_STREAMING_COST: 11593 case ScriptBaseClass.OBJECT_STREAMING_COST:
10654 // The linden calculation is here 11594 // The value returned in SL for normal prims is prim count * 0.06
10655 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11595 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; 11596 break;
10659 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11597 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10660 // The linden calculation is here 11598 // The value returned in SL for normal prims is prim count
10661 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11599 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; 11600 break;
10665 default: 11601 default:
10666 // Invalid or unhandled constant. 11602 // Invalid or unhandled constant.
@@ -10871,15 +11807,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10871 return result; 11807 return result;
10872 } 11808 }
10873 11809
10874 public void print(string str) 11810 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10875 { 11811 {
10876 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11812 List<SceneObjectPart> parts = GetLinkParts(link);
10877 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11813 if (parts.Count < 1)
10878 if (ossl != null) 11814 return 0;
10879 { 11815
10880 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11816 return GetNumberOfSides(parts[0]);
10881 m_log.Info("LSL print():" + str);
10882 }
10883 } 11817 }
10884 11818
10885 private string Name2Username(string name) 11819 private string Name2Username(string name)
@@ -10924,7 +11858,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10924 11858
10925 return rq.ToString(); 11859 return rq.ToString();
10926 } 11860 }
10927 11861/*
11862 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11863 {
11864 m_SayShoutCount = 0;
11865 }
11866*/
10928 private struct Tri 11867 private struct Tri
10929 { 11868 {
10930 public Vector3 p1; 11869 public Vector3 p1;
@@ -11064,9 +12003,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11064 12003
11065 ContactResult result = new ContactResult (); 12004 ContactResult result = new ContactResult ();
11066 result.ConsumerID = group.LocalId; 12005 result.ConsumerID = group.LocalId;
11067 result.Depth = intersection.distance; 12006// result.Depth = intersection.distance;
11068 result.Normal = intersection.normal; 12007 result.Normal = intersection.normal;
11069 result.Pos = intersection.ipoint; 12008 result.Pos = intersection.ipoint;
12009 result.Depth = Vector3.Mag(rayStart - result.Pos);
11070 12010
11071 contacts.Add(result); 12011 contacts.Add(result);
11072 }); 12012 });
@@ -11199,6 +12139,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11199 12139
11200 return contacts[0]; 12140 return contacts[0];
11201 } 12141 }
12142/*
12143 // not done:
12144 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12145 {
12146 ContactResult[] contacts = null;
12147 World.ForEachSOG(delegate(SceneObjectGroup group)
12148 {
12149 if (m_host.ParentGroup == group)
12150 return;
12151
12152 if (group.IsAttachment)
12153 return;
12154
12155 if(group.RootPart.PhysActor != null)
12156 return;
12157
12158 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12159 });
12160 return contacts;
12161 }
12162*/
11202 12163
11203 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12164 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11204 { 12165 {
@@ -11240,32 +12201,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11240 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12201 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11241 12202
11242 12203
11243 if (checkTerrain) 12204 if (World.SuportsRayCastFiltered())
11244 { 12205 {
11245 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12206 if (dist == 0)
11246 if (groundContact != null) 12207 return list;
11247 results.Add((ContactResult)groundContact);
11248 }
11249 12208
11250 if (checkAgents) 12209 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11251 { 12210 if (checkTerrain)
11252 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12211 rayfilter |= RayFilterFlags.land;
11253 foreach (ContactResult r in agentHits) 12212// if (checkAgents)
11254 results.Add(r); 12213// rayfilter |= RayFilterFlags.agent;
11255 } 12214 if (checkPhysical)
12215 rayfilter |= RayFilterFlags.physical;
12216 if (checkNonPhysical)
12217 rayfilter |= RayFilterFlags.nonphysical;
12218 if (detectPhantom)
12219 rayfilter |= RayFilterFlags.LSLPhanton;
12220
12221 Vector3 direction = dir * ( 1/dist);
12222
12223 if(rayfilter == 0)
12224 {
12225 list.Add(new LSL_Integer(0));
12226 return list;
12227 }
12228
12229 // get some more contacts to sort ???
12230 int physcount = 4 * count;
12231 if (physcount > 20)
12232 physcount = 20;
12233
12234 object physresults;
12235 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12236
12237 if (physresults == null)
12238 {
12239 list.Add(new LSL_Integer(-3)); // timeout error
12240 return list;
12241 }
11256 12242
11257 if (checkPhysical || checkNonPhysical || detectPhantom) 12243 results = (List<ContactResult>)physresults;
12244
12245 // for now physics doesn't detect sitted avatars so do it outside physics
12246 if (checkAgents)
12247 {
12248 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12249 foreach (ContactResult r in agentHits)
12250 results.Add(r);
12251 }
12252
12253 // TODO: Replace this with a better solution. ObjectIntersection can only
12254 // detect nonphysical phantoms. They are detected by virtue of being
12255 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12256 // physicsl phantoms as done by the physics scene
12257 // We don't want anything else but phantoms here.
12258 if (detectPhantom)
12259 {
12260 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12261 foreach (ContactResult r in objectHits)
12262 results.Add(r);
12263 }
12264 }
12265 else
11258 { 12266 {
11259 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12267 if (checkTerrain)
11260 foreach (ContactResult r in objectHits) 12268 {
11261 results.Add(r); 12269 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12270 if (groundContact != null)
12271 results.Add((ContactResult)groundContact);
12272 }
12273
12274 if (checkAgents)
12275 {
12276 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12277 foreach (ContactResult r in agentHits)
12278 results.Add(r);
12279 }
12280
12281 if (checkPhysical || checkNonPhysical || detectPhantom)
12282 {
12283 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12284 foreach (ContactResult r in objectHits)
12285 results.Add(r);
12286 }
11262 } 12287 }
11263 12288
11264 results.Sort(delegate(ContactResult a, ContactResult b) 12289 results.Sort(delegate(ContactResult a, ContactResult b)
11265 { 12290 {
11266 return a.Depth.CompareTo(b.Depth); 12291 return a.Depth.CompareTo(b.Depth);
11267 }); 12292 });
11268 12293
11269 int values = 0; 12294 int values = 0;
11270 SceneObjectGroup thisgrp = m_host.ParentGroup; 12295 SceneObjectGroup thisgrp = m_host.ParentGroup;
11271 12296
@@ -11358,7 +12383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11358 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12383 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11359 if (!isAccount) return 0; 12384 if (!isAccount) return 0;
11360 if (estate.HasAccess(id)) return 1; 12385 if (estate.HasAccess(id)) return 1;
11361 if (estate.IsBanned(id)) 12386 if (estate.IsBanned(id, World.GetUserFlags(id)))
11362 estate.RemoveBan(id); 12387 estate.RemoveBan(id);
11363 estate.AddEstateUser(id); 12388 estate.AddEstateUser(id);
11364 break; 12389 break;
@@ -11377,14 +12402,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11377 break; 12402 break;
11378 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12403 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11379 if (!isAccount) return 0; 12404 if (!isAccount) return 0;
11380 if (estate.IsBanned(id)) return 1; 12405 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11381 EstateBan ban = new EstateBan(); 12406 EstateBan ban = new EstateBan();
11382 ban.EstateID = estate.EstateID; 12407 ban.EstateID = estate.EstateID;
11383 ban.BannedUserID = id; 12408 ban.BannedUserID = id;
11384 estate.AddBan(ban); 12409 estate.AddBan(ban);
11385 break; 12410 break;
11386 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12411 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11387 if (!isAccount || !estate.IsBanned(id)) return 0; 12412 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11388 estate.RemoveBan(id); 12413 estate.RemoveBan(id);
11389 break; 12414 break;
11390 default: return 0; 12415 default: return 0;
@@ -11413,7 +12438,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11413 return 16384; 12438 return 16384;
11414 } 12439 }
11415 12440
11416 public LSL_Integer llGetUsedMemory() 12441 public virtual LSL_Integer llGetUsedMemory()
11417 { 12442 {
11418 m_host.AddScriptLPS(1); 12443 m_host.AddScriptLPS(1);
11419 // The value returned for LSO scripts in SL 12444 // The value returned for LSO scripts in SL
@@ -11441,22 +12466,734 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11441 public void llSetSoundQueueing(int queue) 12466 public void llSetSoundQueueing(int queue)
11442 { 12467 {
11443 m_host.AddScriptLPS(1); 12468 m_host.AddScriptLPS(1);
11444 NotImplemented("llSetSoundQueueing");
11445 } 12469 }
11446 12470
11447 public void llCollisionSprite(string impact_sprite) 12471 public void llCollisionSprite(string impact_sprite)
11448 { 12472 {
11449 m_host.AddScriptLPS(1); 12473 m_host.AddScriptLPS(1);
11450 NotImplemented("llCollisionSprite"); 12474 // Viewer 2.0 broke this and it's likely LL has no intention
12475 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11451 } 12476 }
11452 12477
11453 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12478 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11454 { 12479 {
11455 m_host.AddScriptLPS(1); 12480 m_host.AddScriptLPS(1);
11456 NotImplemented("llGodLikeRezObject"); 12481
12482 if (!World.Permissions.IsGod(m_host.OwnerID))
12483 NotImplemented("llGodLikeRezObject");
12484
12485 AssetBase rezAsset = World.AssetService.Get(inventory);
12486 if (rezAsset == null)
12487 {
12488 llSay(0, "Asset not found");
12489 return;
12490 }
12491
12492 SceneObjectGroup group = null;
12493
12494 try
12495 {
12496 string xmlData = Utils.BytesToString(rezAsset.Data);
12497 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12498 }
12499 catch
12500 {
12501 llSay(0, "Asset not found");
12502 return;
12503 }
12504
12505 if (group == null)
12506 {
12507 llSay(0, "Asset not found");
12508 return;
12509 }
12510
12511 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12512 group.RootPart.AttachOffset = group.AbsolutePosition;
12513
12514 group.ResetIDs();
12515
12516 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12517 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12518 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12519 group.ScheduleGroupForFullUpdate();
12520
12521 // objects rezzed with this method are die_at_edge by default.
12522 group.RootPart.SetDieAtEdge(true);
12523
12524 group.ResumeScripts();
12525
12526 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12527 "object_rez", new Object[] {
12528 new LSL_String(
12529 group.RootPart.UUID.ToString()) },
12530 new DetectParams[0]));
12531 }
12532
12533 public LSL_String llTransferLindenDollars(string destination, int amount)
12534 {
12535 UUID txn = UUID.Random();
12536
12537 Util.FireAndForget(delegate(object x)
12538 {
12539 int replycode = 0;
12540 string replydata = destination + "," + amount.ToString();
12541
12542 try
12543 {
12544 TaskInventoryItem item = m_item;
12545 if (item == null)
12546 {
12547 replydata = "SERVICE_ERROR";
12548 return;
12549 }
12550
12551 m_host.AddScriptLPS(1);
12552
12553 if (item.PermsGranter == UUID.Zero)
12554 {
12555 replydata = "MISSING_PERMISSION_DEBIT";
12556 return;
12557 }
12558
12559 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12560 {
12561 replydata = "MISSING_PERMISSION_DEBIT";
12562 return;
12563 }
12564
12565 UUID toID = new UUID();
12566
12567 if (!UUID.TryParse(destination, out toID))
12568 {
12569 replydata = "INVALID_AGENT";
12570 return;
12571 }
12572
12573 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12574
12575 if (money == null)
12576 {
12577 replydata = "TRANSFERS_DISABLED";
12578 return;
12579 }
12580
12581 bool result = money.ObjectGiveMoney(
12582 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
12583
12584 if (result)
12585 {
12586 replycode = 1;
12587 return;
12588 }
12589
12590 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12591 }
12592 finally
12593 {
12594 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12595 "transaction_result", new Object[] {
12596 new LSL_String(txn.ToString()),
12597 new LSL_Integer(replycode),
12598 new LSL_String(replydata) },
12599 new DetectParams[0]));
12600 }
12601 });
12602
12603 return txn.ToString();
11457 } 12604 }
11458 12605
11459 #endregion 12606 #endregion
12607
12608 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12609 {
12610 SceneObjectGroup group = m_host.ParentGroup;
12611
12612 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12613 return;
12614 if (group.IsAttachment)
12615 return;
12616
12617 if (frames.Data.Length > 0) // We are getting a new motion
12618 {
12619 if (group.RootPart.KeyframeMotion != null)
12620 group.RootPart.KeyframeMotion.Delete();
12621 group.RootPart.KeyframeMotion = null;
12622
12623 int idx = 0;
12624
12625 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12626 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12627
12628 while (idx < options.Data.Length)
12629 {
12630 int option = (int)options.GetLSLIntegerItem(idx++);
12631 int remain = options.Data.Length - idx;
12632
12633 switch (option)
12634 {
12635 case ScriptBaseClass.KFM_MODE:
12636 if (remain < 1)
12637 break;
12638 int modeval = (int)options.GetLSLIntegerItem(idx++);
12639 switch(modeval)
12640 {
12641 case ScriptBaseClass.KFM_FORWARD:
12642 mode = KeyframeMotion.PlayMode.Forward;
12643 break;
12644 case ScriptBaseClass.KFM_REVERSE:
12645 mode = KeyframeMotion.PlayMode.Reverse;
12646 break;
12647 case ScriptBaseClass.KFM_LOOP:
12648 mode = KeyframeMotion.PlayMode.Loop;
12649 break;
12650 case ScriptBaseClass.KFM_PING_PONG:
12651 mode = KeyframeMotion.PlayMode.PingPong;
12652 break;
12653 }
12654 break;
12655 case ScriptBaseClass.KFM_DATA:
12656 if (remain < 1)
12657 break;
12658 int dataval = (int)options.GetLSLIntegerItem(idx++);
12659 data = (KeyframeMotion.DataFormat)dataval;
12660 break;
12661 }
12662 }
12663
12664 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12665
12666 idx = 0;
12667
12668 int elemLength = 2;
12669 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12670 elemLength = 3;
12671
12672 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12673 while (idx < frames.Data.Length)
12674 {
12675 int remain = frames.Data.Length - idx;
12676
12677 if (remain < elemLength)
12678 break;
12679
12680 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12681 frame.Position = null;
12682 frame.Rotation = null;
12683
12684 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12685 {
12686 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12687 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12688 }
12689 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12690 {
12691 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12692 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12693 }
12694
12695 float tempf = (float)frames.GetLSLFloatItem(idx++);
12696 frame.TimeMS = (int)(tempf * 1000.0f);
12697
12698 keyframes.Add(frame);
12699 }
12700
12701 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12702 group.RootPart.KeyframeMotion.Start();
12703 }
12704 else
12705 {
12706 if (group.RootPart.KeyframeMotion == null)
12707 return;
12708
12709 if (options.Data.Length == 0)
12710 {
12711 group.RootPart.KeyframeMotion.Stop();
12712 return;
12713 }
12714
12715 int code = (int)options.GetLSLIntegerItem(0);
12716
12717 int idx = 0;
12718
12719 while (idx < options.Data.Length)
12720 {
12721 int option = (int)options.GetLSLIntegerItem(idx++);
12722 int remain = options.Data.Length - idx;
12723
12724 switch (option)
12725 {
12726 case ScriptBaseClass.KFM_COMMAND:
12727 int cmd = (int)options.GetLSLIntegerItem(idx++);
12728 switch (cmd)
12729 {
12730 case ScriptBaseClass.KFM_CMD_PLAY:
12731 group.RootPart.KeyframeMotion.Start();
12732 break;
12733 case ScriptBaseClass.KFM_CMD_STOP:
12734 group.RootPart.KeyframeMotion.Stop();
12735 break;
12736 case ScriptBaseClass.KFM_CMD_PAUSE:
12737 group.RootPart.KeyframeMotion.Pause();
12738 break;
12739 }
12740 break;
12741 }
12742 }
12743 }
12744 }
12745
12746 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12747 {
12748 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12749
12750 int idx = 0;
12751 int idxStart = 0;
12752
12753 bool positionChanged = false;
12754 Vector3 finalPos = Vector3.Zero;
12755
12756 try
12757 {
12758 while (idx < rules.Length)
12759 {
12760 ++rulesParsed;
12761 int code = rules.GetLSLIntegerItem(idx++);
12762
12763 int remain = rules.Length - idx;
12764 idxStart = idx;
12765
12766 switch (code)
12767 {
12768 case (int)ScriptBaseClass.PRIM_POSITION:
12769 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12770 {
12771 if (remain < 1)
12772 return null;
12773
12774 LSL_Vector v;
12775 v = rules.GetVector3Item(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 if (part.LinkNum > 1)
12784 {
12785 localRot = GetPartLocalRot(part);
12786 localPos = GetPartLocalPos(part);
12787 }
12788
12789 v -= localPos;
12790 v /= localRot;
12791
12792 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12793
12794 v = v + 2 * sitOffset;
12795
12796 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12797 av.SendAvatarDataToAllAgents();
12798
12799 }
12800 break;
12801
12802 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12803 case (int)ScriptBaseClass.PRIM_ROTATION:
12804 {
12805 if (remain < 1)
12806 return null;
12807
12808 LSL_Rotation r;
12809 r = rules.GetQuaternionItem(idx++);
12810
12811 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12812 if (part == null)
12813 break;
12814
12815 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12816 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12817
12818 if (part.LinkNum > 1)
12819 localRot = GetPartLocalRot(part);
12820
12821 r = r * llGetRootRotation() / localRot;
12822 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12823 av.SendAvatarDataToAllAgents();
12824 }
12825 break;
12826
12827 // parse rest doing nothing but number of parameters error check
12828 case (int)ScriptBaseClass.PRIM_SIZE:
12829 case (int)ScriptBaseClass.PRIM_MATERIAL:
12830 case (int)ScriptBaseClass.PRIM_PHANTOM:
12831 case (int)ScriptBaseClass.PRIM_PHYSICS:
12832 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12833 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12834 case (int)ScriptBaseClass.PRIM_NAME:
12835 case (int)ScriptBaseClass.PRIM_DESC:
12836 if (remain < 1)
12837 return null;
12838 idx++;
12839 break;
12840
12841 case (int)ScriptBaseClass.PRIM_GLOW:
12842 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12843 case (int)ScriptBaseClass.PRIM_TEXGEN:
12844 if (remain < 2)
12845 return null;
12846 idx += 2;
12847 break;
12848
12849 case (int)ScriptBaseClass.PRIM_TYPE:
12850 if (remain < 3)
12851 return null;
12852 code = (int)rules.GetLSLIntegerItem(idx++);
12853 remain = rules.Length - idx;
12854 switch (code)
12855 {
12856 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12857 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12858 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12859 if (remain < 6)
12860 return null;
12861 idx += 6;
12862 break;
12863
12864 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12865 if (remain < 5)
12866 return null;
12867 idx += 5;
12868 break;
12869
12870 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12871 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12872 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12873 if (remain < 11)
12874 return null;
12875 idx += 11;
12876 break;
12877
12878 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12879 if (remain < 2)
12880 return null;
12881 idx += 2;
12882 break;
12883 }
12884 break;
12885
12886 case (int)ScriptBaseClass.PRIM_COLOR:
12887 case (int)ScriptBaseClass.PRIM_TEXT:
12888 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12889 case (int)ScriptBaseClass.PRIM_OMEGA:
12890 if (remain < 3)
12891 return null;
12892 idx += 3;
12893 break;
12894
12895 case (int)ScriptBaseClass.PRIM_TEXTURE:
12896 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12897 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12898 if (remain < 5)
12899 return null;
12900 idx += 5;
12901 break;
12902
12903 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12904 if (remain < 7)
12905 return null;
12906
12907 idx += 7;
12908 break;
12909
12910 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12911 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12912 return null;
12913
12914 return rules.GetSublist(idx, -1);
12915 }
12916 }
12917 }
12918 catch (InvalidCastException e)
12919 {
12920 ShoutError(string.Format(
12921 "{0} error running rule #{1}: arg #{2} ",
12922 originFunc, rulesParsed, idx - idxStart) + e.Message);
12923 }
12924 finally
12925 {
12926 if (positionChanged)
12927 {
12928 av.OffsetPosition = finalPos;
12929// av.SendAvatarDataToAllAgents();
12930 av.SendTerseUpdateToAllClients();
12931 positionChanged = false;
12932 }
12933 }
12934 return null;
12935 }
12936
12937 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12938 {
12939 // avatars case
12940 // replies as SL wiki
12941
12942// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12943 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12944
12945 int idx = 0;
12946 while (idx < rules.Length)
12947 {
12948 int code = (int)rules.GetLSLIntegerItem(idx++);
12949 int remain = rules.Length - idx;
12950
12951 switch (code)
12952 {
12953 case (int)ScriptBaseClass.PRIM_MATERIAL:
12954 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12955 break;
12956
12957 case (int)ScriptBaseClass.PRIM_PHYSICS:
12958 res.Add(new LSL_Integer(0));
12959 break;
12960
12961 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12962 res.Add(new LSL_Integer(0));
12963 break;
12964
12965 case (int)ScriptBaseClass.PRIM_PHANTOM:
12966 res.Add(new LSL_Integer(0));
12967 break;
12968
12969 case (int)ScriptBaseClass.PRIM_POSITION:
12970
12971 Vector3 pos = avatar.OffsetPosition;
12972
12973 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12974 pos -= sitOffset;
12975
12976 if( sitPart != null)
12977 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12978
12979 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12980 break;
12981
12982 case (int)ScriptBaseClass.PRIM_SIZE:
12983 // as in llGetAgentSize above
12984// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12985 Vector3 s = avatar.Appearance.AvatarSize;
12986 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
12987
12988 break;
12989
12990 case (int)ScriptBaseClass.PRIM_ROTATION:
12991 Quaternion rot = avatar.Rotation;
12992 if (sitPart != null)
12993 {
12994 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12995 }
12996
12997 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12998 break;
12999
13000 case (int)ScriptBaseClass.PRIM_TYPE:
13001 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13002 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13003 res.Add(new LSL_Vector(0f,1.0f,0f));
13004 res.Add(new LSL_Float(0.0f));
13005 res.Add(new LSL_Vector(0, 0, 0));
13006 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13007 res.Add(new LSL_Vector(0, 0, 0));
13008 break;
13009
13010 case (int)ScriptBaseClass.PRIM_TEXTURE:
13011 if (remain < 1)
13012 return null;
13013
13014 int face = (int)rules.GetLSLIntegerItem(idx++);
13015 if (face == ScriptBaseClass.ALL_SIDES)
13016 {
13017 for (face = 0; face < 21; face++)
13018 {
13019 res.Add(new LSL_String(""));
13020 res.Add(new LSL_Vector(0,0,0));
13021 res.Add(new LSL_Vector(0,0,0));
13022 res.Add(new LSL_Float(0.0));
13023 }
13024 }
13025 else
13026 {
13027 if (face >= 0 && face < 21)
13028 {
13029 res.Add(new LSL_String(""));
13030 res.Add(new LSL_Vector(0,0,0));
13031 res.Add(new LSL_Vector(0,0,0));
13032 res.Add(new LSL_Float(0.0));
13033 }
13034 }
13035 break;
13036
13037 case (int)ScriptBaseClass.PRIM_COLOR:
13038 if (remain < 1)
13039 return null;
13040
13041 face = (int)rules.GetLSLIntegerItem(idx++);
13042
13043 if (face == ScriptBaseClass.ALL_SIDES)
13044 {
13045 for (face = 0; face < 21; face++)
13046 {
13047 res.Add(new LSL_Vector(0,0,0));
13048 res.Add(new LSL_Float(0));
13049 }
13050 }
13051 else
13052 {
13053 res.Add(new LSL_Vector(0,0,0));
13054 res.Add(new LSL_Float(0));
13055 }
13056 break;
13057
13058 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13059 if (remain < 1)
13060 return null;
13061 face = (int)rules.GetLSLIntegerItem(idx++);
13062
13063 if (face == ScriptBaseClass.ALL_SIDES)
13064 {
13065 for (face = 0; face < 21; face++)
13066 {
13067 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13068 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13069 }
13070 }
13071 else
13072 {
13073 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13074 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13075 }
13076 break;
13077
13078 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13079 if (remain < 1)
13080 return null;
13081 face = (int)rules.GetLSLIntegerItem(idx++);
13082
13083 if (face == ScriptBaseClass.ALL_SIDES)
13084 {
13085 for (face = 0; face < 21; face++)
13086 {
13087 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13088 }
13089 }
13090 else
13091 {
13092 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13093 }
13094 break;
13095
13096 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13097 res.Add(new LSL_Integer(0));
13098 res.Add(new LSL_Integer(0));// softness
13099 res.Add(new LSL_Float(0.0f)); // gravity
13100 res.Add(new LSL_Float(0.0f)); // friction
13101 res.Add(new LSL_Float(0.0f)); // wind
13102 res.Add(new LSL_Float(0.0f)); // tension
13103 res.Add(new LSL_Vector(0f,0f,0f));
13104 break;
13105
13106 case (int)ScriptBaseClass.PRIM_TEXGEN:
13107 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13108 if (remain < 1)
13109 return null;
13110 face = (int)rules.GetLSLIntegerItem(idx++);
13111
13112 if (face == ScriptBaseClass.ALL_SIDES)
13113 {
13114 for (face = 0; face < 21; face++)
13115 {
13116 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13117 }
13118 }
13119 else
13120 {
13121 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13122 }
13123 break;
13124
13125 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13126 res.Add(new LSL_Integer(0));
13127 res.Add(new LSL_Vector(0f,0f,0f));
13128 res.Add(new LSL_Float(0f)); // intensity
13129 res.Add(new LSL_Float(0f)); // radius
13130 res.Add(new LSL_Float(0f)); // falloff
13131 break;
13132
13133 case (int)ScriptBaseClass.PRIM_GLOW:
13134 if (remain < 1)
13135 return null;
13136 face = (int)rules.GetLSLIntegerItem(idx++);
13137
13138 if (face == ScriptBaseClass.ALL_SIDES)
13139 {
13140 for (face = 0; face < 21; face++)
13141 {
13142 res.Add(new LSL_Float(0f));
13143 }
13144 }
13145 else
13146 {
13147 res.Add(new LSL_Float(0f));
13148 }
13149 break;
13150
13151 case (int)ScriptBaseClass.PRIM_TEXT:
13152 res.Add(new LSL_String(""));
13153 res.Add(new LSL_Vector(0f,0f,0f));
13154 res.Add(new LSL_Float(1.0f));
13155 break;
13156
13157 case (int)ScriptBaseClass.PRIM_NAME:
13158 res.Add(new LSL_String(avatar.Name));
13159 break;
13160
13161 case (int)ScriptBaseClass.PRIM_DESC:
13162 res.Add(new LSL_String(""));
13163 break;
13164
13165 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13166 Quaternion lrot = avatar.Rotation;
13167
13168 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13169 {
13170 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13171 }
13172 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13173 break;
13174
13175 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13176 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13177 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13178 lpos -= lsitOffset;
13179
13180 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13181 {
13182 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13183 }
13184 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13185 break;
13186
13187 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13188 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13189 return null;
13190
13191 return rules.GetSublist(idx, -1);
13192 }
13193 }
13194
13195 return null;
13196 }
11460 } 13197 }
11461 13198
11462 public class NotecardCache 13199 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 dd45406..d3ef378 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -93,7 +93,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
93 private const int AGENT = 1; 93 private const int AGENT = 1;
94 private const int AGENT_BY_USERNAME = 0x10; 94 private const int AGENT_BY_USERNAME = 0x10;
95 private const int NPC = 0x20; 95 private const int NPC = 0x20;
96 private const int OS_NPC = 0x01000000;
97 private const int ACTIVE = 2; 96 private const int ACTIVE = 2;
98 private const int PASSIVE = 4; 97 private const int PASSIVE = 4;
99 private const int SCRIPTED = 8; 98 private const int SCRIPTED = 8;
@@ -240,7 +239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
240 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 239 List<SensedEntity> sensedEntities = new List<SensedEntity>();
241 240
242 // Is the sensor type is AGENT and not SCRIPTED then include agents 241 // Is the sensor type is AGENT and not SCRIPTED then include agents
243 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 242 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
244 { 243 {
245 sensedEntities.AddRange(doAgentSensor(ts)); 244 sensedEntities.AddRange(doAgentSensor(ts));
246 } 245 }
@@ -339,7 +338,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
339 float dy; 338 float dy;
340 float dz; 339 float dz;
341 340
342 Quaternion q = SensePoint.GetWorldRotation(); 341// Quaternion q = SensePoint.RotationOffset;
342 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
343 if (SensePoint.ParentGroup.IsAttachment) 343 if (SensePoint.ParentGroup.IsAttachment)
344 { 344 {
345 // In attachments, rotate the sensor cone with the 345 // In attachments, rotate the sensor cone with the
@@ -353,7 +353,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
353 // Position of a sensor in a child prim attached to an avatar 353 // Position of a sensor in a child prim attached to an avatar
354 // will be still wrong. 354 // will be still wrong.
355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
356 q = avatar.Rotation * q; 356 fromRegionPos = avatar.AbsolutePosition;
357 q = avatar.Rotation;
357 } 358 }
358 359
359 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 360 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -480,7 +481,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
480 // Position of a sensor in a child prim attached to an avatar 481 // Position of a sensor in a child prim attached to an avatar
481 // will be still wrong. 482 // will be still wrong.
482 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 483 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
483 q = avatar.Rotation * q; 484 if (avatar == null)
485 return sensedEntities;
486 fromRegionPos = avatar.AbsolutePosition;
487 q = avatar.Rotation;
484 } 488 }
485 489
486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 490 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -496,7 +500,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
496// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 500// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
497// presence.Name, presence.PresenceType, ts.name, ts.type); 501// presence.Name, presence.PresenceType, ts.name, ts.type);
498 502
499 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 503 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
500 { 504 {
501 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 505 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
502 if (npcData == null || !npcData.SenseAsAgent) 506 if (npcData == null || !npcData.SenseAsAgent)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index 0b14565..68aacd2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -123,25 +123,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
123 if (Timers.Count == 0) 123 if (Timers.Count == 0)
124 return; 124 return;
125 125
126 Dictionary<string, TimerInfo>.ValueCollection tvals;
126 lock (TimerListLock) 127 lock (TimerListLock)
127 { 128 {
128 // Go through all timers 129 // Go through all timers
129 Dictionary<string, TimerInfo>.ValueCollection tvals = Timers.Values; 130 tvals = Timers.Values;
130 foreach (TimerInfo ts in tvals) 131 }
132
133 foreach (TimerInfo ts in tvals)
134 {
135 // Time has passed?
136 if (ts.next < DateTime.Now.Ticks)
131 { 137 {
132 // Time has passed? 138 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
133 if (ts.next < DateTime.Now.Ticks) 139 // Add it to queue
134 { 140 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
135 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 141 new EventParams("timer", new Object[0],
136 // Add it to queue 142 new DetectParams[0]));
137 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 143 // set next interval
138 new EventParams("timer", new Object[0], 144
139 new DetectParams[0])); 145 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
140 // set next interval 146 ts.next = DateTime.Now.Ticks + ts.interval;
141
142 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
143 ts.next = DateTime.Now.Ticks + ts.interval;
144 }
145 } 147 }
146 } 148 }
147 } 149 }