aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api/Implementation
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3195
-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, 2690 insertions, 802 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 47a9cdc..94fd940 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -305,6 +305,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
305 return null; 305 return null;
306 } 306 }
307 307
308 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
309 {
310 // Remove a specific script
311
312 // Remove dataserver events
313 m_Dataserver[engine].RemoveEvents(localID, itemID);
314
315 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
316 if (comms != null)
317 comms.DeleteListener(itemID);
318
319 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
320 xmlrpc.DeleteChannels(itemID);
321 xmlrpc.CancelSRDRequests(itemID);
322
323 // Remove Sensors
324 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
325
326 }
327
308 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 328 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
309 { 329 {
310 List<Object> data = new List<Object>(); 330 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..b5fa6de
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,116 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal TaskInventoryItem m_item;
63 internal bool m_CMFunctionsEnabled = false;
64
65 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
66 {
67 m_ScriptEngine = ScriptEngine;
68 m_host = host;
69 m_item = item;
70
71 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
72 m_CMFunctionsEnabled = true;
73 }
74
75 public override Object InitializeLifetimeService()
76 {
77 ILease lease = (ILease)base.InitializeLifetimeService();
78
79 if (lease.CurrentState == LeaseState.Initial)
80 {
81 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
82 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
83 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
84 }
85 return lease;
86 }
87
88 public Scene World
89 {
90 get { return m_ScriptEngine.World; }
91 }
92
93 public string cmDetectedCountry(int number)
94 {
95 m_host.AddScriptLPS(1);
96 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
97 if (detectedParams == null)
98 return String.Empty;
99 return detectedParams.Country;
100 }
101
102 public string cmGetAgentCountry(LSL_Key key)
103 {
104 if (!World.Permissions.IsGod(m_host.OwnerID))
105 return String.Empty;
106
107 UUID uuid;
108
109 if (!UUID.TryParse(key, out uuid))
110 return String.Empty;
111
112 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
113 return account.UserCountry;
114 }
115 }
116}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 4108588..07b7123 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{
@@ -104,16 +108,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
104 protected int m_notecardLineReadCharsMax = 255; 108 protected int m_notecardLineReadCharsMax = 255;
105 protected int m_scriptConsoleChannel = 0; 109 protected int m_scriptConsoleChannel = 0;
106 protected bool m_scriptConsoleChannelEnabled = false; 110 protected bool m_scriptConsoleChannelEnabled = false;
111 protected bool m_debuggerSafe = false;
107 protected IUrlModule m_UrlModule = null; 112 protected IUrlModule m_UrlModule = null;
108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 113 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
109 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 114 new Dictionary<UUID, UserInfoCacheEntry>();
115 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
110 protected ISoundModule m_SoundModule = null; 116 protected ISoundModule m_SoundModule = null;
111 117
118// protected Timer m_ShoutSayTimer;
119 protected int m_SayShoutCount = 0;
120 DateTime m_lastSayShoutCheck;
121
122 private Dictionary<string, string> MovementAnimationsForLSL =
123 new Dictionary<string, string> {
124 {"FLY", "Flying"},
125 {"FLYSLOW", "FlyingSlow"},
126 {"HOVER_UP", "Hovering Up"},
127 {"HOVER_DOWN", "Hovering Down"},
128 {"HOVER", "Hovering"},
129 {"LAND", "Landing"},
130 {"FALLDOWN", "Falling Down"},
131 {"PREJUMP", "PreJumping"},
132 {"JUMP", "Jumping"},
133 {"STANDUP", "Standing Up"},
134 {"SOFT_LAND", "Soft Landing"},
135 {"STAND", "Standing"},
136 {"CROUCHWALK", "CrouchWalking"},
137 {"RUN", "Running"},
138 {"WALK", "Walking"},
139 {"CROUCH", "Crouching"},
140 {"TURNLEFT", "Turning Left"},
141 {"TURNRIGHT", "Turning Right"}
142 };
143
112 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
113 { 145 {
146/*
147 m_ShoutSayTimer = new Timer(1000);
148 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
149 m_ShoutSayTimer.AutoReset = true;
150 m_ShoutSayTimer.Start();
151*/
152 m_lastSayShoutCheck = DateTime.UtcNow;
153
114 m_ScriptEngine = ScriptEngine; 154 m_ScriptEngine = ScriptEngine;
115 m_host = host; 155 m_host = host;
116 m_item = item; 156 m_item = item;
157 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
117 158
118 LoadLimits(); // read script limits from config. 159 LoadLimits(); // read script limits from config.
119 160
@@ -174,6 +215,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
174 get { return m_ScriptEngine.World; } 215 get { return m_ScriptEngine.World; }
175 } 216 }
176 217
218 [DebuggerNonUserCode]
177 public void state(string newState) 219 public void state(string newState)
178 { 220 {
179 m_ScriptEngine.SetState(m_item.ItemID, newState); 221 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -183,6 +225,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
183 /// Reset the named script. The script must be present 225 /// Reset the named script. The script must be present
184 /// in the same prim. 226 /// in the same prim.
185 /// </summary> 227 /// </summary>
228 [DebuggerNonUserCode]
186 public void llResetScript() 229 public void llResetScript()
187 { 230 {
188 m_host.AddScriptLPS(1); 231 m_host.AddScriptLPS(1);
@@ -245,6 +288,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
245 } 288 }
246 } 289 }
247 290
291 public List<ScenePresence> GetLinkAvatars(int linkType)
292 {
293 List<ScenePresence> ret = new List<ScenePresence>();
294 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
295 return ret;
296
297 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
298
299 switch (linkType)
300 {
301 case ScriptBaseClass.LINK_SET:
302 return avs;
303
304 case ScriptBaseClass.LINK_ROOT:
305 return ret;
306
307 case ScriptBaseClass.LINK_ALL_OTHERS:
308 return avs;
309
310 case ScriptBaseClass.LINK_ALL_CHILDREN:
311 return avs;
312
313 case ScriptBaseClass.LINK_THIS:
314 return ret;
315
316 default:
317 if (linkType < 0)
318 return ret;
319
320 int partCount = m_host.ParentGroup.GetPartCount();
321
322 if (linkType <= partCount)
323 {
324 return ret;
325 }
326 else
327 {
328 linkType = linkType - partCount;
329 if (linkType > avs.Count)
330 {
331 return ret;
332 }
333 else
334 {
335 ret.Add(avs[linkType-1]);
336 return ret;
337 }
338 }
339 }
340 }
341
248 public List<SceneObjectPart> GetLinkParts(int linkType) 342 public List<SceneObjectPart> GetLinkParts(int linkType)
249 { 343 {
250 return GetLinkParts(m_host, linkType); 344 return GetLinkParts(m_host, linkType);
@@ -253,6 +347,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
253 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 347 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
254 { 348 {
255 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 349 List<SceneObjectPart> ret = new List<SceneObjectPart>();
350 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
351 return ret;
256 ret.Add(part); 352 ret.Add(part);
257 353
258 switch (linkType) 354 switch (linkType)
@@ -479,31 +575,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
479 575
480 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 576 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
481 577
482 /// <summary> 578 // Utility function for llRot2Euler
483 /// Convert an LSL rotation to a Euler vector. 579
484 /// </summary> 580 // normalize an angle between -PI and PI (-180 to +180 degrees)
485 /// <remarks> 581 protected double NormalizeAngle(double angle)
486 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
487 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
488 /// </remarks>
489 /// <param name="r"></param>
490 /// <returns></returns>
491 public LSL_Vector llRot2Euler(LSL_Rotation r)
492 { 582 {
493 m_host.AddScriptLPS(1); 583 if (angle > -Math.PI && angle < Math.PI)
584 return angle;
494 585
495 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 586 int numPis = (int)(Math.PI / angle);
496 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 587 double remainder = angle - Math.PI * numPis;
497 if (m == 0.0) return new LSL_Vector(); 588 if (numPis % 2 == 1)
498 double x = Math.Atan2(-v.y, v.z); 589 return Math.PI - angle;
499 double sin = v.x / m; 590 return remainder;
500 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 591 }
501 double y = Math.Asin(sin);
502 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
503 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)));
504 double z = Math.Atan2(v.y, v.x);
505 592
506 return new LSL_Vector(x, y, z); 593 public LSL_Vector llRot2Euler(LSL_Rotation q1)
594 {
595 m_host.AddScriptLPS(1);
596 LSL_Vector eul = new LSL_Vector();
597
598 double sqw = q1.s*q1.s;
599 double sqx = q1.x*q1.x;
600 double sqy = q1.z*q1.z;
601 double sqz = q1.y*q1.y;
602 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
603 double test = q1.x*q1.z + q1.y*q1.s;
604 if (test > 0.4999*unit) { // singularity at north pole
605 eul.z = 2 * Math.Atan2(q1.x,q1.s);
606 eul.y = Math.PI/2;
607 eul.x = 0;
608 return eul;
609 }
610 if (test < -0.4999*unit) { // singularity at south pole
611 eul.z = -2 * Math.Atan2(q1.x,q1.s);
612 eul.y = -Math.PI/2;
613 eul.x = 0;
614 return eul;
615 }
616 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
617 eul.y = Math.Asin(2*test/unit);
618 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
619 return eul;
507 } 620 }
508 621
509 /* From wiki: 622 /* From wiki:
@@ -556,18 +669,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
556 m_host.AddScriptLPS(1); 669 m_host.AddScriptLPS(1);
557 670
558 double x,y,z,s; 671 double x,y,z,s;
559 672 v.x *= 0.5;
560 double c1 = Math.Cos(v.x * 0.5); 673 v.y *= 0.5;
561 double c2 = Math.Cos(v.y * 0.5); 674 v.z *= 0.5;
562 double c3 = Math.Cos(v.z * 0.5); 675 double c1 = Math.Cos(v.x);
563 double s1 = Math.Sin(v.x * 0.5); 676 double c2 = Math.Cos(v.y);
564 double s2 = Math.Sin(v.y * 0.5); 677 double c1c2 = c1 * c2;
565 double s3 = Math.Sin(v.z * 0.5); 678 double s1 = Math.Sin(v.x);
566 679 double s2 = Math.Sin(v.y);
567 x = s1 * c2 * c3 + c1 * s2 * s3; 680 double s1s2 = s1 * s2;
568 y = c1 * s2 * c3 - s1 * c2 * s3; 681 double c1s2 = c1 * s2;
569 z = s1 * s2 * c3 + c1 * c2 * s3; 682 double s1c2 = s1 * c2;
570 s = c1 * c2 * c3 - s1 * s2 * s3; 683 double c3 = Math.Cos(v.z);
684 double s3 = Math.Sin(v.z);
685
686 x = s1c2 * c3 + c1s2 * s3;
687 y = c1s2 * c3 - s1c2 * s3;
688 z = s1s2 * c3 + c1c2 * s3;
689 s = c1c2 * c3 - s1s2 * s3;
571 690
572 return new LSL_Rotation(x, y, z, s); 691 return new LSL_Rotation(x, y, z, s);
573 } 692 }
@@ -705,77 +824,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
705 { 824 {
706 //A and B should both be normalized 825 //A and B should both be normalized
707 m_host.AddScriptLPS(1); 826 m_host.AddScriptLPS(1);
708 LSL_Rotation rotBetween; 827 /* This method is more accurate than the SL one, and thus causes problems
709 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 828 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
710 // continue calculation. 829
711 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 830 double dotProduct = LSL_Vector.Dot(a, b);
831 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
832 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
833 double angle = Math.Acos(dotProduct / magProduct);
834 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
835 double s = Math.Sin(angle / 2);
836
837 double x = axis.x * s;
838 double y = axis.y * s;
839 double z = axis.z * s;
840 double w = Math.Cos(angle / 2);
841
842 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
843 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
844
845 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
846 */
847
848 // This method mimics the 180 errors found in SL
849 // See www.euclideanspace.com... angleBetween
850 LSL_Vector vec_a = a;
851 LSL_Vector vec_b = b;
852
853 // Eliminate zero length
854 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
855 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
856 if (vec_a_mag < 0.00001 ||
857 vec_b_mag < 0.00001)
712 { 858 {
713 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 859 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
714 } 860 }
715 else 861
862 // Normalize
863 vec_a = llVecNorm(vec_a);
864 vec_b = llVecNorm(vec_b);
865
866 // Calculate axis and rotation angle
867 LSL_Vector axis = vec_a % vec_b;
868 LSL_Float cos_theta = vec_a * vec_b;
869
870 // Check if parallel
871 if (cos_theta > 0.99999)
716 { 872 {
717 a = LSL_Vector.Norm(a); 873 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
718 b = LSL_Vector.Norm(b); 874 }
719 double dotProduct = LSL_Vector.Dot(a, b); 875
720 // There are two degenerate cases possible. These are for vectors 180 or 876 // Check if anti-parallel
721 // 0 degrees apart. These have to be detected and handled individually. 877 else if (cos_theta < -0.99999)
722 // 878 {
723 // Check for vectors 180 degrees apart. 879 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
724 // A dot product of -1 would mean the angle between vectors is 180 degrees. 880 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
725 if (dotProduct < -0.9999999f) 881 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
726 { 882 }
727 // First assume X axis is orthogonal to the vectors. 883 else // other rotation
728 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 884 {
729 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 885 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
730 // Check for near zero vector. A very small non-zero number here will create 886 axis = llVecNorm(axis);
731 // a rotation in an undesired direction. 887 double x, y, z, s, t;
732 if (LSL_Vector.Mag(orthoVector) > 0.0001) 888 s = Math.Cos(theta);
733 { 889 t = Math.Sin(theta);
734 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 890 x = axis.x * t;
735 } 891 y = axis.y * t;
736 // If the magnitude of the vector was near zero, then assume the X axis is not 892 z = axis.z * t;
737 // orthogonal and use the Z axis instead. 893 return new LSL_Rotation(x,y,z,s);
738 else
739 {
740 // Set 180 z rotation.
741 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
742 }
743 }
744 // Check for parallel vectors.
745 // A dot product of 1 would mean the angle between vectors is 0 degrees.
746 else if (dotProduct > 0.9999999f)
747 {
748 // Set zero rotation.
749 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
750 }
751 else
752 {
753 // All special checks have been performed so get the axis of rotation.
754 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
755 // Quarternion s value is the length of the unit vector + dot product.
756 double qs = 1.0 + dotProduct;
757 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
758 // Normalize the rotation.
759 double mag = LSL_Rotation.Mag(rotBetween);
760 // We shouldn't have to worry about a divide by zero here. The qs value will be
761 // non-zero because we already know if we're here, then the dotProduct is not -1 so
762 // qs will not be zero. Also, we've already handled the input vectors being zero so the
763 // crossProduct vector should also not be zero.
764 rotBetween.x = rotBetween.x / mag;
765 rotBetween.y = rotBetween.y / mag;
766 rotBetween.z = rotBetween.z / mag;
767 rotBetween.s = rotBetween.s / mag;
768 // Check for undefined values and set zero rotation if any found. This code might not actually be required
769 // any longer since zero vectors are checked for at the top.
770 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
771 {
772 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
773 }
774 }
775 } 894 }
776 return rotBetween;
777 } 895 }
778 896
779 public void llWhisper(int channelID, string text) 897 public void llWhisper(int channelID, string text)
780 { 898 {
781 m_host.AddScriptLPS(1); 899 m_host.AddScriptLPS(1);
@@ -791,10 +909,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
791 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 909 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
792 } 910 }
793 911
912 private void CheckSayShoutTime()
913 {
914 DateTime now = DateTime.UtcNow;
915 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
916 {
917 m_lastSayShoutCheck = now;
918 m_SayShoutCount = 0;
919 }
920 else
921 m_SayShoutCount++;
922 }
923
794 public void llSay(int channelID, string text) 924 public void llSay(int channelID, string text)
795 { 925 {
796 m_host.AddScriptLPS(1); 926 m_host.AddScriptLPS(1);
797 927
928 if (channelID == 0)
929// m_SayShoutCount++;
930 CheckSayShoutTime();
931
932 if (m_SayShoutCount >= 11)
933 ScriptSleep(2000);
934
798 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 935 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
799 { 936 {
800 Console.WriteLine(text); 937 Console.WriteLine(text);
@@ -817,6 +954,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
817 { 954 {
818 m_host.AddScriptLPS(1); 955 m_host.AddScriptLPS(1);
819 956
957 if (channelID == 0)
958// m_SayShoutCount++;
959 CheckSayShoutTime();
960
961 if (m_SayShoutCount >= 11)
962 ScriptSleep(2000);
963
820 if (text.Length > 1023) 964 if (text.Length > 1023)
821 text = text.Substring(0, 1023); 965 text = text.Substring(0, 1023);
822 966
@@ -848,22 +992,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
848 992
849 public void llRegionSayTo(string target, int channel, string msg) 993 public void llRegionSayTo(string target, int channel, string msg)
850 { 994 {
995 string error = String.Empty;
996
851 if (msg.Length > 1023) 997 if (msg.Length > 1023)
852 msg = msg.Substring(0, 1023); 998 msg = msg.Substring(0, 1023);
853 999
854 m_host.AddScriptLPS(1); 1000 m_host.AddScriptLPS(1);
855 1001
856 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
857 {
858 return;
859 }
860
861 UUID TargetID; 1002 UUID TargetID;
862 UUID.TryParse(target, out TargetID); 1003 UUID.TryParse(target, out TargetID);
863 1004
864 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1005 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
865 if (wComm != null) 1006 if (wComm != null)
866 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1007 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1008 LSLError(error);
867 } 1009 }
868 1010
869 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1011 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1119,10 +1261,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1119 return detectedParams.TouchUV; 1261 return detectedParams.TouchUV;
1120 } 1262 }
1121 1263
1264 [DebuggerNonUserCode]
1122 public virtual void llDie() 1265 public virtual void llDie()
1123 { 1266 {
1124 m_host.AddScriptLPS(1); 1267 m_host.AddScriptLPS(1);
1125 throw new SelfDeleteException(); 1268 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1126 } 1269 }
1127 1270
1128 public LSL_Float llGround(LSL_Vector offset) 1271 public LSL_Float llGround(LSL_Vector offset)
@@ -1193,6 +1336,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1193 1336
1194 public void llSetStatus(int status, int value) 1337 public void llSetStatus(int status, int value)
1195 { 1338 {
1339 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1340 return;
1196 m_host.AddScriptLPS(1); 1341 m_host.AddScriptLPS(1);
1197 1342
1198 int statusrotationaxis = 0; 1343 int statusrotationaxis = 0;
@@ -1216,6 +1361,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1216 if (!allow) 1361 if (!allow)
1217 return; 1362 return;
1218 1363
1364 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1365 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1366 return;
1367
1219 m_host.ScriptSetPhysicsStatus(true); 1368 m_host.ScriptSetPhysicsStatus(true);
1220 } 1369 }
1221 else 1370 else
@@ -1415,6 +1564,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1415 { 1564 {
1416 m_host.AddScriptLPS(1); 1565 m_host.AddScriptLPS(1);
1417 1566
1567 SetColor(m_host, color, face);
1568 }
1569
1570 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1571 {
1572 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1573 return;
1574
1575 Primitive.TextureEntry tex = part.Shape.Textures;
1576 Color4 texcolor;
1577 if (face >= 0 && face < GetNumberOfSides(part))
1578 {
1579 texcolor = tex.CreateFace((uint)face).RGBA;
1580 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1581 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1582 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1583 tex.FaceTextures[face].RGBA = texcolor;
1584 part.UpdateTextureEntry(tex.GetBytes());
1585 return;
1586 }
1587 else if (face == ScriptBaseClass.ALL_SIDES)
1588 {
1589 for (uint i = 0; i < GetNumberOfSides(part); i++)
1590 {
1591 if (tex.FaceTextures[i] != null)
1592 {
1593 texcolor = tex.FaceTextures[i].RGBA;
1594 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1595 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1596 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1597 tex.FaceTextures[i].RGBA = texcolor;
1598 }
1599 texcolor = tex.DefaultTexture.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.DefaultTexture.RGBA = texcolor;
1604 }
1605 part.UpdateTextureEntry(tex.GetBytes());
1606 return;
1607 }
1608
1418 if (face == ScriptBaseClass.ALL_SIDES) 1609 if (face == ScriptBaseClass.ALL_SIDES)
1419 face = SceneObjectPart.ALL_SIDES; 1610 face = SceneObjectPart.ALL_SIDES;
1420 1611
@@ -1423,6 +1614,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1423 1614
1424 public void SetTexGen(SceneObjectPart part, int face,int style) 1615 public void SetTexGen(SceneObjectPart part, int face,int style)
1425 { 1616 {
1617 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1618 return;
1619
1426 Primitive.TextureEntry tex = part.Shape.Textures; 1620 Primitive.TextureEntry tex = part.Shape.Textures;
1427 MappingType textype; 1621 MappingType textype;
1428 textype = MappingType.Default; 1622 textype = MappingType.Default;
@@ -1453,6 +1647,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1453 1647
1454 public void SetGlow(SceneObjectPart part, int face, float glow) 1648 public void SetGlow(SceneObjectPart part, int face, float glow)
1455 { 1649 {
1650 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1651 return;
1652
1456 Primitive.TextureEntry tex = part.Shape.Textures; 1653 Primitive.TextureEntry tex = part.Shape.Textures;
1457 if (face >= 0 && face < GetNumberOfSides(part)) 1654 if (face >= 0 && face < GetNumberOfSides(part))
1458 { 1655 {
@@ -1478,6 +1675,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1478 1675
1479 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1676 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1480 { 1677 {
1678 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1679 return;
1481 1680
1482 Shininess sval = new Shininess(); 1681 Shininess sval = new Shininess();
1483 1682
@@ -1528,6 +1727,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1528 1727
1529 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1728 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1530 { 1729 {
1730 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1731 return;
1732
1531 Primitive.TextureEntry tex = part.Shape.Textures; 1733 Primitive.TextureEntry tex = part.Shape.Textures;
1532 if (face >= 0 && face < GetNumberOfSides(part)) 1734 if (face >= 0 && face < GetNumberOfSides(part))
1533 { 1735 {
@@ -1588,13 +1790,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1588 m_host.AddScriptLPS(1); 1790 m_host.AddScriptLPS(1);
1589 1791
1590 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1792 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1591 1793 if (parts.Count > 0)
1592 foreach (SceneObjectPart part in parts) 1794 {
1593 SetAlpha(part, alpha, face); 1795 try
1796 {
1797 foreach (SceneObjectPart part in parts)
1798 SetAlpha(part, alpha, face);
1799 }
1800 finally
1801 {
1802 }
1803 }
1594 } 1804 }
1595 1805
1596 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1806 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1597 { 1807 {
1808 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1809 return;
1810
1598 Primitive.TextureEntry tex = part.Shape.Textures; 1811 Primitive.TextureEntry tex = part.Shape.Textures;
1599 Color4 texcolor; 1812 Color4 texcolor;
1600 if (face >= 0 && face < GetNumberOfSides(part)) 1813 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1647,7 +1860,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1647 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1860 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1648 float wind, float tension, LSL_Vector Force) 1861 float wind, float tension, LSL_Vector Force)
1649 { 1862 {
1650 if (part == null) 1863 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1651 return; 1864 return;
1652 1865
1653 if (flexi) 1866 if (flexi)
@@ -1681,7 +1894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1681 /// <param name="falloff"></param> 1894 /// <param name="falloff"></param>
1682 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1895 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1683 { 1896 {
1684 if (part == null) 1897 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1685 return; 1898 return;
1686 1899
1687 if (light) 1900 if (light)
@@ -1714,11 +1927,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1714 Primitive.TextureEntry tex = part.Shape.Textures; 1927 Primitive.TextureEntry tex = part.Shape.Textures;
1715 Color4 texcolor; 1928 Color4 texcolor;
1716 LSL_Vector rgb = new LSL_Vector(); 1929 LSL_Vector rgb = new LSL_Vector();
1930 int nsides = GetNumberOfSides(part);
1931
1717 if (face == ScriptBaseClass.ALL_SIDES) 1932 if (face == ScriptBaseClass.ALL_SIDES)
1718 { 1933 {
1719 int i; 1934 int i;
1720 1935 for (i = 0; i < nsides; i++)
1721 for (i = 0 ; i < GetNumberOfSides(part); i++)
1722 { 1936 {
1723 texcolor = tex.GetFace((uint)i).RGBA; 1937 texcolor = tex.GetFace((uint)i).RGBA;
1724 rgb.x += texcolor.R; 1938 rgb.x += texcolor.R;
@@ -1726,14 +1940,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1726 rgb.z += texcolor.B; 1940 rgb.z += texcolor.B;
1727 } 1941 }
1728 1942
1729 rgb.x /= (float)GetNumberOfSides(part); 1943 float invnsides = 1.0f / (float)nsides;
1730 rgb.y /= (float)GetNumberOfSides(part); 1944
1731 rgb.z /= (float)GetNumberOfSides(part); 1945 rgb.x *= invnsides;
1946 rgb.y *= invnsides;
1947 rgb.z *= invnsides;
1732 1948
1733 return rgb; 1949 return rgb;
1734 } 1950 }
1735 1951 if (face >= 0 && face < nsides)
1736 if (face >= 0 && face < GetNumberOfSides(part))
1737 { 1952 {
1738 texcolor = tex.GetFace((uint)face).RGBA; 1953 texcolor = tex.GetFace((uint)face).RGBA;
1739 rgb.x = texcolor.R; 1954 rgb.x = texcolor.R;
@@ -1760,15 +1975,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1760 m_host.AddScriptLPS(1); 1975 m_host.AddScriptLPS(1);
1761 1976
1762 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1977 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1763 1978 if (parts.Count > 0)
1764 foreach (SceneObjectPart part in parts) 1979 {
1765 SetTexture(part, texture, face); 1980 try
1766 1981 {
1982 foreach (SceneObjectPart part in parts)
1983 SetTexture(part, texture, face);
1984 }
1985 finally
1986 {
1987 }
1988 }
1767 ScriptSleep(200); 1989 ScriptSleep(200);
1768 } 1990 }
1769 1991
1770 protected void SetTexture(SceneObjectPart part, string texture, int face) 1992 protected void SetTexture(SceneObjectPart part, string texture, int face)
1771 { 1993 {
1994 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1995 return;
1996
1772 UUID textureID = new UUID(); 1997 UUID textureID = new UUID();
1773 1998
1774 textureID = InventoryKey(texture, (int)AssetType.Texture); 1999 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1813,6 +2038,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1813 2038
1814 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2039 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1815 { 2040 {
2041 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2042 return;
2043
1816 Primitive.TextureEntry tex = part.Shape.Textures; 2044 Primitive.TextureEntry tex = part.Shape.Textures;
1817 if (face >= 0 && face < GetNumberOfSides(part)) 2045 if (face >= 0 && face < GetNumberOfSides(part))
1818 { 2046 {
@@ -1849,6 +2077,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1849 2077
1850 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2078 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1851 { 2079 {
2080 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2081 return;
2082
1852 Primitive.TextureEntry tex = part.Shape.Textures; 2083 Primitive.TextureEntry tex = part.Shape.Textures;
1853 if (face >= 0 && face < GetNumberOfSides(part)) 2084 if (face >= 0 && face < GetNumberOfSides(part))
1854 { 2085 {
@@ -1885,6 +2116,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1885 2116
1886 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2117 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1887 { 2118 {
2119 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2120 return;
2121
1888 Primitive.TextureEntry tex = part.Shape.Textures; 2122 Primitive.TextureEntry tex = part.Shape.Textures;
1889 if (face >= 0 && face < GetNumberOfSides(part)) 2123 if (face >= 0 && face < GetNumberOfSides(part))
1890 { 2124 {
@@ -2055,24 +2289,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2055 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2289 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2056 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2290 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2057 { 2291 {
2058 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2292 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2293 return;
2294
2059 LSL_Vector currentPos = GetPartLocalPos(part); 2295 LSL_Vector currentPos = GetPartLocalPos(part);
2296 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2060 2297
2061 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2062 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2063 2298
2064 if (part.ParentGroup.RootPart == part) 2299 if (part.ParentGroup.RootPart == part)
2065 { 2300 {
2066 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2067 targetPos.z = ground;
2068 SceneObjectGroup parent = part.ParentGroup; 2301 SceneObjectGroup parent = part.ParentGroup;
2069 parent.UpdateGroupPosition(!adjust ? targetPos : 2302 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2070 SetPosAdjust(currentPos, targetPos)); 2303 return;
2304 Util.FireAndForget(delegate(object x) {
2305 parent.UpdateGroupPosition((Vector3)toPos);
2306 });
2071 } 2307 }
2072 else 2308 else
2073 { 2309 {
2074 part.OffsetPosition = !adjust ? targetPos : 2310 part.OffsetPosition = (Vector3)toPos;
2075 SetPosAdjust(currentPos, targetPos);
2076 SceneObjectGroup parent = part.ParentGroup; 2311 SceneObjectGroup parent = part.ParentGroup;
2077 parent.HasGroupChanged = true; 2312 parent.HasGroupChanged = true;
2078 parent.ScheduleGroupForTerseUpdate(); 2313 parent.ScheduleGroupForTerseUpdate();
@@ -2104,13 +2339,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2104 else 2339 else
2105 { 2340 {
2106 if (part.ParentGroup.IsAttachment) 2341 if (part.ParentGroup.IsAttachment)
2107 {
2108 pos = part.AttachedPos; 2342 pos = part.AttachedPos;
2109 }
2110 else 2343 else
2111 {
2112 pos = part.AbsolutePosition; 2344 pos = part.AbsolutePosition;
2113 }
2114 } 2345 }
2115 2346
2116// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2347// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2150,25 +2381,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2150 2381
2151 protected void SetRot(SceneObjectPart part, Quaternion rot) 2382 protected void SetRot(SceneObjectPart part, Quaternion rot)
2152 { 2383 {
2153 part.UpdateRotation(rot); 2384 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2154 // Update rotation does not move the object in the physics scene if it's a linkset. 2385 return;
2155 2386
2156//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2387 bool isroot = (part == part.ParentGroup.RootPart);
2157// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2388 bool isphys;
2158 2389
2159 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2160 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2161 // It's perfectly okay when the object is not an active physical body though.
2162 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2163 // but only if the object is not physial and active. This is important for rotating doors.
2164 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2165 // scene
2166 PhysicsActor pa = part.PhysActor; 2390 PhysicsActor pa = part.PhysActor;
2167 2391
2168 if (pa != null && !pa.IsPhysical) 2392 // keep using physactor ideia of isphysical
2393 // it should be SOP ideia of that
2394 // not much of a issue with ubitODE
2395 if (pa != null && pa.IsPhysical)
2396 isphys = true;
2397 else
2398 isphys = false;
2399
2400 // SL doesn't let scripts rotate root of physical linksets
2401 if (isroot && isphys)
2402 return;
2403
2404 part.UpdateRotation(rot);
2405
2406 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2407 // so do a nasty update of parts positions if is a root part rotation
2408 if (isroot && pa != null) // with if above implies non physical root part
2169 { 2409 {
2170 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2410 part.ParentGroup.ResetChildPrimPhysicsPositions();
2171 } 2411 }
2412 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2413 {
2414 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2415 if (sittingavas.Count > 0)
2416 {
2417 foreach (ScenePresence av in sittingavas)
2418 {
2419 if (isroot || part.LocalId == av.ParentID)
2420 av.SendTerseUpdateToAllClients();
2421 }
2422 }
2423 }
2172 } 2424 }
2173 2425
2174 /// <summary> 2426 /// <summary>
@@ -2216,8 +2468,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2216 2468
2217 public LSL_Rotation llGetLocalRot() 2469 public LSL_Rotation llGetLocalRot()
2218 { 2470 {
2471 return GetPartLocalRot(m_host);
2472 }
2473
2474 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2475 {
2219 m_host.AddScriptLPS(1); 2476 m_host.AddScriptLPS(1);
2220 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2477 Quaternion rot = part.RotationOffset;
2478 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2221 } 2479 }
2222 2480
2223 public void llSetForce(LSL_Vector force, int local) 2481 public void llSetForce(LSL_Vector force, int local)
@@ -2297,16 +2555,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2297 m_host.ApplyImpulse(v, local != 0); 2555 m_host.ApplyImpulse(v, local != 0);
2298 } 2556 }
2299 2557
2558
2300 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2559 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2301 { 2560 {
2302 m_host.AddScriptLPS(1); 2561 m_host.AddScriptLPS(1);
2303 m_host.ApplyAngularImpulse(force, local != 0); 2562 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2304 } 2563 }
2305 2564
2306 public void llSetTorque(LSL_Vector torque, int local) 2565 public void llSetTorque(LSL_Vector torque, int local)
2307 { 2566 {
2308 m_host.AddScriptLPS(1); 2567 m_host.AddScriptLPS(1);
2309 m_host.SetAngularImpulse(torque, local != 0); 2568 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2310 } 2569 }
2311 2570
2312 public LSL_Vector llGetTorque() 2571 public LSL_Vector llGetTorque()
@@ -2323,20 +2582,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2323 llSetTorque(torque, local); 2582 llSetTorque(torque, local);
2324 } 2583 }
2325 2584
2585 public void llSetVelocity(LSL_Vector vel, int local)
2586 {
2587 m_host.AddScriptLPS(1);
2588 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2589 }
2590
2326 public LSL_Vector llGetVel() 2591 public LSL_Vector llGetVel()
2327 { 2592 {
2328 m_host.AddScriptLPS(1); 2593 m_host.AddScriptLPS(1);
2329 2594
2330 Vector3 vel; 2595 Vector3 vel = Vector3.Zero;
2331 2596
2332 if (m_host.ParentGroup.IsAttachment) 2597 if (m_host.ParentGroup.IsAttachment)
2333 { 2598 {
2334 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2599 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2335 vel = avatar.Velocity; 2600 if (avatar != null)
2601 vel = avatar.Velocity;
2336 } 2602 }
2337 else 2603 else
2338 { 2604 {
2339 vel = m_host.Velocity; 2605 vel = m_host.ParentGroup.RootPart.Velocity;
2340 } 2606 }
2341 2607
2342 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2608 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2348,10 +2614,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2348 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2614 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2349 } 2615 }
2350 2616
2617 public void llSetAngularVelocity(LSL_Vector avel, int local)
2618 {
2619 m_host.AddScriptLPS(1);
2620 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2621 }
2622
2351 public LSL_Vector llGetOmega() 2623 public LSL_Vector llGetOmega()
2352 { 2624 {
2353 m_host.AddScriptLPS(1); 2625 m_host.AddScriptLPS(1);
2354 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2626 Vector3 avel = m_host.AngularVelocity;
2627 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2355 } 2628 }
2356 2629
2357 public LSL_Float llGetTimeOfDay() 2630 public LSL_Float llGetTimeOfDay()
@@ -2824,16 +3097,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2824 new_group.RootPart.UUID.ToString()) }, 3097 new_group.RootPart.UUID.ToString()) },
2825 new DetectParams[0])); 3098 new DetectParams[0]));
2826 3099
2827 float groupmass = new_group.GetMass(); 3100 // do recoil
3101 SceneObjectGroup hostgrp = m_host.ParentGroup;
3102 if (hostgrp == null)
3103 return;
3104
3105 if (hostgrp.IsAttachment) // don't recoil avatars
3106 return;
2828 3107
2829 PhysicsActor pa = new_group.RootPart.PhysActor; 3108 PhysicsActor pa = new_group.RootPart.PhysActor;
2830 3109
2831 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3110 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2832 { 3111 {
2833 //Recoil. 3112 float groupmass = new_group.GetMass();
2834 llApplyImpulse(vel * groupmass, 0); 3113 vel *= -groupmass;
3114 llApplyImpulse(vel, 0);
2835 } 3115 }
2836 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3116 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3117 return;
3118
2837 }); 3119 });
2838 3120
2839 //ScriptSleep((int)((groupmass * velmag) / 10)); 3121 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2848,35 +3130,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2848 public void llLookAt(LSL_Vector target, double strength, double damping) 3130 public void llLookAt(LSL_Vector target, double strength, double damping)
2849 { 3131 {
2850 m_host.AddScriptLPS(1); 3132 m_host.AddScriptLPS(1);
2851 // Determine where we are looking from
2852 LSL_Vector from = llGetPos();
2853 3133
2854 // Work out the normalised vector from the source to the target 3134 // Get the normalized vector to the target
2855 LSL_Vector delta = llVecNorm(target - from); 3135 LSL_Vector d1 = llVecNorm(target - llGetPos());
2856 LSL_Vector angle = new LSL_Vector(0,0,0);
2857 3136
2858 // Calculate the yaw 3137 // Get the bearing (yaw)
2859 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3138 LSL_Vector a1 = new LSL_Vector(0,0,0);
2860 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3139 a1.z = llAtan2(d1.y, d1.x);
2861 3140
2862 // Calculate pitch 3141 // Get the elevation (pitch)
2863 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3142 LSL_Vector a2 = new LSL_Vector(0,0,0);
3143 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2864 3144
2865 // we need to convert from a vector describing 3145 LSL_Rotation r1 = llEuler2Rot(a1);
2866 // the angles of rotation in radians into rotation value 3146 LSL_Rotation r2 = llEuler2Rot(a2);
2867 LSL_Rotation rot = llEuler2Rot(angle); 3147 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2868
2869 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2870 // set the rotation of the object, copy that behavior
2871 PhysicsActor pa = m_host.PhysActor;
2872 3148
2873 if (strength == 0 || pa == null || !pa.IsPhysical) 3149 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2874 { 3150 {
2875 llSetRot(rot); 3151 // Do nothing if either value is 0 (this has been checked in SL)
3152 if (strength <= 0.0 || damping <= 0.0)
3153 return;
3154
3155 llSetRot(r3 * r2 * r1);
2876 } 3156 }
2877 else 3157 else
2878 { 3158 {
2879 m_host.StartLookAt(rot, (float)strength, (float)damping); 3159 if (strength == 0)
3160 {
3161 llSetRot(r3 * r2 * r1);
3162 return;
3163 }
3164
3165 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2880 } 3166 }
2881 } 3167 }
2882 3168
@@ -2922,17 +3208,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2922 } 3208 }
2923 else 3209 else
2924 { 3210 {
2925 if (m_host.IsRoot) 3211 // new SL always returns object mass
2926 { 3212// if (m_host.IsRoot)
3213// {
2927 return m_host.ParentGroup.GetMass(); 3214 return m_host.ParentGroup.GetMass();
2928 } 3215// }
2929 else 3216// else
2930 { 3217// {
2931 return m_host.GetMass(); 3218// return m_host.GetMass();
2932 } 3219// }
2933 } 3220 }
2934 } 3221 }
2935 3222
3223
3224 public LSL_Float llGetMassMKS()
3225 {
3226 return 100f * llGetMass();
3227 }
3228
2936 public void llCollisionFilter(string name, string id, int accept) 3229 public void llCollisionFilter(string name, string id, int accept)
2937 { 3230 {
2938 m_host.AddScriptLPS(1); 3231 m_host.AddScriptLPS(1);
@@ -2980,8 +3273,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2980 { 3273 {
2981 // Unregister controls from Presence 3274 // Unregister controls from Presence
2982 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3275 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2983 // Remove Take Control permission.
2984 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
2985 } 3276 }
2986 } 3277 }
2987 } 3278 }
@@ -3007,7 +3298,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3007 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3298 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3008 3299
3009 if (attachmentsModule != null) 3300 if (attachmentsModule != null)
3010 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3301 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3011 else 3302 else
3012 return false; 3303 return false;
3013 } 3304 }
@@ -3037,9 +3328,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3037 { 3328 {
3038 m_host.AddScriptLPS(1); 3329 m_host.AddScriptLPS(1);
3039 3330
3040// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3041// return;
3042
3043 if (m_item.PermsGranter != m_host.OwnerID) 3331 if (m_item.PermsGranter != m_host.OwnerID)
3044 return; 3332 return;
3045 3333
@@ -3082,6 +3370,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3082 3370
3083 public void llInstantMessage(string user, string message) 3371 public void llInstantMessage(string user, string message)
3084 { 3372 {
3373 UUID result;
3374 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3375 {
3376 ShoutError("An invalid key was passed to llInstantMessage");
3377 ScriptSleep(2000);
3378 return;
3379 }
3380
3381
3085 m_host.AddScriptLPS(1); 3382 m_host.AddScriptLPS(1);
3086 3383
3087 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3384 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3096,14 +3393,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3096 UUID friendTransactionID = UUID.Random(); 3393 UUID friendTransactionID = UUID.Random();
3097 3394
3098 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3395 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3099 3396
3100 GridInstantMessage msg = new GridInstantMessage(); 3397 GridInstantMessage msg = new GridInstantMessage();
3101 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3398 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3102 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3399 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3103 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3400 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3104// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3401// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3105// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3402// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3106 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3403// DateTime dt = DateTime.UtcNow;
3404//
3405// // Ticks from UtcNow, but make it look like local. Evil, huh?
3406// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3407//
3408// try
3409// {
3410// // Convert that to the PST timezone
3411// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3412// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3413// }
3414// catch
3415// {
3416// // No logging here, as it could be VERY spammy
3417// }
3418//
3419// // And make it look local again to fool the unix time util
3420// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3421
3422 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3423
3107 //if (client != null) 3424 //if (client != null)
3108 //{ 3425 //{
3109 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3426 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3117,12 +3434,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3117 msg.message = message.Substring(0, 1024); 3434 msg.message = message.Substring(0, 1024);
3118 else 3435 else
3119 msg.message = message; 3436 msg.message = message;
3120 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3437 msg.dialog = (byte)19; // MessageFromObject
3121 msg.fromGroup = false;// fromGroup; 3438 msg.fromGroup = false;// fromGroup;
3122 msg.offline = (byte)0; //offline; 3439 msg.offline = (byte)0; //offline;
3123 msg.ParentEstateID = 0; //ParentEstateID; 3440 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3124 msg.Position = new Vector3(m_host.AbsolutePosition); 3441 msg.Position = new Vector3(m_host.AbsolutePosition);
3125 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3442 msg.RegionID = World.RegionInfo.RegionID.Guid;
3126 msg.binaryBucket 3443 msg.binaryBucket
3127 = Util.StringToBytes256( 3444 = Util.StringToBytes256(
3128 "{0}/{1}/{2}/{3}", 3445 "{0}/{1}/{2}/{3}",
@@ -3150,7 +3467,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3150 } 3467 }
3151 3468
3152 emailModule.SendEmail(m_host.UUID, address, subject, message); 3469 emailModule.SendEmail(m_host.UUID, address, subject, message);
3153 llSleep(EMAIL_PAUSE_TIME); 3470 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3154 } 3471 }
3155 3472
3156 public void llGetNextEmail(string address, string subject) 3473 public void llGetNextEmail(string address, string subject)
@@ -3396,7 +3713,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3396 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3713 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3397 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3714 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3398 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3715 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3716 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3399 ScriptBaseClass.PERMISSION_ATTACH; 3717 ScriptBaseClass.PERMISSION_ATTACH;
3718
3400 } 3719 }
3401 else 3720 else
3402 { 3721 {
@@ -3427,15 +3746,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3427 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3746 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3428 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3747 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3429 } 3748 }
3749 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3750 {
3751 implicitPerms = perm;
3752 }
3430 } 3753 }
3431 3754
3432 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3755 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3433 { 3756 {
3434 lock (m_host.TaskInventory) 3757 m_host.TaskInventory.LockItemsForWrite(true);
3435 { 3758 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3436 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3759 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3437 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3760 m_host.TaskInventory.LockItemsForWrite(false);
3438 }
3439 3761
3440 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3762 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3441 "run_time_permissions", new Object[] { 3763 "run_time_permissions", new Object[] {
@@ -3478,11 +3800,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3478 3800
3479 if (!m_waitingForScriptAnswer) 3801 if (!m_waitingForScriptAnswer)
3480 { 3802 {
3481 lock (m_host.TaskInventory) 3803 m_host.TaskInventory.LockItemsForWrite(true);
3482 { 3804 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3483 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3805 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3484 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3806 m_host.TaskInventory.LockItemsForWrite(false);
3485 }
3486 3807
3487 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3808 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3488 m_waitingForScriptAnswer=true; 3809 m_waitingForScriptAnswer=true;
@@ -3511,14 +3832,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3511 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3832 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3512 llReleaseControls(); 3833 llReleaseControls();
3513 3834
3514 lock (m_host.TaskInventory) 3835 m_host.TaskInventory.LockItemsForWrite(true);
3515 { 3836 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3516 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3837 m_host.TaskInventory.LockItemsForWrite(false);
3517 } 3838
3518 3839 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3519 m_ScriptEngine.PostScriptEvent( 3840 "run_time_permissions", new Object[] {
3520 m_item.ItemID, 3841 new LSL_Integer(answer) },
3521 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3842 new DetectParams[0]));
3522 } 3843 }
3523 3844
3524 public LSL_String llGetPermissionsKey() 3845 public LSL_String llGetPermissionsKey()
@@ -3557,14 +3878,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3557 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3878 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3558 { 3879 {
3559 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3880 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3560 3881 if (parts.Count > 0)
3561 foreach (SceneObjectPart part in parts) 3882 {
3562 part.SetFaceColorAlpha(face, color, null); 3883 try
3884 {
3885 foreach (SceneObjectPart part in parts)
3886 part.SetFaceColorAlpha(face, color, null);
3887 }
3888 finally
3889 {
3890 }
3891 }
3563 } 3892 }
3564 3893
3565 public void llCreateLink(string target, int parent) 3894 public void llCreateLink(string target, int parent)
3566 { 3895 {
3567 m_host.AddScriptLPS(1); 3896 m_host.AddScriptLPS(1);
3897
3568 UUID targetID; 3898 UUID targetID;
3569 3899
3570 if (!UUID.TryParse(target, out targetID)) 3900 if (!UUID.TryParse(target, out targetID))
@@ -3670,10 +4000,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3670 // Restructuring Multiple Prims. 4000 // Restructuring Multiple Prims.
3671 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4001 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3672 parts.Remove(parentPrim.RootPart); 4002 parts.Remove(parentPrim.RootPart);
3673 foreach (SceneObjectPart part in parts) 4003 if (parts.Count > 0)
3674 { 4004 {
3675 parentPrim.DelinkFromGroup(part.LocalId, true); 4005 try
4006 {
4007 foreach (SceneObjectPart part in parts)
4008 {
4009 parentPrim.DelinkFromGroup(part.LocalId, true);
4010 }
4011 }
4012 finally
4013 {
4014 }
3676 } 4015 }
4016
3677 parentPrim.HasGroupChanged = true; 4017 parentPrim.HasGroupChanged = true;
3678 parentPrim.ScheduleGroupForFullUpdate(); 4018 parentPrim.ScheduleGroupForFullUpdate();
3679 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4019 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3682,12 +4022,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3682 { 4022 {
3683 SceneObjectPart newRoot = parts[0]; 4023 SceneObjectPart newRoot = parts[0];
3684 parts.Remove(newRoot); 4024 parts.Remove(newRoot);
3685 foreach (SceneObjectPart part in parts) 4025
4026 try
3686 { 4027 {
3687 // Required for linking 4028 foreach (SceneObjectPart part in parts)
3688 part.ClearUpdateSchedule(); 4029 {
3689 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4030 part.ClearUpdateSchedule();
4031 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4032 }
3690 } 4033 }
4034 finally
4035 {
4036 }
4037
4038
3691 newRoot.ParentGroup.HasGroupChanged = true; 4039 newRoot.ParentGroup.HasGroupChanged = true;
3692 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4040 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3693 } 4041 }
@@ -3707,6 +4055,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3707 public void llBreakAllLinks() 4055 public void llBreakAllLinks()
3708 { 4056 {
3709 m_host.AddScriptLPS(1); 4057 m_host.AddScriptLPS(1);
4058
4059 TaskInventoryItem item = m_item;
4060
4061 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4062 && !m_automaticLinkPermission)
4063 {
4064 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4065 return;
4066 }
4067
3710 SceneObjectGroup parentPrim = m_host.ParentGroup; 4068 SceneObjectGroup parentPrim = m_host.ParentGroup;
3711 if (parentPrim.AttachmentPoint != 0) 4069 if (parentPrim.AttachmentPoint != 0)
3712 return; // Fail silently if attached 4070 return; // Fail silently if attached
@@ -3726,25 +4084,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3726 public LSL_String llGetLinkKey(int linknum) 4084 public LSL_String llGetLinkKey(int linknum)
3727 { 4085 {
3728 m_host.AddScriptLPS(1); 4086 m_host.AddScriptLPS(1);
3729 List<UUID> keytable = new List<UUID>();
3730 // parse for sitting avatare-uuids
3731 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3732 {
3733 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3734 keytable.Add(presence.UUID);
3735 });
3736
3737 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3738 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3739 {
3740 return keytable[totalprims - linknum].ToString();
3741 }
3742
3743 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3744 {
3745 return m_host.UUID.ToString();
3746 }
3747
3748 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4087 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3749 if (part != null) 4088 if (part != null)
3750 { 4089 {
@@ -3752,6 +4091,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3752 } 4091 }
3753 else 4092 else
3754 { 4093 {
4094 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4095 {
4096 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4097
4098 if (linknum < 0)
4099 return UUID.Zero.ToString();
4100
4101 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4102 if (avatars.Count > linknum)
4103 {
4104 return avatars[linknum].UUID.ToString();
4105 }
4106 }
3755 return UUID.Zero.ToString(); 4107 return UUID.Zero.ToString();
3756 } 4108 }
3757 } 4109 }
@@ -3861,17 +4213,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3861 m_host.AddScriptLPS(1); 4213 m_host.AddScriptLPS(1);
3862 int count = 0; 4214 int count = 0;
3863 4215
3864 lock (m_host.TaskInventory) 4216 m_host.TaskInventory.LockItemsForRead(true);
4217 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3865 { 4218 {
3866 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4219 if (inv.Value.Type == type || type == -1)
3867 { 4220 {
3868 if (inv.Value.Type == type || type == -1) 4221 count = count + 1;
3869 {
3870 count = count + 1;
3871 }
3872 } 4222 }
3873 } 4223 }
3874 4224
4225 m_host.TaskInventory.LockItemsForRead(false);
3875 return count; 4226 return count;
3876 } 4227 }
3877 4228
@@ -3880,16 +4231,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3880 m_host.AddScriptLPS(1); 4231 m_host.AddScriptLPS(1);
3881 ArrayList keys = new ArrayList(); 4232 ArrayList keys = new ArrayList();
3882 4233
3883 lock (m_host.TaskInventory) 4234 m_host.TaskInventory.LockItemsForRead(true);
4235 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3884 { 4236 {
3885 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4237 if (inv.Value.Type == type || type == -1)
3886 { 4238 {
3887 if (inv.Value.Type == type || type == -1) 4239 keys.Add(inv.Value.Name);
3888 {
3889 keys.Add(inv.Value.Name);
3890 }
3891 } 4240 }
3892 } 4241 }
4242 m_host.TaskInventory.LockItemsForRead(false);
3893 4243
3894 if (keys.Count == 0) 4244 if (keys.Count == 0)
3895 { 4245 {
@@ -3927,7 +4277,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3927 if (item == null) 4277 if (item == null)
3928 { 4278 {
3929 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4279 llSay(0, String.Format("Could not find object '{0}'", inventory));
3930 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4280 return;
4281// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3931 } 4282 }
3932 4283
3933 UUID objId = item.ItemID; 4284 UUID objId = item.ItemID;
@@ -3955,33 +4306,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3955 return; 4306 return;
3956 } 4307 }
3957 } 4308 }
4309
3958 // destination is an avatar 4310 // destination is an avatar
3959 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4311 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3960 4312
3961 if (agentItem == null) 4313 if (agentItem == null)
3962 return; 4314 return;
3963 4315
3964 if (m_TransferModule != null) 4316 byte[] bucket = new byte[1];
3965 { 4317 bucket[0] = (byte)item.Type;
3966 byte[] bucket = new byte[1]; 4318 //byte[] objBytes = agentItem.ID.GetBytes();
3967 bucket[0] = (byte)item.Type; 4319 //Array.Copy(objBytes, 0, bucket, 1, 16);
3968 4320
3969 GridInstantMessage msg = new GridInstantMessage(World, 4321 GridInstantMessage msg = new GridInstantMessage(World,
3970 m_host.OwnerID, m_host.Name, destId, 4322 m_host.OwnerID, m_host.Name, destId,
3971 (byte)InstantMessageDialog.TaskInventoryOffered, 4323 (byte)InstantMessageDialog.TaskInventoryOffered,
3972 false, item.Name+". "+m_host.Name+" is located at "+ 4324 false, item.Name+". "+m_host.Name+" is located at "+
3973 World.RegionInfo.RegionName+" "+ 4325 World.RegionInfo.RegionName+" "+
3974 m_host.AbsolutePosition.ToString(), 4326 m_host.AbsolutePosition.ToString(),
3975 agentItem.ID, true, m_host.AbsolutePosition, 4327 agentItem.ID, true, m_host.AbsolutePosition,
3976 bucket, true); 4328 bucket, true);
3977 4329
3978 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4330 ScenePresence sp;
3979 }
3980 4331
4332 if (World.TryGetScenePresence(destId, out sp))
4333 {
4334 sp.ControllingClient.SendInstantMessage(msg);
4335 }
4336 else
4337 {
4338 if (m_TransferModule != null)
4339 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4340 }
4341
4342 //This delay should only occur when giving inventory to avatars.
3981 ScriptSleep(3000); 4343 ScriptSleep(3000);
3982 } 4344 }
3983 } 4345 }
3984 4346
4347 [DebuggerNonUserCode]
3985 public void llRemoveInventory(string name) 4348 public void llRemoveInventory(string name)
3986 { 4349 {
3987 m_host.AddScriptLPS(1); 4350 m_host.AddScriptLPS(1);
@@ -4036,109 +4399,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4036 { 4399 {
4037 m_host.AddScriptLPS(1); 4400 m_host.AddScriptLPS(1);
4038 4401
4039 UUID uuid = (UUID)id; 4402 UUID uuid;
4040 PresenceInfo pinfo = null; 4403 if (UUID.TryParse(id, out uuid))
4041 UserAccount account;
4042
4043 UserInfoCacheEntry ce;
4044 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4045 { 4404 {
4046 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4405 PresenceInfo pinfo = null;
4047 if (account == null) 4406 UserAccount account;
4407
4408 UserInfoCacheEntry ce;
4409 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4048 { 4410 {
4049 m_userInfoCache[uuid] = null; // Cache negative 4411 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4050 return UUID.Zero.ToString(); 4412 if (account == null)
4051 } 4413 {
4414 m_userInfoCache[uuid] = null; // Cache negative
4415 return UUID.Zero.ToString();
4416 }
4052 4417
4053 4418
4054 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4419 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4055 if (pinfos != null && pinfos.Length > 0) 4420 if (pinfos != null && pinfos.Length > 0)
4056 {
4057 foreach (PresenceInfo p in pinfos)
4058 { 4421 {
4059 if (p.RegionID != UUID.Zero) 4422 foreach (PresenceInfo p in pinfos)
4060 { 4423 {
4061 pinfo = p; 4424 if (p.RegionID != UUID.Zero)
4425 {
4426 pinfo = p;
4427 }
4062 } 4428 }
4063 } 4429 }
4064 }
4065 4430
4066 ce = new UserInfoCacheEntry(); 4431 ce = new UserInfoCacheEntry();
4067 ce.time = Util.EnvironmentTickCount(); 4432 ce.time = Util.EnvironmentTickCount();
4068 ce.account = account; 4433 ce.account = account;
4069 ce.pinfo = pinfo; 4434 ce.pinfo = pinfo;
4070 } 4435 m_userInfoCache[uuid] = ce;
4071 else 4436 }
4072 { 4437 else
4073 if (ce == null) 4438 {
4074 return UUID.Zero.ToString(); 4439 if (ce == null)
4440 return UUID.Zero.ToString();
4075 4441
4076 account = ce.account; 4442 account = ce.account;
4077 pinfo = ce.pinfo; 4443 pinfo = ce.pinfo;
4078 } 4444 }
4079 4445
4080 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4446 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4081 {
4082 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4083 if (pinfos != null && pinfos.Length > 0)
4084 { 4447 {
4085 foreach (PresenceInfo p in pinfos) 4448 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4449 if (pinfos != null && pinfos.Length > 0)
4086 { 4450 {
4087 if (p.RegionID != UUID.Zero) 4451 foreach (PresenceInfo p in pinfos)
4088 { 4452 {
4089 pinfo = p; 4453 if (p.RegionID != UUID.Zero)
4454 {
4455 pinfo = p;
4456 }
4090 } 4457 }
4091 } 4458 }
4092 } 4459 else
4093 else 4460 pinfo = null;
4094 pinfo = null;
4095 4461
4096 ce.time = Util.EnvironmentTickCount(); 4462 ce.time = Util.EnvironmentTickCount();
4097 ce.pinfo = pinfo; 4463 ce.pinfo = pinfo;
4098 } 4464 }
4099 4465
4100 string reply = String.Empty; 4466 string reply = String.Empty;
4101 4467
4102 switch (data) 4468 switch (data)
4103 { 4469 {
4104 case 1: // DATA_ONLINE (0|1) 4470 case 1: // DATA_ONLINE (0|1)
4105 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4471 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4106 reply = "1"; 4472 reply = "1";
4107 else 4473 else
4108 reply = "0"; 4474 reply = "0";
4109 break; 4475 break;
4110 case 2: // DATA_NAME (First Last) 4476 case 2: // DATA_NAME (First Last)
4111 reply = account.FirstName + " " + account.LastName; 4477 reply = account.FirstName + " " + account.LastName;
4112 break; 4478 break;
4113 case 3: // DATA_BORN (YYYY-MM-DD) 4479 case 3: // DATA_BORN (YYYY-MM-DD)
4114 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4480 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4115 born = born.AddSeconds(account.Created); 4481 born = born.AddSeconds(account.Created);
4116 reply = born.ToString("yyyy-MM-dd"); 4482 reply = born.ToString("yyyy-MM-dd");
4117 break; 4483 break;
4118 case 4: // DATA_RATING (0,0,0,0,0,0) 4484 case 4: // DATA_RATING (0,0,0,0,0,0)
4119 reply = "0,0,0,0,0,0"; 4485 reply = "0,0,0,0,0,0";
4120 break; 4486 break;
4121 case 7: // DATA_USERLEVEL (integer) 4487 case 8: // DATA_PAYINFO (0|1|2|3)
4122 reply = account.UserLevel.ToString(); 4488 reply = "0";
4123 break; 4489 break;
4124 case 8: // DATA_PAYINFO (0|1|2|3) 4490 default:
4125 reply = "0"; 4491 return UUID.Zero.ToString(); // Raise no event
4126 break; 4492 }
4127 default:
4128 return UUID.Zero.ToString(); // Raise no event
4129 }
4130 4493
4131 UUID rq = UUID.Random(); 4494 UUID rq = UUID.Random();
4132 4495
4133 UUID tid = AsyncCommands. 4496 UUID tid = AsyncCommands.
4134 DataserverPlugin.RegisterRequest(m_host.LocalId, 4497 DataserverPlugin.RegisterRequest(m_host.LocalId,
4135 m_item.ItemID, rq.ToString()); 4498 m_item.ItemID, rq.ToString());
4136 4499
4137 AsyncCommands. 4500 AsyncCommands.
4138 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4501 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4139 4502
4140 ScriptSleep(100); 4503 ScriptSleep(100);
4141 return tid.ToString(); 4504 return tid.ToString();
4505 }
4506 else
4507 {
4508 ShoutError("Invalid UUID passed to llRequestAgentData.");
4509 }
4510 return "";
4142 } 4511 }
4143 4512
4144 public LSL_String llRequestInventoryData(string name) 4513 public LSL_String llRequestInventoryData(string name)
@@ -4195,13 +4564,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4195 if (UUID.TryParse(agent, out agentId)) 4564 if (UUID.TryParse(agent, out agentId))
4196 { 4565 {
4197 ScenePresence presence = World.GetScenePresence(agentId); 4566 ScenePresence presence = World.GetScenePresence(agentId);
4198 if (presence != null) 4567 if (presence != null && presence.PresenceType != PresenceType.Npc)
4199 { 4568 {
4569 // agent must not be a god
4570 if (presence.UserLevel >= 200) return;
4571
4200 // agent must be over the owners land 4572 // agent must be over the owners land
4201 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4573 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4202 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4574 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4203 { 4575 {
4204 World.TeleportClientHome(agentId, presence.ControllingClient); 4576 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4577 {
4578 // They can't be teleported home for some reason
4579 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4580 if (regionInfo != null)
4581 {
4582 World.RequestTeleportLocation(
4583 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4584 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4585 }
4586 }
4205 } 4587 }
4206 } 4588 }
4207 } 4589 }
@@ -4308,7 +4690,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4308 UUID av = new UUID(); 4690 UUID av = new UUID();
4309 if (!UUID.TryParse(agent,out av)) 4691 if (!UUID.TryParse(agent,out av))
4310 { 4692 {
4311 LSLError("First parameter to llDialog needs to be a key"); 4693 //LSLError("First parameter to llDialog needs to be a key");
4312 return; 4694 return;
4313 } 4695 }
4314 4696
@@ -4340,10 +4722,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4340 public void llCollisionSound(string impact_sound, double impact_volume) 4722 public void llCollisionSound(string impact_sound, double impact_volume)
4341 { 4723 {
4342 m_host.AddScriptLPS(1); 4724 m_host.AddScriptLPS(1);
4343 4725
4726 if(impact_sound == "")
4727 {
4728 m_host.CollisionSoundVolume = (float)impact_volume;
4729 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4730 m_host.CollisionSoundType = 0;
4731 return;
4732 }
4344 // TODO: Parameter check logic required. 4733 // TODO: Parameter check logic required.
4345 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4734 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound);
4346 m_host.CollisionSoundVolume = (float)impact_volume; 4735 m_host.CollisionSoundVolume = (float)impact_volume;
4736 m_host.CollisionSoundType = 1;
4347 } 4737 }
4348 4738
4349 public LSL_String llGetAnimation(string id) 4739 public LSL_String llGetAnimation(string id)
@@ -4357,14 +4747,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4357 4747
4358 if (m_host.RegionHandle == presence.RegionHandle) 4748 if (m_host.RegionHandle == presence.RegionHandle)
4359 { 4749 {
4360 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4361
4362 if (presence != null) 4750 if (presence != null)
4363 { 4751 {
4364 AnimationSet currentAnims = presence.Animator.Animations; 4752 if (presence.SitGround)
4365 string currentAnimationState = String.Empty; 4753 return "Sitting on Ground";
4366 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4754 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4367 return currentAnimationState; 4755 return "Sitting";
4756
4757 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4758 string lslMovementAnimation;
4759
4760 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4761 return lslMovementAnimation;
4368 } 4762 }
4369 } 4763 }
4370 4764
@@ -4511,7 +4905,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4511 { 4905 {
4512 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4906 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4513 float distance_term = distance * distance * distance; // Script Energy 4907 float distance_term = distance * distance * distance; // Script Energy
4514 float pusher_mass = m_host.GetMass(); 4908 // use total object mass and not part
4909 float pusher_mass = m_host.ParentGroup.GetMass();
4515 4910
4516 float PUSH_ATTENUATION_DISTANCE = 17f; 4911 float PUSH_ATTENUATION_DISTANCE = 17f;
4517 float PUSH_ATTENUATION_SCALE = 5f; 4912 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4761,6 +5156,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4761 { 5156 {
4762 return item.AssetID.ToString(); 5157 return item.AssetID.ToString();
4763 } 5158 }
5159 m_host.TaskInventory.LockItemsForRead(false);
4764 5160
4765 return UUID.Zero.ToString(); 5161 return UUID.Zero.ToString();
4766 } 5162 }
@@ -4894,7 +5290,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4894 public LSL_Vector llGetCenterOfMass() 5290 public LSL_Vector llGetCenterOfMass()
4895 { 5291 {
4896 m_host.AddScriptLPS(1); 5292 m_host.AddScriptLPS(1);
4897 Vector3 center = m_host.GetGeometricCenter(); 5293 Vector3 center = m_host.GetCenterOfMass();
4898 return new LSL_Vector(center.X,center.Y,center.Z); 5294 return new LSL_Vector(center.X,center.Y,center.Z);
4899 } 5295 }
4900 5296
@@ -4913,14 +5309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4913 { 5309 {
4914 m_host.AddScriptLPS(1); 5310 m_host.AddScriptLPS(1);
4915 5311
4916 if (src == null) 5312 return src.Length;
4917 {
4918 return 0;
4919 }
4920 else
4921 {
4922 return src.Length;
4923 }
4924 } 5313 }
4925 5314
4926 public LSL_Integer llList2Integer(LSL_List src, int index) 5315 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4991,7 +5380,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4991 else if (src.Data[index] is LSL_Float) 5380 else if (src.Data[index] is LSL_Float)
4992 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5381 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4993 else if (src.Data[index] is LSL_String) 5382 else if (src.Data[index] is LSL_String)
4994 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5383 {
5384 string str = ((LSL_String) src.Data[index]).m_string;
5385 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5386 if (m != Match.Empty)
5387 {
5388 str = m.Value;
5389 double d = 0.0;
5390 if (!Double.TryParse(str, out d))
5391 return 0.0;
5392
5393 return d;
5394 }
5395 return 0.0;
5396 }
4995 return Convert.ToDouble(src.Data[index]); 5397 return Convert.ToDouble(src.Data[index]);
4996 } 5398 }
4997 catch (FormatException) 5399 catch (FormatException)
@@ -5033,7 +5435,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5033 // for completion and should LSL_Key ever be implemented 5435 // for completion and should LSL_Key ever be implemented
5034 // as it's own struct 5436 // as it's own struct
5035 else if (!(src.Data[index] is LSL_String || 5437 else if (!(src.Data[index] is LSL_String ||
5036 src.Data[index] is LSL_Key)) 5438 src.Data[index] is LSL_Key ||
5439 src.Data[index] is String))
5037 { 5440 {
5038 return ""; 5441 return "";
5039 } 5442 }
@@ -5291,7 +5694,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5291 } 5694 }
5292 } 5695 }
5293 } 5696 }
5294 else { 5697 else
5698 {
5295 object[] array = new object[src.Length]; 5699 object[] array = new object[src.Length];
5296 Array.Copy(src.Data, 0, array, 0, src.Length); 5700 Array.Copy(src.Data, 0, array, 0, src.Length);
5297 result = new LSL_List(array); 5701 result = new LSL_List(array);
@@ -5398,7 +5802,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5398 public LSL_Integer llGetRegionAgentCount() 5802 public LSL_Integer llGetRegionAgentCount()
5399 { 5803 {
5400 m_host.AddScriptLPS(1); 5804 m_host.AddScriptLPS(1);
5401 return new LSL_Integer(World.GetRootAgentCount()); 5805
5806 int count = 0;
5807 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5808 count++;
5809 });
5810
5811 return new LSL_Integer(count);
5402 } 5812 }
5403 5813
5404 public LSL_Vector llGetRegionCorner() 5814 public LSL_Vector llGetRegionCorner()
@@ -5639,6 +6049,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5639 flags |= ScriptBaseClass.AGENT_AWAY; 6049 flags |= ScriptBaseClass.AGENT_AWAY;
5640 } 6050 }
5641 6051
6052 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6053 UUID[] anims = agent.Animator.GetAnimationArray();
6054 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6055 {
6056 flags |= ScriptBaseClass.AGENT_BUSY;
6057 }
6058
5642 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6059 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5643 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6060 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5644 { 6061 {
@@ -5686,6 +6103,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5686 flags |= ScriptBaseClass.AGENT_SITTING; 6103 flags |= ScriptBaseClass.AGENT_SITTING;
5687 } 6104 }
5688 6105
6106 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6107 {
6108 flags |= ScriptBaseClass.AGENT_MALE;
6109 }
6110
5689 return flags; 6111 return flags;
5690 } 6112 }
5691 6113
@@ -5833,9 +6255,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5833 6255
5834 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6256 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5835 6257
5836 foreach (SceneObjectPart part in parts) 6258 try
6259 {
6260 foreach (SceneObjectPart part in parts)
6261 {
6262 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6263 }
6264 }
6265 finally
5837 { 6266 {
5838 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5839 } 6267 }
5840 } 6268 }
5841 6269
@@ -5889,13 +6317,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5889 6317
5890 if (m_host.OwnerID == land.LandData.OwnerID) 6318 if (m_host.OwnerID == land.LandData.OwnerID)
5891 { 6319 {
5892 World.TeleportClientHome(agentID, presence.ControllingClient); 6320 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6321 presence.TeleportWithMomentum(pos, null);
6322 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5893 } 6323 }
5894 } 6324 }
5895 } 6325 }
5896 ScriptSleep(5000); 6326 ScriptSleep(5000);
5897 } 6327 }
5898 6328
6329 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6330 {
6331 return ParseString2List(str, separators, in_spacers, false);
6332 }
6333
5899 public LSL_Integer llOverMyLand(string id) 6334 public LSL_Integer llOverMyLand(string id)
5900 { 6335 {
5901 m_host.AddScriptLPS(1); 6336 m_host.AddScriptLPS(1);
@@ -5954,20 +6389,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5954 return agentSize; 6389 return agentSize;
5955 } 6390 }
5956 6391
5957 public LSL_Integer llSameGroup(string agent) 6392 public LSL_Integer llSameGroup(string id)
5958 { 6393 {
5959 m_host.AddScriptLPS(1); 6394 m_host.AddScriptLPS(1);
5960 UUID agentId = new UUID(); 6395 UUID uuid = new UUID();
5961 if (!UUID.TryParse(agent, out agentId)) 6396 if (!UUID.TryParse(id, out uuid))
5962 return new LSL_Integer(0);
5963 ScenePresence presence = World.GetScenePresence(agentId);
5964 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5965 return new LSL_Integer(0); 6397 return new LSL_Integer(0);
5966 IClientAPI client = presence.ControllingClient; 6398
5967 if (m_host.GroupID == client.ActiveGroupId) 6399 // Check if it's a group key
6400 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5968 return new LSL_Integer(1); 6401 return new LSL_Integer(1);
5969 else 6402
6403 // We got passed a UUID.Zero
6404 if (uuid == UUID.Zero)
5970 return new LSL_Integer(0); 6405 return new LSL_Integer(0);
6406
6407 // Handle the case where id names an avatar
6408 ScenePresence presence = World.GetScenePresence(uuid);
6409 if (presence != null)
6410 {
6411 if (presence.IsChildAgent)
6412 return new LSL_Integer(0);
6413
6414 IClientAPI client = presence.ControllingClient;
6415 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6416 return new LSL_Integer(1);
6417
6418 return new LSL_Integer(0);
6419 }
6420
6421 // Handle object case
6422 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6423 if (part != null)
6424 {
6425 // This will handle both deed and non-deed and also the no
6426 // group case
6427 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6428 return new LSL_Integer(1);
6429
6430 return new LSL_Integer(0);
6431 }
6432
6433 return new LSL_Integer(0);
5971 } 6434 }
5972 6435
5973 public void llUnSit(string id) 6436 public void llUnSit(string id)
@@ -6092,7 +6555,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6092 return m_host.ParentGroup.AttachmentPoint; 6555 return m_host.ParentGroup.AttachmentPoint;
6093 } 6556 }
6094 6557
6095 public LSL_Integer llGetFreeMemory() 6558 public virtual LSL_Integer llGetFreeMemory()
6096 { 6559 {
6097 m_host.AddScriptLPS(1); 6560 m_host.AddScriptLPS(1);
6098 // Make scripts designed for LSO happy 6561 // Make scripts designed for LSO happy
@@ -6209,7 +6672,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6209 SetParticleSystem(m_host, rules); 6672 SetParticleSystem(m_host, rules);
6210 } 6673 }
6211 6674
6212 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6675 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6676 {
6213 6677
6214 6678
6215 if (rules.Length == 0) 6679 if (rules.Length == 0)
@@ -6524,6 +6988,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6524 6988
6525 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6989 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6526 { 6990 {
6991 // LSL quaternions can normalize to 0, normal Quaternions can't.
6992 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6993 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6994
6527 part.SitTargetPosition = offset; 6995 part.SitTargetPosition = offset;
6528 part.SitTargetOrientation = rot; 6996 part.SitTargetOrientation = rot;
6529 part.ParentGroup.HasGroupChanged = true; 6997 part.ParentGroup.HasGroupChanged = true;
@@ -6709,13 +7177,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6709 UUID av = new UUID(); 7177 UUID av = new UUID();
6710 if (!UUID.TryParse(avatar,out av)) 7178 if (!UUID.TryParse(avatar,out av))
6711 { 7179 {
6712 LSLError("First parameter to llDialog needs to be a key"); 7180 //LSLError("First parameter to llDialog needs to be a key");
6713 return; 7181 return;
6714 } 7182 }
6715 if (buttons.Length < 1) 7183 if (buttons.Length < 1)
6716 { 7184 {
6717 LSLError("No less than 1 button can be shown"); 7185 buttons.Add("OK");
6718 return;
6719 } 7186 }
6720 if (buttons.Length > 12) 7187 if (buttons.Length > 12)
6721 { 7188 {
@@ -6732,7 +7199,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6732 } 7199 }
6733 if (buttons.Data[i].ToString().Length > 24) 7200 if (buttons.Data[i].ToString().Length > 24)
6734 { 7201 {
6735 LSLError("button label cannot be longer than 24 characters"); 7202 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6736 return; 7203 return;
6737 } 7204 }
6738 buts[i] = buttons.Data[i].ToString(); 7205 buts[i] = buttons.Data[i].ToString();
@@ -6799,9 +7266,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6799 return; 7266 return;
6800 } 7267 }
6801 7268
6802 // the rest of the permission checks are done in RezScript, so check the pin there as well 7269 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6803 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7270 if (dest != null)
7271 {
7272 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7273 {
7274 // the rest of the permission checks are done in RezScript, so check the pin there as well
7275 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6804 7276
7277 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7278 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7279 }
7280 }
6805 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7281 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6806 ScriptSleep(3000); 7282 ScriptSleep(3000);
6807 } 7283 }
@@ -6871,19 +7347,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6871 public LSL_String llMD5String(string src, int nonce) 7347 public LSL_String llMD5String(string src, int nonce)
6872 { 7348 {
6873 m_host.AddScriptLPS(1); 7349 m_host.AddScriptLPS(1);
6874 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7350 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6875 } 7351 }
6876 7352
6877 public LSL_String llSHA1String(string src) 7353 public LSL_String llSHA1String(string src)
6878 { 7354 {
6879 m_host.AddScriptLPS(1); 7355 m_host.AddScriptLPS(1);
6880 return Util.SHA1Hash(src).ToLower(); 7356 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6881 } 7357 }
6882 7358
6883 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7359 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6884 { 7360 {
6885 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7361 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6886 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7362 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7363 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7364 return shapeBlock;
6887 7365
6888 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7366 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6889 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7367 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6988,6 +7466,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6988 // Prim type box, cylinder and prism. 7466 // Prim type box, cylinder and prism.
6989 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) 7467 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)
6990 { 7468 {
7469 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7470 return;
7471
6991 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7472 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6992 ObjectShapePacket.ObjectDataBlock shapeBlock; 7473 ObjectShapePacket.ObjectDataBlock shapeBlock;
6993 7474
@@ -7041,6 +7522,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7041 // Prim type sphere. 7522 // Prim type sphere.
7042 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7523 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7043 { 7524 {
7525 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7526 return;
7527
7044 ObjectShapePacket.ObjectDataBlock shapeBlock; 7528 ObjectShapePacket.ObjectDataBlock shapeBlock;
7045 7529
7046 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7530 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7082,6 +7566,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7082 // Prim type torus, tube and ring. 7566 // Prim type torus, tube and ring.
7083 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) 7567 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)
7084 { 7568 {
7569 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7570 return;
7571
7085 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7572 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7086 ObjectShapePacket.ObjectDataBlock shapeBlock; 7573 ObjectShapePacket.ObjectDataBlock shapeBlock;
7087 7574
@@ -7217,6 +7704,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7217 // Prim type sculpt. 7704 // Prim type sculpt.
7218 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7705 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7219 { 7706 {
7707 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7708 return;
7709
7220 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7710 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7221 UUID sculptId; 7711 UUID sculptId;
7222 7712
@@ -7241,7 +7731,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7241 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7731 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7242 { 7732 {
7243 // default 7733 // default
7244 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7734 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7245 } 7735 }
7246 7736
7247 part.Shape.SetSculptProperties((byte)type, sculptId); 7737 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7258,48 +7748,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7258 ScriptSleep(200); 7748 ScriptSleep(200);
7259 } 7749 }
7260 7750
7261 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7751 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7262 { 7752 {
7263 m_host.AddScriptLPS(1); 7753 m_host.AddScriptLPS(1);
7264 7754
7265 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7755 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7266 7756
7267 ScriptSleep(200); 7757 ScriptSleep(200);
7268 } 7758 }
7269 7759
7270 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7760 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7271 { 7761 {
7272 m_host.AddScriptLPS(1); 7762 List<object> parts = new List<object>();
7763 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7764 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7765 foreach (SceneObjectPart p in prims)
7766 parts.Add(p);
7767 foreach (ScenePresence p in avatars)
7768 parts.Add(p);
7273 7769
7274 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7770 LSL_List remaining = null;
7771 uint rulesParsed = 0;
7772
7773 if (parts.Count > 0)
7774 {
7775 foreach (object part in parts)
7776 {
7777 if (part is SceneObjectPart)
7778 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7779 else
7780 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7781 }
7782
7783 while ((object)remaining != null && remaining.Length > 2)
7784 {
7785 linknumber = remaining.GetLSLIntegerItem(0);
7786 rules = remaining.GetSublist(1, -1);
7787 parts.Clear();
7788 prims = GetLinkParts(linknumber);
7789 avatars = GetLinkAvatars(linknumber);
7790 foreach (SceneObjectPart p in prims)
7791 parts.Add(p);
7792 foreach (ScenePresence p in avatars)
7793 parts.Add(p);
7794
7795 remaining = null;
7796 foreach (object part in parts)
7797 {
7798 if (part is SceneObjectPart)
7799 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7800 else
7801 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7802 }
7803 }
7804 }
7275 } 7805 }
7276 7806
7277 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7807 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7808 float material_density, float material_friction,
7809 float material_restitution, float material_gravity_modifier)
7278 { 7810 {
7279 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7811 ExtraPhysicsData physdata = new ExtraPhysicsData();
7812 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7813 physdata.Density = part.Density;
7814 physdata.Friction = part.Friction;
7815 physdata.Bounce = part.Bounciness;
7816 physdata.GravitationModifier = part.GravityModifier;
7280 7817
7281 LSL_List remaining = null; 7818 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7282 uint rulesParsed = 0; 7819 physdata.Density = material_density;
7820 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7821 physdata.Friction = material_friction;
7822 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7823 physdata.Bounce = material_restitution;
7824 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7825 physdata.GravitationModifier = material_gravity_modifier;
7283 7826
7284 foreach (SceneObjectPart part in parts) 7827 part.UpdateExtraPhysics(physdata);
7285 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7828 }
7286 7829
7287 while (remaining != null && remaining.Length > 2) 7830 public void llSetPhysicsMaterial(int material_bits,
7288 { 7831 float material_gravity_modifier, float material_restitution,
7289 linknumber = remaining.GetLSLIntegerItem(0); 7832 float material_friction, float material_density)
7290 rules = remaining.GetSublist(1, -1); 7833 {
7291 parts = GetLinkParts(linknumber); 7834 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7835 }
7292 7836
7293 foreach (SceneObjectPart part in parts) 7837 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7294 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7838 {
7839 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7840 llSetLinkPrimitiveParamsFast(linknumber, rules);
7841 ScriptSleep(200);
7842 }
7843
7844 // vector up using libomv (c&p from sop )
7845 // vector up rotated by r
7846 private Vector3 Zrot(Quaternion r)
7847 {
7848 double x, y, z, m;
7849
7850 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7851 if (Math.Abs(1.0 - m) > 0.000001)
7852 {
7853 m = 1.0 / Math.Sqrt(m);
7854 r.X *= (float)m;
7855 r.Y *= (float)m;
7856 r.Z *= (float)m;
7857 r.W *= (float)m;
7295 } 7858 }
7859
7860 x = 2 * (r.X * r.Z + r.Y * r.W);
7861 y = 2 * (-r.X * r.W + r.Y * r.Z);
7862 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7863
7864 return new Vector3((float)x, (float)y, (float)z);
7296 } 7865 }
7297 7866
7298 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7867 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7299 { 7868 {
7869 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7870 return null;
7871
7300 int idx = 0; 7872 int idx = 0;
7301 int idxStart = 0; 7873 int idxStart = 0;
7302 7874
7875 SceneObjectGroup parentgrp = part.ParentGroup;
7876
7303 bool positionChanged = false; 7877 bool positionChanged = false;
7304 LSL_Vector currentPosition = GetPartLocalPos(part); 7878 LSL_Vector currentPosition = GetPartLocalPos(part);
7305 7879
@@ -7324,8 +7898,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7324 return null; 7898 return null;
7325 7899
7326 v=rules.GetVector3Item(idx++); 7900 v=rules.GetVector3Item(idx++);
7327 positionChanged = true;
7328 currentPosition = GetSetPosTarget(part, v, currentPosition); 7901 currentPosition = GetSetPosTarget(part, v, currentPosition);
7902 positionChanged = true;
7329 7903
7330 break; 7904 break;
7331 case (int)ScriptBaseClass.PRIM_SIZE: 7905 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7602,7 +8176,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7602 return null; 8176 return null;
7603 8177
7604 string ph = rules.Data[idx++].ToString(); 8178 string ph = rules.Data[idx++].ToString();
7605 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8179 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7606 8180
7607 break; 8181 break;
7608 8182
@@ -7620,12 +8194,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7620 part.ScriptSetPhysicsStatus(physics); 8194 part.ScriptSetPhysicsStatus(physics);
7621 break; 8195 break;
7622 8196
8197 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8198 if (remain < 1)
8199 return null;
8200
8201 int shape_type = rules.GetLSLIntegerItem(idx++);
8202
8203 ExtraPhysicsData physdata = new ExtraPhysicsData();
8204 physdata.Density = part.Density;
8205 physdata.Bounce = part.Bounciness;
8206 physdata.GravitationModifier = part.GravityModifier;
8207 physdata.PhysShapeType = (PhysShapeType)shape_type;
8208
8209 part.UpdateExtraPhysics(physdata);
8210
8211 break;
8212
8213 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8214 if (remain < 5)
8215 return null;
8216
8217 int material_bits = rules.GetLSLIntegerItem(idx++);
8218 float material_density = (float)rules.GetLSLFloatItem(idx++);
8219 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8220 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8221 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8222
8223 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8224
8225 break;
8226
7623 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8227 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7624 if (remain < 1) 8228 if (remain < 1)
7625 return null; 8229 return null;
7626 string temp = rules.Data[idx++].ToString(); 8230 string temp = rules.Data[idx++].ToString();
7627 8231
7628 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8232 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7629 8233
7630 break; 8234 break;
7631 8235
@@ -7699,7 +8303,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7699 if (part.ParentGroup.RootPart == part) 8303 if (part.ParentGroup.RootPart == part)
7700 { 8304 {
7701 SceneObjectGroup parent = part.ParentGroup; 8305 SceneObjectGroup parent = part.ParentGroup;
7702 parent.UpdateGroupPosition(currentPosition); 8306 Util.FireAndForget(delegate(object x) {
8307 parent.UpdateGroupPosition(currentPosition);
8308 });
7703 } 8309 }
7704 else 8310 else
7705 { 8311 {
@@ -7744,10 +8350,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7744 8350
7745 public LSL_String llXorBase64Strings(string str1, string str2) 8351 public LSL_String llXorBase64Strings(string str1, string str2)
7746 { 8352 {
7747 m_host.AddScriptLPS(1); 8353 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7748 Deprecated("llXorBase64Strings"); 8354
7749 ScriptSleep(300); 8355 ScriptSleep(300);
7750 return String.Empty; 8356 m_host.AddScriptLPS(1);
8357
8358 if (str1 == String.Empty)
8359 return String.Empty;
8360 if (str2 == String.Empty)
8361 return str1;
8362
8363 int len = str2.Length;
8364 if ((len % 4) != 0) // LL is EVIL!!!!
8365 {
8366 while (str2.EndsWith("="))
8367 str2 = str2.Substring(0, str2.Length - 1);
8368
8369 len = str2.Length;
8370 int mod = len % 4;
8371
8372 if (mod == 1)
8373 str2 = str2.Substring(0, str2.Length - 1);
8374 else if (mod == 2)
8375 str2 += "==";
8376 else if (mod == 3)
8377 str2 += "=";
8378 }
8379
8380 byte[] data1;
8381 byte[] data2;
8382 try
8383 {
8384 data1 = Convert.FromBase64String(str1);
8385 data2 = Convert.FromBase64String(str2);
8386 }
8387 catch (Exception)
8388 {
8389 return new LSL_String(String.Empty);
8390 }
8391
8392 // For cases where the decoded length of s2 is greater
8393 // than the decoded length of s1, simply perform a normal
8394 // decode and XOR
8395 //
8396 if (data2.Length >= data1.Length)
8397 {
8398 for (int pos = 0 ; pos < data1.Length ; pos++ )
8399 data1[pos] ^= data2[pos];
8400
8401 return Convert.ToBase64String(data1);
8402 }
8403
8404 // Remove padding
8405 while (str1.EndsWith("="))
8406 str1 = str1.Substring(0, str1.Length - 1);
8407 while (str2.EndsWith("="))
8408 str2 = str2.Substring(0, str2.Length - 1);
8409
8410 byte[] d1 = new byte[str1.Length];
8411 byte[] d2 = new byte[str2.Length];
8412
8413 for (int i = 0 ; i < str1.Length ; i++)
8414 {
8415 int idx = b64.IndexOf(str1.Substring(i, 1));
8416 if (idx == -1)
8417 idx = 0;
8418 d1[i] = (byte)idx;
8419 }
8420
8421 for (int i = 0 ; i < str2.Length ; i++)
8422 {
8423 int idx = b64.IndexOf(str2.Substring(i, 1));
8424 if (idx == -1)
8425 idx = 0;
8426 d2[i] = (byte)idx;
8427 }
8428
8429 string output = String.Empty;
8430
8431 for (int pos = 0 ; pos < d1.Length ; pos++)
8432 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8433
8434 while (output.Length % 3 > 0)
8435 output += "=";
8436
8437 return output;
7751 } 8438 }
7752 8439
7753 public void llRemoteDataSetRegion() 8440 public void llRemoteDataSetRegion()
@@ -7871,13 +8558,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7871 public LSL_Integer llGetNumberOfPrims() 8558 public LSL_Integer llGetNumberOfPrims()
7872 { 8559 {
7873 m_host.AddScriptLPS(1); 8560 m_host.AddScriptLPS(1);
7874 int avatarCount = 0; 8561 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7875 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8562
7876 {
7877 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7878 avatarCount++;
7879 });
7880
7881 return m_host.ParentGroup.PrimCount + avatarCount; 8563 return m_host.ParentGroup.PrimCount + avatarCount;
7882 } 8564 }
7883 8565
@@ -7893,55 +8575,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7893 m_host.AddScriptLPS(1); 8575 m_host.AddScriptLPS(1);
7894 UUID objID = UUID.Zero; 8576 UUID objID = UUID.Zero;
7895 LSL_List result = new LSL_List(); 8577 LSL_List result = new LSL_List();
8578
8579 // If the ID is not valid, return null result
7896 if (!UUID.TryParse(obj, out objID)) 8580 if (!UUID.TryParse(obj, out objID))
7897 { 8581 {
7898 result.Add(new LSL_Vector()); 8582 result.Add(new LSL_Vector());
7899 result.Add(new LSL_Vector()); 8583 result.Add(new LSL_Vector());
7900 return result; 8584 return result;
7901 } 8585 }
8586
8587 // Check if this is an attached prim. If so, replace
8588 // the UUID with the avatar UUID and report it's bounding box
8589 SceneObjectPart part = World.GetSceneObjectPart(objID);
8590 if (part != null && part.ParentGroup.IsAttachment)
8591 objID = part.ParentGroup.AttachedAvatar;
8592
8593 // Find out if this is an avatar ID. If so, return it's box
7902 ScenePresence presence = World.GetScenePresence(objID); 8594 ScenePresence presence = World.GetScenePresence(objID);
7903 if (presence != null) 8595 if (presence != null)
7904 { 8596 {
7905 if (presence.ParentID == 0) // not sat on an object 8597 // As per LSL Wiki, there is no difference between sitting
8598 // and standing avatar since server 1.36
8599 LSL_Vector lower;
8600 LSL_Vector upper;
8601 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8602 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7906 { 8603 {
7907 LSL_Vector lower; 8604 // This is for ground sitting avatars
7908 LSL_Vector upper; 8605 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7909 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8606 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7910 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8607 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7911 {
7912 // This is for ground sitting avatars
7913 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7914 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7915 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7916 }
7917 else
7918 {
7919 // This is for standing/flying avatars
7920 float height = presence.Appearance.AvatarHeight / 2.0f;
7921 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7922 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7923 }
7924 result.Add(lower);
7925 result.Add(upper);
7926 return result;
7927 } 8608 }
7928 else 8609 else
7929 { 8610 {
7930 // sitting on an object so we need the bounding box of that 8611 // This is for standing/flying avatars
7931 // which should include the avatar so set the UUID to the 8612 float height = presence.Appearance.AvatarHeight / 2.0f;
7932 // UUID of the object the avatar is sat on and allow it to fall through 8613 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7933 // to processing an object 8614 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7934 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7935 objID = p.UUID;
7936 } 8615 }
8616
8617 // Adjust to the documented error offsets (see LSL Wiki)
8618 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8619 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8620
8621 if (lower.x > upper.x)
8622 lower.x = upper.x;
8623 if (lower.y > upper.y)
8624 lower.y = upper.y;
8625 if (lower.z > upper.z)
8626 lower.z = upper.z;
8627
8628 result.Add(lower);
8629 result.Add(upper);
8630 return result;
7937 } 8631 }
7938 SceneObjectPart part = World.GetSceneObjectPart(objID); 8632
8633 part = World.GetSceneObjectPart(objID);
7939 // Currently only works for single prims without a sitting avatar 8634 // Currently only works for single prims without a sitting avatar
7940 if (part != null) 8635 if (part != null)
7941 { 8636 {
7942 Vector3 halfSize = part.Scale / 2.0f; 8637 float minX;
7943 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8638 float maxX;
7944 LSL_Vector upper = new LSL_Vector(halfSize); 8639 float minY;
8640 float maxY;
8641 float minZ;
8642 float maxZ;
8643
8644 // This BBox is in sim coordinates, with the offset being
8645 // a contained point.
8646 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8647 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8648
8649 minX -= offsets[0].X;
8650 maxX -= offsets[0].X;
8651 minY -= offsets[0].Y;
8652 maxY -= offsets[0].Y;
8653 minZ -= offsets[0].Z;
8654 maxZ -= offsets[0].Z;
8655
8656 LSL_Vector lower;
8657 LSL_Vector upper;
8658
8659 // Adjust to the documented error offsets (see LSL Wiki)
8660 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8661 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8662
8663 if (lower.x > upper.x)
8664 lower.x = upper.x;
8665 if (lower.y > upper.y)
8666 lower.y = upper.y;
8667 if (lower.z > upper.z)
8668 lower.z = upper.z;
8669
7945 result.Add(lower); 8670 result.Add(lower);
7946 result.Add(upper); 8671 result.Add(upper);
7947 return result; 8672 return result;
@@ -7955,7 +8680,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7955 8680
7956 public LSL_Vector llGetGeometricCenter() 8681 public LSL_Vector llGetGeometricCenter()
7957 { 8682 {
7958 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8683 Vector3 tmp = m_host.GetGeometricCenter();
8684 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7959 } 8685 }
7960 8686
7961 public LSL_List llGetPrimitiveParams(LSL_List rules) 8687 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7983,24 +8709,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7983 { 8709 {
7984 m_host.AddScriptLPS(1); 8710 m_host.AddScriptLPS(1);
7985 8711
7986 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8712 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8713 // keep other options as before
7987 8714
8715 List<SceneObjectPart> parts;
8716 List<ScenePresence> avatars;
8717
7988 LSL_List res = new LSL_List(); 8718 LSL_List res = new LSL_List();
7989 LSL_List remaining = null; 8719 LSL_List remaining = null;
7990 8720
7991 foreach (SceneObjectPart part in parts) 8721 while (rules.Length > 0)
7992 { 8722 {
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); 8723 parts = GetLinkParts(linknumber);
8724 avatars = GetLinkAvatars(linknumber);
8001 8725
8726 remaining = null;
8002 foreach (SceneObjectPart part in parts) 8727 foreach (SceneObjectPart part in parts)
8728 {
8003 remaining = GetPrimParams(part, rules, ref res); 8729 remaining = GetPrimParams(part, rules, ref res);
8730 }
8731 foreach (ScenePresence avatar in avatars)
8732 {
8733 remaining = GetPrimParams(avatar, rules, ref res);
8734 }
8735
8736 if (remaining != null && remaining.Length > 0)
8737 {
8738 linknumber = remaining.GetLSLIntegerItem(0);
8739 rules = remaining.GetSublist(1, -1);
8740 }
8004 } 8741 }
8005 8742
8006 return res; 8743 return res;
@@ -8045,13 +8782,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8045 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8782 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8046 part.AbsolutePosition.Y, 8783 part.AbsolutePosition.Y,
8047 part.AbsolutePosition.Z); 8784 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); 8785 res.Add(v);
8056 break; 8786 break;
8057 8787
@@ -8223,30 +8953,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8223 if (remain < 1) 8953 if (remain < 1)
8224 return null; 8954 return null;
8225 8955
8226 face=(int)rules.GetLSLIntegerItem(idx++); 8956 face = (int)rules.GetLSLIntegerItem(idx++);
8227 8957
8228 tex = part.Shape.Textures; 8958 tex = part.Shape.Textures;
8959 int shiny;
8229 if (face == ScriptBaseClass.ALL_SIDES) 8960 if (face == ScriptBaseClass.ALL_SIDES)
8230 { 8961 {
8231 for (face = 0; face < GetNumberOfSides(part); face++) 8962 for (face = 0; face < GetNumberOfSides(part); face++)
8232 { 8963 {
8233 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8964 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8234 // Convert Shininess to PRIM_SHINY_* 8965 if (shinyness == Shininess.High)
8235 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8966 {
8236 // PRIM_BUMP_* 8967 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8237 res.Add(new LSL_Integer((int)texface.Bump)); 8968 }
8969 else if (shinyness == Shininess.Medium)
8970 {
8971 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8972 }
8973 else if (shinyness == Shininess.Low)
8974 {
8975 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8976 }
8977 else
8978 {
8979 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8980 }
8981 res.Add(new LSL_Integer(shiny));
8982 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8238 } 8983 }
8239 } 8984 }
8240 else 8985 else
8241 { 8986 {
8242 if (face >= 0 && face < GetNumberOfSides(part)) 8987 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8988 if (shinyness == Shininess.High)
8243 { 8989 {
8244 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8990 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8245 // Convert Shininess to PRIM_SHINY_* 8991 }
8246 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8992 else if (shinyness == Shininess.Medium)
8247 // PRIM_BUMP_* 8993 {
8248 res.Add(new LSL_Integer((int)texface.Bump)); 8994 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8995 }
8996 else if (shinyness == Shininess.Low)
8997 {
8998 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8999 }
9000 else
9001 {
9002 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8249 } 9003 }
9004 res.Add(new LSL_Integer(shiny));
9005 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8250 } 9006 }
8251 break; 9007 break;
8252 9008
@@ -8254,24 +9010,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8254 if (remain < 1) 9010 if (remain < 1)
8255 return null; 9011 return null;
8256 9012
8257 face=(int)rules.GetLSLIntegerItem(idx++); 9013 face = (int)rules.GetLSLIntegerItem(idx++);
8258 9014
8259 tex = part.Shape.Textures; 9015 tex = part.Shape.Textures;
9016 int fullbright;
8260 if (face == ScriptBaseClass.ALL_SIDES) 9017 if (face == ScriptBaseClass.ALL_SIDES)
8261 { 9018 {
8262 for (face = 0; face < GetNumberOfSides(part); face++) 9019 for (face = 0; face < GetNumberOfSides(part); face++)
8263 { 9020 {
8264 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9021 if (tex.GetFace((uint)face).Fullbright == true)
8265 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9022 {
9023 fullbright = ScriptBaseClass.TRUE;
9024 }
9025 else
9026 {
9027 fullbright = ScriptBaseClass.FALSE;
9028 }
9029 res.Add(new LSL_Integer(fullbright));
8266 } 9030 }
8267 } 9031 }
8268 else 9032 else
8269 { 9033 {
8270 if (face >= 0 && face < GetNumberOfSides(part)) 9034 if (tex.GetFace((uint)face).Fullbright == true)
8271 { 9035 {
8272 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9036 fullbright = ScriptBaseClass.TRUE;
8273 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9037 }
9038 else
9039 {
9040 fullbright = ScriptBaseClass.FALSE;
8274 } 9041 }
9042 res.Add(new LSL_Integer(fullbright));
8275 } 9043 }
8276 break; 9044 break;
8277 9045
@@ -8293,27 +9061,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8293 break; 9061 break;
8294 9062
8295 case (int)ScriptBaseClass.PRIM_TEXGEN: 9063 case (int)ScriptBaseClass.PRIM_TEXGEN:
9064 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8296 if (remain < 1) 9065 if (remain < 1)
8297 return null; 9066 return null;
8298 9067
8299 face=(int)rules.GetLSLIntegerItem(idx++); 9068 face = (int)rules.GetLSLIntegerItem(idx++);
8300 9069
8301 tex = part.Shape.Textures; 9070 tex = part.Shape.Textures;
8302 if (face == ScriptBaseClass.ALL_SIDES) 9071 if (face == ScriptBaseClass.ALL_SIDES)
8303 { 9072 {
8304 for (face = 0; face < GetNumberOfSides(part); face++) 9073 for (face = 0; face < GetNumberOfSides(part); face++)
8305 { 9074 {
8306 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9075 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8307 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9076 {
8308 res.Add(new LSL_Integer((uint)texgen >> 1)); 9077 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9078 }
9079 else
9080 {
9081 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9082 }
8309 } 9083 }
8310 } 9084 }
8311 else 9085 else
8312 { 9086 {
8313 if (face >= 0 && face < GetNumberOfSides(part)) 9087 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8314 { 9088 {
8315 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9089 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8316 res.Add(new LSL_Integer((uint)texgen >> 1)); 9090 }
9091 else
9092 {
9093 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8317 } 9094 }
8318 } 9095 }
8319 break; 9096 break;
@@ -8337,24 +9114,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8337 if (remain < 1) 9114 if (remain < 1)
8338 return null; 9115 return null;
8339 9116
8340 face=(int)rules.GetLSLIntegerItem(idx++); 9117 face = (int)rules.GetLSLIntegerItem(idx++);
8341 9118
8342 tex = part.Shape.Textures; 9119 tex = part.Shape.Textures;
9120 float primglow;
8343 if (face == ScriptBaseClass.ALL_SIDES) 9121 if (face == ScriptBaseClass.ALL_SIDES)
8344 { 9122 {
8345 for (face = 0; face < GetNumberOfSides(part); face++) 9123 for (face = 0; face < GetNumberOfSides(part); face++)
8346 { 9124 {
8347 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9125 primglow = tex.GetFace((uint)face).Glow;
8348 res.Add(new LSL_Float(texface.Glow)); 9126 res.Add(new LSL_Float(primglow));
8349 } 9127 }
8350 } 9128 }
8351 else 9129 else
8352 { 9130 {
8353 if (face >= 0 && face < GetNumberOfSides(part)) 9131 primglow = tex.GetFace((uint)face).Glow;
8354 { 9132 res.Add(new LSL_Float(primglow));
8355 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8356 res.Add(new LSL_Float(texface.Glow));
8357 }
8358 } 9133 }
8359 break; 9134 break;
8360 9135
@@ -8366,15 +9141,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8366 textColor.B)); 9141 textColor.B));
8367 res.Add(new LSL_Float(textColor.A)); 9142 res.Add(new LSL_Float(textColor.A));
8368 break; 9143 break;
9144
8369 case (int)ScriptBaseClass.PRIM_NAME: 9145 case (int)ScriptBaseClass.PRIM_NAME:
8370 res.Add(new LSL_String(part.Name)); 9146 res.Add(new LSL_String(part.Name));
8371 break; 9147 break;
9148
8372 case (int)ScriptBaseClass.PRIM_DESC: 9149 case (int)ScriptBaseClass.PRIM_DESC:
8373 res.Add(new LSL_String(part.Description)); 9150 res.Add(new LSL_String(part.Description));
8374 break; 9151 break;
9152
8375 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9153 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8376 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9154 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8377 break; 9155 break;
9156
8378 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9157 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8379 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9158 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8380 break; 9159 break;
@@ -8985,8 +9764,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8985 // The function returns an ordered list 9764 // The function returns an ordered list
8986 // representing the tokens found in the supplied 9765 // representing the tokens found in the supplied
8987 // sources string. If two successive tokenizers 9766 // sources string. If two successive tokenizers
8988 // are encountered, then a NULL entry is added 9767 // are encountered, then a null-string entry is
8989 // to the list. 9768 // added to the list.
8990 // 9769 //
8991 // It is a precondition that the source and 9770 // It is a precondition that the source and
8992 // toekizer lisst are non-null. If they are null, 9771 // toekizer lisst are non-null. If they are null,
@@ -8994,7 +9773,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8994 // while their lengths are being determined. 9773 // while their lengths are being determined.
8995 // 9774 //
8996 // A small amount of working memoryis required 9775 // A small amount of working memoryis required
8997 // of approximately 8*#tokenizers. 9776 // of approximately 8*#tokenizers + 8*srcstrlen.
8998 // 9777 //
8999 // There are many ways in which this function 9778 // There are many ways in which this function
9000 // can be implemented, this implementation is 9779 // can be implemented, this implementation is
@@ -9010,155 +9789,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9010 // and eliminates redundant tokenizers as soon 9789 // and eliminates redundant tokenizers as soon
9011 // as is possible. 9790 // as is possible.
9012 // 9791 //
9013 // The implementation tries to avoid any copying 9792 // The implementation tries to minimize temporary
9014 // of arrays or other objects. 9793 // garbage generation.
9015 // </remarks> 9794 // </remarks>
9016 9795
9017 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9796 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9018 { 9797 {
9019 int beginning = 0; 9798 return ParseString2List(src, separators, spacers, true);
9020 int srclen = src.Length; 9799 }
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 9800
9035 LSL_List tokens = new LSL_List(); 9801 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9802 {
9803 int srclen = src.Length;
9804 int seplen = separators.Length;
9805 object[] separray = separators.Data;
9806 int spclen = spacers.Length;
9807 object[] spcarray = spacers.Data;
9808 int dellen = 0;
9809 string[] delarray = new string[seplen+spclen];
9036 9810
9037 // All entries are initially valid 9811 int outlen = 0;
9812 string[] outarray = new string[srclen*2+1];
9038 9813
9039 for (int i = 0; i < mlen; i++) 9814 int i, j;
9040 active[i] = true; 9815 string d;
9041 9816
9042 offset[mlen] = srclen; 9817 m_host.AddScriptLPS(1);
9043 9818
9044 while (beginning < srclen) 9819 /*
9820 * Convert separator and spacer lists to C# strings.
9821 * Also filter out null strings so we don't hang.
9822 */
9823 for (i = 0; i < seplen; i ++)
9045 { 9824 {
9825 d = separray[i].ToString();
9826 if (d.Length > 0)
9827 {
9828 delarray[dellen++] = d;
9829 }
9830 }
9831 seplen = dellen;
9046 9832
9047 best = mlen; // as bad as it gets 9833 for (i = 0; i < spclen; i ++)
9834 {
9835 d = spcarray[i].ToString();
9836 if (d.Length > 0)
9837 {
9838 delarray[dellen++] = d;
9839 }
9840 }
9048 9841
9049 // Scan for separators 9842 /*
9843 * Scan through source string from beginning to end.
9844 */
9845 for (i = 0;;)
9846 {
9050 9847
9051 for (j = 0; j < seplen; j++) 9848 /*
9849 * Find earliest delimeter in src starting at i (if any).
9850 */
9851 int earliestDel = -1;
9852 int earliestSrc = srclen;
9853 string earliestStr = null;
9854 for (j = 0; j < dellen; j ++)
9052 { 9855 {
9053 if (separray[j].ToString() == String.Empty) 9856 d = delarray[j];
9054 active[j] = false; 9857 if (d != null)
9055
9056 if (active[j])
9057 { 9858 {
9058 // scan all of the markers 9859 int index = src.IndexOf(d, i);
9059 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9860 if (index < 0)
9060 { 9861 {
9061 // not present at all 9862 delarray[j] = null; // delim nowhere in src, don't check it anymore
9062 active[j] = false;
9063 } 9863 }
9064 else 9864 else if (index < earliestSrc)
9065 { 9865 {
9066 // present and correct 9866 earliestSrc = index; // where delimeter starts in source string
9067 if (offset[j] < offset[best]) 9867 earliestDel = j; // where delimeter is in delarray[]
9068 { 9868 earliestStr = d; // the delimeter string from delarray[]
9069 // closest so far 9869 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 } 9870 }
9075 } 9871 }
9076 } 9872 }
9077 9873
9078 // Scan for spacers 9874 /*
9079 9875 * Output source string starting at i through start of earliest delimeter.
9080 if (offset[best] != beginning) 9876 */
9877 if (keepNulls || (earliestSrc > i))
9081 { 9878 {
9082 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9879 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 } 9880 }
9107 9881
9108 // This is the normal exit from the scanning loop 9882 /*
9883 * If no delimeter found at or after i, we're done scanning.
9884 */
9885 if (earliestDel < 0) break;
9109 9886
9110 if (best == mlen) 9887 /*
9888 * If delimeter was a spacer, output the spacer.
9889 */
9890 if (earliestDel >= seplen)
9111 { 9891 {
9112 // no markers were found on this pass 9892 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 } 9893 }
9118 9894
9119 // Otherwise we just add the newly delimited token 9895 /*
9120 // and recalculate where the search should continue. 9896 * Look at rest of src string following delimeter.
9121 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9897 */
9122 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9898 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 } 9899 }
9136 9900
9137 // This an awkward an not very intuitive boundary case. If the 9901 /*
9138 // last substring is a tokenizer, then there is an implied trailing 9902 * 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 9903 */
9140 // arduous. Alternatively the 'break' could be replced with a return 9904 object[] outlist = new object[outlen];
9141 // but that's shabby programming. 9905 for (i = 0; i < outlen; i ++)
9142
9143 if ((beginning == srclen) && (keepNulls))
9144 { 9906 {
9145 if (srclen != 0) 9907 outlist[i] = new LSL_String(outarray[i]);
9146 tokens.Add(new LSL_String(""));
9147 } 9908 }
9148 9909 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 } 9910 }
9163 9911
9164 public LSL_Integer llGetObjectPermMask(int mask) 9912 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9253,6 +10001,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9253 case 4: 10001 case 4:
9254 return (int)item.NextPermissions; 10002 return (int)item.NextPermissions;
9255 } 10003 }
10004 m_host.TaskInventory.LockItemsForRead(false);
9256 10005
9257 return -1; 10006 return -1;
9258 } 10007 }
@@ -9455,31 +10204,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9455 UUID key = new UUID(); 10204 UUID key = new UUID();
9456 if (UUID.TryParse(id, out key)) 10205 if (UUID.TryParse(id, out key))
9457 { 10206 {
9458 try 10207 // return total object mass
9459 { 10208 SceneObjectPart part = World.GetSceneObjectPart(key);
9460 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10209 if (part != null)
9461 if (obj != null) 10210 return part.ParentGroup.GetMass();
9462 return (double)obj.GetMass(); 10211
9463 // the object is null so the key is for an avatar 10212 // the object is null so the key is for an avatar
9464 ScenePresence avatar = World.GetScenePresence(key); 10213 ScenePresence avatar = World.GetScenePresence(key);
9465 if (avatar != null) 10214 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 { 10215 {
9475 return 0; // The Object/Agent not in the region so just return zero 10216 if (avatar.IsChildAgent)
10217 {
10218 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10219 // child agents have a mass of 1.0
10220 return 1;
10221 }
10222 else
10223 {
10224 return (double)avatar.GetMass();
10225 }
9476 } 10226 }
9477 } 10227 }
9478 return 0; 10228 return 0;
9479 } 10229 }
9480 10230
9481 /// <summary> 10231 /// <summary>
9482 /// illListReplaceList removes the sub-list defined by the inclusive indices 10232 /// llListReplaceList removes the sub-list defined by the inclusive indices
9483 /// start and end and inserts the src list in its place. The inclusive 10233 /// 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 10234 /// 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 10235 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9536,16 +10286,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9536 // based upon end. Note that if end exceeds the upper 10286 // based upon end. Note that if end exceeds the upper
9537 // bound in this case, the entire destination list 10287 // bound in this case, the entire destination list
9538 // is removed. 10288 // is removed.
9539 else 10289 else if (start == 0)
9540 { 10290 {
9541 if (end + 1 < dest.Length) 10291 if (end + 1 < dest.Length)
9542 {
9543 return src + dest.GetSublist(end + 1, -1); 10292 return src + dest.GetSublist(end + 1, -1);
9544 }
9545 else 10293 else
9546 {
9547 return src; 10294 return src;
9548 } 10295 }
10296 else // Start < 0
10297 {
10298 if (end + 1 < dest.Length)
10299 return dest.GetSublist(end + 1, -1);
10300 else
10301 return new LSL_List();
9549 } 10302 }
9550 } 10303 }
9551 // Finally, if start > end, we strip away a prefix and 10304 // Finally, if start > end, we strip away a prefix and
@@ -9596,17 +10349,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9596 int width = 0; 10349 int width = 0;
9597 int height = 0; 10350 int height = 0;
9598 10351
9599 ParcelMediaCommandEnum? commandToSend = null; 10352 uint commandToSend = 0;
9600 float time = 0.0f; // default is from start 10353 float time = 0.0f; // default is from start
9601 10354
9602 ScenePresence presence = null; 10355 ScenePresence presence = null;
9603 10356
9604 for (int i = 0; i < commandList.Data.Length; i++) 10357 for (int i = 0; i < commandList.Data.Length; i++)
9605 { 10358 {
9606 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10359 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9607 switch (command) 10360 switch (command)
9608 { 10361 {
9609 case ParcelMediaCommandEnum.Agent: 10362 case (uint)ParcelMediaCommandEnum.Agent:
9610 // we send only to one agent 10363 // we send only to one agent
9611 if ((i + 1) < commandList.Length) 10364 if ((i + 1) < commandList.Length)
9612 { 10365 {
@@ -9623,25 +10376,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9623 } 10376 }
9624 break; 10377 break;
9625 10378
9626 case ParcelMediaCommandEnum.Loop: 10379 case (uint)ParcelMediaCommandEnum.Loop:
9627 loop = 1; 10380 loop = 1;
9628 commandToSend = command; 10381 commandToSend = command;
9629 update = true; //need to send the media update packet to set looping 10382 update = true; //need to send the media update packet to set looping
9630 break; 10383 break;
9631 10384
9632 case ParcelMediaCommandEnum.Play: 10385 case (uint)ParcelMediaCommandEnum.Play:
9633 loop = 0; 10386 loop = 0;
9634 commandToSend = command; 10387 commandToSend = command;
9635 update = true; //need to send the media update packet to make sure it doesn't loop 10388 update = true; //need to send the media update packet to make sure it doesn't loop
9636 break; 10389 break;
9637 10390
9638 case ParcelMediaCommandEnum.Pause: 10391 case (uint)ParcelMediaCommandEnum.Pause:
9639 case ParcelMediaCommandEnum.Stop: 10392 case (uint)ParcelMediaCommandEnum.Stop:
9640 case ParcelMediaCommandEnum.Unload: 10393 case (uint)ParcelMediaCommandEnum.Unload:
9641 commandToSend = command; 10394 commandToSend = command;
9642 break; 10395 break;
9643 10396
9644 case ParcelMediaCommandEnum.Url: 10397 case (uint)ParcelMediaCommandEnum.Url:
9645 if ((i + 1) < commandList.Length) 10398 if ((i + 1) < commandList.Length)
9646 { 10399 {
9647 if (commandList.Data[i + 1] is LSL_String) 10400 if (commandList.Data[i + 1] is LSL_String)
@@ -9654,7 +10407,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9654 } 10407 }
9655 break; 10408 break;
9656 10409
9657 case ParcelMediaCommandEnum.Texture: 10410 case (uint)ParcelMediaCommandEnum.Texture:
9658 if ((i + 1) < commandList.Length) 10411 if ((i + 1) < commandList.Length)
9659 { 10412 {
9660 if (commandList.Data[i + 1] is LSL_String) 10413 if (commandList.Data[i + 1] is LSL_String)
@@ -9667,7 +10420,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9667 } 10420 }
9668 break; 10421 break;
9669 10422
9670 case ParcelMediaCommandEnum.Time: 10423 case (uint)ParcelMediaCommandEnum.Time:
9671 if ((i + 1) < commandList.Length) 10424 if ((i + 1) < commandList.Length)
9672 { 10425 {
9673 if (commandList.Data[i + 1] is LSL_Float) 10426 if (commandList.Data[i + 1] is LSL_Float)
@@ -9679,7 +10432,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9679 } 10432 }
9680 break; 10433 break;
9681 10434
9682 case ParcelMediaCommandEnum.AutoAlign: 10435 case (uint)ParcelMediaCommandEnum.AutoAlign:
9683 if ((i + 1) < commandList.Length) 10436 if ((i + 1) < commandList.Length)
9684 { 10437 {
9685 if (commandList.Data[i + 1] is LSL_Integer) 10438 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9693,7 +10446,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9693 } 10446 }
9694 break; 10447 break;
9695 10448
9696 case ParcelMediaCommandEnum.Type: 10449 case (uint)ParcelMediaCommandEnum.Type:
9697 if ((i + 1) < commandList.Length) 10450 if ((i + 1) < commandList.Length)
9698 { 10451 {
9699 if (commandList.Data[i + 1] is LSL_String) 10452 if (commandList.Data[i + 1] is LSL_String)
@@ -9706,7 +10459,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9706 } 10459 }
9707 break; 10460 break;
9708 10461
9709 case ParcelMediaCommandEnum.Desc: 10462 case (uint)ParcelMediaCommandEnum.Desc:
9710 if ((i + 1) < commandList.Length) 10463 if ((i + 1) < commandList.Length)
9711 { 10464 {
9712 if (commandList.Data[i + 1] is LSL_String) 10465 if (commandList.Data[i + 1] is LSL_String)
@@ -9719,7 +10472,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9719 } 10472 }
9720 break; 10473 break;
9721 10474
9722 case ParcelMediaCommandEnum.Size: 10475 case (uint)ParcelMediaCommandEnum.Size:
9723 if ((i + 2) < commandList.Length) 10476 if ((i + 2) < commandList.Length)
9724 { 10477 {
9725 if (commandList.Data[i + 1] is LSL_Integer) 10478 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9789,7 +10542,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9789 } 10542 }
9790 } 10543 }
9791 10544
9792 if (commandToSend != null) 10545 if (commandToSend != 0)
9793 { 10546 {
9794 // the commandList contained a start/stop/... command, too 10547 // the commandList contained a start/stop/... command, too
9795 if (presence == null) 10548 if (presence == null)
@@ -9826,7 +10579,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9826 10579
9827 if (aList.Data[i] != null) 10580 if (aList.Data[i] != null)
9828 { 10581 {
9829 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10582 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9830 { 10583 {
9831 case ParcelMediaCommandEnum.Url: 10584 case ParcelMediaCommandEnum.Url:
9832 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10585 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9883,15 +10636,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9883 10636
9884 if (quick_pay_buttons.Data.Length < 4) 10637 if (quick_pay_buttons.Data.Length < 4)
9885 { 10638 {
9886 LSLError("List must have at least 4 elements"); 10639 int x;
9887 return; 10640 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10641 {
10642 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10643 }
9888 } 10644 }
9889 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10645 int[] nPrice = new int[5];
9890 10646 nPrice[0] = price;
9891 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10647 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9892 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10648 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9893 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10649 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9894 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10650 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10651 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9895 m_host.ParentGroup.HasGroupChanged = true; 10652 m_host.ParentGroup.HasGroupChanged = true;
9896 } 10653 }
9897 10654
@@ -9908,7 +10665,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9908 return new LSL_Vector(); 10665 return new LSL_Vector();
9909 } 10666 }
9910 10667
9911 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10668// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10669 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9912 if (presence != null) 10670 if (presence != null)
9913 { 10671 {
9914 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10672 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9930,7 +10688,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9930 return new LSL_Rotation(); 10688 return new LSL_Rotation();
9931 } 10689 }
9932 10690
9933 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10691// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10692 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9934 if (presence != null) 10693 if (presence != null)
9935 { 10694 {
9936 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10695 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9990,14 +10749,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9990 { 10749 {
9991 m_host.AddScriptLPS(1); 10750 m_host.AddScriptLPS(1);
9992 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10751 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9993 if (detectedParams == null) return; // only works on the first detected avatar 10752 if (detectedParams == null)
9994 10753 {
10754 if (m_host.ParentGroup.IsAttachment == true)
10755 {
10756 detectedParams = new DetectParams();
10757 detectedParams.Key = m_host.OwnerID;
10758 }
10759 else
10760 {
10761 return;
10762 }
10763 }
10764
9995 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10765 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9996 if (avatar != null) 10766 if (avatar != null)
9997 { 10767 {
9998 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10768 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9999 simname, pos, lookAt); 10769 simname, pos, lookAt);
10000 } 10770 }
10771
10001 ScriptSleep(1000); 10772 ScriptSleep(1000);
10002 } 10773 }
10003 10774
@@ -10121,12 +10892,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10121 10892
10122 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10893 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10123 object[] data = rules.Data; 10894 object[] data = rules.Data;
10124 for (int i = 0; i < data.Length; ++i) { 10895 for (int i = 0; i < data.Length; ++i)
10896 {
10125 int type = Convert.ToInt32(data[i++].ToString()); 10897 int type = Convert.ToInt32(data[i++].ToString());
10126 if (i >= data.Length) break; // odd number of entries => ignore the last 10898 if (i >= data.Length) break; // odd number of entries => ignore the last
10127 10899
10128 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10900 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10129 switch (type) { 10901 switch (type)
10902 {
10130 case ScriptBaseClass.CAMERA_FOCUS: 10903 case ScriptBaseClass.CAMERA_FOCUS:
10131 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10904 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10132 case ScriptBaseClass.CAMERA_POSITION: 10905 case ScriptBaseClass.CAMERA_POSITION:
@@ -10231,19 +11004,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10231 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11004 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10232 { 11005 {
10233 m_host.AddScriptLPS(1); 11006 m_host.AddScriptLPS(1);
10234 string ret = String.Empty; 11007
10235 string src1 = llBase64ToString(str1); 11008 if (str1 == String.Empty)
10236 string src2 = llBase64ToString(str2); 11009 return String.Empty;
10237 int c = 0; 11010 if (str2 == String.Empty)
10238 for (int i = 0; i < src1.Length; i++) 11011 return str1;
11012
11013 int len = str2.Length;
11014 if ((len % 4) != 0) // LL is EVIL!!!!
10239 { 11015 {
10240 ret += (char) (src1[i] ^ src2[c]); 11016 while (str2.EndsWith("="))
11017 str2 = str2.Substring(0, str2.Length - 1);
11018
11019 len = str2.Length;
11020 int mod = len % 4;
10241 11021
10242 c++; 11022 if (mod == 1)
10243 if (c >= src2.Length) 11023 str2 = str2.Substring(0, str2.Length - 1);
10244 c = 0; 11024 else if (mod == 2)
11025 str2 += "==";
11026 else if (mod == 3)
11027 str2 += "=";
11028 }
11029
11030 byte[] data1;
11031 byte[] data2;
11032 try
11033 {
11034 data1 = Convert.FromBase64String(str1);
11035 data2 = Convert.FromBase64String(str2);
11036 }
11037 catch (Exception)
11038 {
11039 return new LSL_String(String.Empty);
11040 }
11041
11042 byte[] d2 = new Byte[data1.Length];
11043 int pos = 0;
11044
11045 if (data1.Length <= data2.Length)
11046 {
11047 Array.Copy(data2, 0, d2, 0, data1.Length);
11048 }
11049 else
11050 {
11051 while (pos < data1.Length)
11052 {
11053 len = data1.Length - pos;
11054 if (len > data2.Length)
11055 len = data2.Length;
11056
11057 Array.Copy(data2, 0, d2, pos, len);
11058 pos += len;
11059 }
10245 } 11060 }
10246 return llStringToBase64(ret); 11061
11062 for (pos = 0 ; pos < data1.Length ; pos++ )
11063 data1[pos] ^= d2[pos];
11064
11065 return Convert.ToBase64String(data1);
10247 } 11066 }
10248 11067
10249 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11068 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10296,16 +11115,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10296 if (userAgent != null) 11115 if (userAgent != null)
10297 httpHeaders["User-Agent"] = userAgent; 11116 httpHeaders["User-Agent"] = userAgent;
10298 11117
11118 // See if the URL contains any header hacks
11119 string[] urlParts = url.Split(new char[] {'\n'});
11120 if (urlParts.Length > 1)
11121 {
11122 // Iterate the passed headers and parse them
11123 for (int i = 1 ; i < urlParts.Length ; i++ )
11124 {
11125 // The rest of those would be added to the body in SL.
11126 // Let's not do that.
11127 if (urlParts[i] == String.Empty)
11128 break;
11129
11130 // See if this could be a valid header
11131 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11132 if (headerParts.Length != 2)
11133 continue;
11134
11135 string headerName = headerParts[0].Trim();
11136 string headerValue = headerParts[1].Trim();
11137
11138 // Filter out headers that could be used to abuse
11139 // another system or cloak the request
11140 if (headerName.ToLower() == "x-secondlife-shard" ||
11141 headerName.ToLower() == "x-secondlife-object-name" ||
11142 headerName.ToLower() == "x-secondlife-object-key" ||
11143 headerName.ToLower() == "x-secondlife-region" ||
11144 headerName.ToLower() == "x-secondlife-local-position" ||
11145 headerName.ToLower() == "x-secondlife-local-velocity" ||
11146 headerName.ToLower() == "x-secondlife-local-rotation" ||
11147 headerName.ToLower() == "x-secondlife-owner-name" ||
11148 headerName.ToLower() == "x-secondlife-owner-key" ||
11149 headerName.ToLower() == "connection" ||
11150 headerName.ToLower() == "content-length" ||
11151 headerName.ToLower() == "from" ||
11152 headerName.ToLower() == "host" ||
11153 headerName.ToLower() == "proxy-authorization" ||
11154 headerName.ToLower() == "referer" ||
11155 headerName.ToLower() == "trailer" ||
11156 headerName.ToLower() == "transfer-encoding" ||
11157 headerName.ToLower() == "via" ||
11158 headerName.ToLower() == "authorization")
11159 continue;
11160
11161 httpHeaders[headerName] = headerValue;
11162 }
11163
11164 // Finally, strip any protocol specifier from the URL
11165 url = urlParts[0].Trim();
11166 int idx = url.IndexOf(" HTTP/");
11167 if (idx != -1)
11168 url = url.Substring(0, idx);
11169 }
11170
10299 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11171 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10300 Regex r = new Regex(authregex); 11172 Regex r = new Regex(authregex);
10301 int[] gnums = r.GetGroupNumbers(); 11173 int[] gnums = r.GetGroupNumbers();
10302 Match m = r.Match(url); 11174 Match m = r.Match(url);
10303 if (m.Success) { 11175 if (m.Success)
10304 for (int i = 1; i < gnums.Length; i++) { 11176 {
11177 for (int i = 1; i < gnums.Length; i++)
11178 {
10305 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11179 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10306 //CaptureCollection cc = g.Captures; 11180 //CaptureCollection cc = g.Captures;
10307 } 11181 }
10308 if (m.Groups.Count == 5) { 11182 if (m.Groups.Count == 5)
11183 {
10309 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11184 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(); 11185 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10311 } 11186 }
@@ -10508,6 +11383,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10508 11383
10509 LSL_List ret = new LSL_List(); 11384 LSL_List ret = new LSL_List();
10510 UUID key = new UUID(); 11385 UUID key = new UUID();
11386
11387
10511 if (UUID.TryParse(id, out key)) 11388 if (UUID.TryParse(id, out key))
10512 { 11389 {
10513 ScenePresence av = World.GetScenePresence(key); 11390 ScenePresence av = World.GetScenePresence(key);
@@ -10525,13 +11402,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10525 ret.Add(new LSL_String("")); 11402 ret.Add(new LSL_String(""));
10526 break; 11403 break;
10527 case ScriptBaseClass.OBJECT_POS: 11404 case ScriptBaseClass.OBJECT_POS:
10528 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11405 Vector3 avpos;
11406
11407 if (av.ParentID != 0 && av.ParentPart != null)
11408 {
11409 avpos = av.OffsetPosition;
11410
11411 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11412 avpos -= sitOffset;
11413
11414 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11415 }
11416 else
11417 avpos = av.AbsolutePosition;
11418
11419 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10529 break; 11420 break;
10530 case ScriptBaseClass.OBJECT_ROT: 11421 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)); 11422 Quaternion avrot = av.Rotation;
11423 if (av.ParentID != 0 && av.ParentPart != null)
11424 {
11425 avrot = av.ParentPart.GetWorldRotation() * avrot;
11426 }
11427 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10532 break; 11428 break;
10533 case ScriptBaseClass.OBJECT_VELOCITY: 11429 case ScriptBaseClass.OBJECT_VELOCITY:
10534 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11430 Vector3 avvel = av.Velocity;
11431 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10535 break; 11432 break;
10536 case ScriptBaseClass.OBJECT_OWNER: 11433 case ScriptBaseClass.OBJECT_OWNER:
10537 ret.Add(new LSL_String(id)); 11434 ret.Add(new LSL_String(id));
@@ -10587,11 +11484,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10587 case ScriptBaseClass.OBJECT_NAME: 11484 case ScriptBaseClass.OBJECT_NAME:
10588 ret.Add(new LSL_String(obj.Name)); 11485 ret.Add(new LSL_String(obj.Name));
10589 break; 11486 break;
10590 case ScriptBaseClass.OBJECT_DESC: 11487 case ScriptBaseClass.OBJECT_DESC:
10591 ret.Add(new LSL_String(obj.Description)); 11488 ret.Add(new LSL_String(obj.Description));
10592 break; 11489 break;
10593 case ScriptBaseClass.OBJECT_POS: 11490 case ScriptBaseClass.OBJECT_POS:
10594 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11491 Vector3 opos = obj.AbsolutePosition;
11492 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10595 break; 11493 break;
10596 case ScriptBaseClass.OBJECT_ROT: 11494 case ScriptBaseClass.OBJECT_ROT:
10597 { 11495 {
@@ -10641,9 +11539,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10641 // The value returned in SL for normal prims is prim count 11539 // The value returned in SL for normal prims is prim count
10642 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11540 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10643 break; 11541 break;
10644 // The following 3 costs I have intentionaly coded to return zero. They are part of 11542
10645 // "Land Impact" calculations. These calculations are probably not applicable 11543 // 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: 11544 case ScriptBaseClass.OBJECT_SERVER_COST:
10648 // The linden calculation is here 11545 // The linden calculation is here
10649 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11546 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10651,16 +11548,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10651 ret.Add(new LSL_Float(0)); 11548 ret.Add(new LSL_Float(0));
10652 break; 11549 break;
10653 case ScriptBaseClass.OBJECT_STREAMING_COST: 11550 case ScriptBaseClass.OBJECT_STREAMING_COST:
10654 // The linden calculation is here 11551 // The value returned in SL for normal prims is prim count * 0.06
10655 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11552 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; 11553 break;
10659 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11554 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10660 // The linden calculation is here 11555 // The value returned in SL for normal prims is prim count
10661 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11556 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; 11557 break;
10665 default: 11558 default:
10666 // Invalid or unhandled constant. 11559 // Invalid or unhandled constant.
@@ -10871,15 +11764,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10871 return result; 11764 return result;
10872 } 11765 }
10873 11766
10874 public void print(string str) 11767 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10875 { 11768 {
10876 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11769 List<SceneObjectPart> parts = GetLinkParts(link);
10877 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11770 if (parts.Count < 1)
10878 if (ossl != null) 11771 return 0;
10879 { 11772
10880 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11773 return GetNumberOfSides(parts[0]);
10881 m_log.Info("LSL print():" + str);
10882 }
10883 } 11774 }
10884 11775
10885 private string Name2Username(string name) 11776 private string Name2Username(string name)
@@ -10924,7 +11815,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10924 11815
10925 return rq.ToString(); 11816 return rq.ToString();
10926 } 11817 }
10927 11818/*
11819 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11820 {
11821 m_SayShoutCount = 0;
11822 }
11823*/
10928 private struct Tri 11824 private struct Tri
10929 { 11825 {
10930 public Vector3 p1; 11826 public Vector3 p1;
@@ -11064,9 +11960,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11064 11960
11065 ContactResult result = new ContactResult (); 11961 ContactResult result = new ContactResult ();
11066 result.ConsumerID = group.LocalId; 11962 result.ConsumerID = group.LocalId;
11067 result.Depth = intersection.distance; 11963// result.Depth = intersection.distance;
11068 result.Normal = intersection.normal; 11964 result.Normal = intersection.normal;
11069 result.Pos = intersection.ipoint; 11965 result.Pos = intersection.ipoint;
11966 result.Depth = Vector3.Mag(rayStart - result.Pos);
11070 11967
11071 contacts.Add(result); 11968 contacts.Add(result);
11072 }); 11969 });
@@ -11199,6 +12096,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11199 12096
11200 return contacts[0]; 12097 return contacts[0];
11201 } 12098 }
12099/*
12100 // not done:
12101 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12102 {
12103 ContactResult[] contacts = null;
12104 World.ForEachSOG(delegate(SceneObjectGroup group)
12105 {
12106 if (m_host.ParentGroup == group)
12107 return;
12108
12109 if (group.IsAttachment)
12110 return;
12111
12112 if(group.RootPart.PhysActor != null)
12113 return;
12114
12115 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12116 });
12117 return contacts;
12118 }
12119*/
11202 12120
11203 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12121 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11204 { 12122 {
@@ -11240,32 +12158,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11240 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12158 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11241 12159
11242 12160
11243 if (checkTerrain) 12161 if (World.SuportsRayCastFiltered())
11244 { 12162 {
11245 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12163 if (dist == 0)
11246 if (groundContact != null) 12164 return list;
11247 results.Add((ContactResult)groundContact);
11248 }
11249 12165
11250 if (checkAgents) 12166 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11251 { 12167 if (checkTerrain)
11252 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12168 rayfilter |= RayFilterFlags.land;
11253 foreach (ContactResult r in agentHits) 12169// if (checkAgents)
11254 results.Add(r); 12170// rayfilter |= RayFilterFlags.agent;
11255 } 12171 if (checkPhysical)
12172 rayfilter |= RayFilterFlags.physical;
12173 if (checkNonPhysical)
12174 rayfilter |= RayFilterFlags.nonphysical;
12175 if (detectPhantom)
12176 rayfilter |= RayFilterFlags.LSLPhanton;
12177
12178 Vector3 direction = dir * ( 1/dist);
12179
12180 if(rayfilter == 0)
12181 {
12182 list.Add(new LSL_Integer(0));
12183 return list;
12184 }
12185
12186 // get some more contacts to sort ???
12187 int physcount = 4 * count;
12188 if (physcount > 20)
12189 physcount = 20;
12190
12191 object physresults;
12192 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12193
12194 if (physresults == null)
12195 {
12196 list.Add(new LSL_Integer(-3)); // timeout error
12197 return list;
12198 }
11256 12199
11257 if (checkPhysical || checkNonPhysical || detectPhantom) 12200 results = (List<ContactResult>)physresults;
12201
12202 // for now physics doesn't detect sitted avatars so do it outside physics
12203 if (checkAgents)
12204 {
12205 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12206 foreach (ContactResult r in agentHits)
12207 results.Add(r);
12208 }
12209
12210 // TODO: Replace this with a better solution. ObjectIntersection can only
12211 // detect nonphysical phantoms. They are detected by virtue of being
12212 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12213 // physicsl phantoms as done by the physics scene
12214 // We don't want anything else but phantoms here.
12215 if (detectPhantom)
12216 {
12217 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12218 foreach (ContactResult r in objectHits)
12219 results.Add(r);
12220 }
12221 }
12222 else
11258 { 12223 {
11259 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12224 if (checkTerrain)
11260 foreach (ContactResult r in objectHits) 12225 {
11261 results.Add(r); 12226 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12227 if (groundContact != null)
12228 results.Add((ContactResult)groundContact);
12229 }
12230
12231 if (checkAgents)
12232 {
12233 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12234 foreach (ContactResult r in agentHits)
12235 results.Add(r);
12236 }
12237
12238 if (checkPhysical || checkNonPhysical || detectPhantom)
12239 {
12240 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12241 foreach (ContactResult r in objectHits)
12242 results.Add(r);
12243 }
11262 } 12244 }
11263 12245
11264 results.Sort(delegate(ContactResult a, ContactResult b) 12246 results.Sort(delegate(ContactResult a, ContactResult b)
11265 { 12247 {
11266 return a.Depth.CompareTo(b.Depth); 12248 return a.Depth.CompareTo(b.Depth);
11267 }); 12249 });
11268 12250
11269 int values = 0; 12251 int values = 0;
11270 SceneObjectGroup thisgrp = m_host.ParentGroup; 12252 SceneObjectGroup thisgrp = m_host.ParentGroup;
11271 12253
@@ -11358,7 +12340,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11358 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12340 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11359 if (!isAccount) return 0; 12341 if (!isAccount) return 0;
11360 if (estate.HasAccess(id)) return 1; 12342 if (estate.HasAccess(id)) return 1;
11361 if (estate.IsBanned(id)) 12343 if (estate.IsBanned(id, World.GetUserFlags(id)))
11362 estate.RemoveBan(id); 12344 estate.RemoveBan(id);
11363 estate.AddEstateUser(id); 12345 estate.AddEstateUser(id);
11364 break; 12346 break;
@@ -11377,14 +12359,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11377 break; 12359 break;
11378 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12360 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11379 if (!isAccount) return 0; 12361 if (!isAccount) return 0;
11380 if (estate.IsBanned(id)) return 1; 12362 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11381 EstateBan ban = new EstateBan(); 12363 EstateBan ban = new EstateBan();
11382 ban.EstateID = estate.EstateID; 12364 ban.EstateID = estate.EstateID;
11383 ban.BannedUserID = id; 12365 ban.BannedUserID = id;
11384 estate.AddBan(ban); 12366 estate.AddBan(ban);
11385 break; 12367 break;
11386 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12368 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11387 if (!isAccount || !estate.IsBanned(id)) return 0; 12369 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11388 estate.RemoveBan(id); 12370 estate.RemoveBan(id);
11389 break; 12371 break;
11390 default: return 0; 12372 default: return 0;
@@ -11413,7 +12395,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11413 return 16384; 12395 return 16384;
11414 } 12396 }
11415 12397
11416 public LSL_Integer llGetUsedMemory() 12398 public virtual LSL_Integer llGetUsedMemory()
11417 { 12399 {
11418 m_host.AddScriptLPS(1); 12400 m_host.AddScriptLPS(1);
11419 // The value returned for LSO scripts in SL 12401 // The value returned for LSO scripts in SL
@@ -11441,22 +12423,731 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11441 public void llSetSoundQueueing(int queue) 12423 public void llSetSoundQueueing(int queue)
11442 { 12424 {
11443 m_host.AddScriptLPS(1); 12425 m_host.AddScriptLPS(1);
11444 NotImplemented("llSetSoundQueueing");
11445 } 12426 }
11446 12427
11447 public void llCollisionSprite(string impact_sprite) 12428 public void llCollisionSprite(string impact_sprite)
11448 { 12429 {
11449 m_host.AddScriptLPS(1); 12430 m_host.AddScriptLPS(1);
11450 NotImplemented("llCollisionSprite"); 12431 // Viewer 2.0 broke this and it's likely LL has no intention
12432 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11451 } 12433 }
11452 12434
11453 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12435 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11454 { 12436 {
11455 m_host.AddScriptLPS(1); 12437 m_host.AddScriptLPS(1);
11456 NotImplemented("llGodLikeRezObject"); 12438
12439 if (!World.Permissions.IsGod(m_host.OwnerID))
12440 NotImplemented("llGodLikeRezObject");
12441
12442 AssetBase rezAsset = World.AssetService.Get(inventory);
12443 if (rezAsset == null)
12444 {
12445 llSay(0, "Asset not found");
12446 return;
12447 }
12448
12449 SceneObjectGroup group = null;
12450
12451 try
12452 {
12453 string xmlData = Utils.BytesToString(rezAsset.Data);
12454 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12455 }
12456 catch
12457 {
12458 llSay(0, "Asset not found");
12459 return;
12460 }
12461
12462 if (group == null)
12463 {
12464 llSay(0, "Asset not found");
12465 return;
12466 }
12467
12468 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12469 group.RootPart.AttachOffset = group.AbsolutePosition;
12470
12471 group.ResetIDs();
12472
12473 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12474 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12475 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12476 group.ScheduleGroupForFullUpdate();
12477
12478 // objects rezzed with this method are die_at_edge by default.
12479 group.RootPart.SetDieAtEdge(true);
12480
12481 group.ResumeScripts();
12482
12483 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12484 "object_rez", new Object[] {
12485 new LSL_String(
12486 group.RootPart.UUID.ToString()) },
12487 new DetectParams[0]));
12488 }
12489
12490 public LSL_String llTransferLindenDollars(string destination, int amount)
12491 {
12492 UUID txn = UUID.Random();
12493
12494 Util.FireAndForget(delegate(object x)
12495 {
12496 int replycode = 0;
12497 string replydata = destination + "," + amount.ToString();
12498
12499 try
12500 {
12501 TaskInventoryItem item = m_item;
12502 if (item == null)
12503 {
12504 replydata = "SERVICE_ERROR";
12505 return;
12506 }
12507
12508 m_host.AddScriptLPS(1);
12509
12510 if (item.PermsGranter == UUID.Zero)
12511 {
12512 replydata = "MISSING_PERMISSION_DEBIT";
12513 return;
12514 }
12515
12516 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12517 {
12518 replydata = "MISSING_PERMISSION_DEBIT";
12519 return;
12520 }
12521
12522 UUID toID = new UUID();
12523
12524 if (!UUID.TryParse(destination, out toID))
12525 {
12526 replydata = "INVALID_AGENT";
12527 return;
12528 }
12529
12530 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12531
12532 if (money == null)
12533 {
12534 replydata = "TRANSFERS_DISABLED";
12535 return;
12536 }
12537
12538 bool result = money.ObjectGiveMoney(
12539 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12540
12541 if (result)
12542 {
12543 replycode = 1;
12544 return;
12545 }
12546
12547 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12548 }
12549 finally
12550 {
12551 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12552 "transaction_result", new Object[] {
12553 new LSL_String(txn.ToString()),
12554 new LSL_Integer(replycode),
12555 new LSL_String(replydata) },
12556 new DetectParams[0]));
12557 }
12558 });
12559
12560 return txn.ToString();
11457 } 12561 }
11458 12562
11459 #endregion 12563 #endregion
12564
12565 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12566 {
12567 SceneObjectGroup group = m_host.ParentGroup;
12568
12569 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12570 return;
12571 if (group.IsAttachment)
12572 return;
12573
12574 if (frames.Data.Length > 0) // We are getting a new motion
12575 {
12576 if (group.RootPart.KeyframeMotion != null)
12577 group.RootPart.KeyframeMotion.Delete();
12578 group.RootPart.KeyframeMotion = null;
12579
12580 int idx = 0;
12581
12582 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12583 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12584
12585 while (idx < options.Data.Length)
12586 {
12587 int option = (int)options.GetLSLIntegerItem(idx++);
12588 int remain = options.Data.Length - idx;
12589
12590 switch (option)
12591 {
12592 case ScriptBaseClass.KFM_MODE:
12593 if (remain < 1)
12594 break;
12595 int modeval = (int)options.GetLSLIntegerItem(idx++);
12596 switch(modeval)
12597 {
12598 case ScriptBaseClass.KFM_FORWARD:
12599 mode = KeyframeMotion.PlayMode.Forward;
12600 break;
12601 case ScriptBaseClass.KFM_REVERSE:
12602 mode = KeyframeMotion.PlayMode.Reverse;
12603 break;
12604 case ScriptBaseClass.KFM_LOOP:
12605 mode = KeyframeMotion.PlayMode.Loop;
12606 break;
12607 case ScriptBaseClass.KFM_PING_PONG:
12608 mode = KeyframeMotion.PlayMode.PingPong;
12609 break;
12610 }
12611 break;
12612 case ScriptBaseClass.KFM_DATA:
12613 if (remain < 1)
12614 break;
12615 int dataval = (int)options.GetLSLIntegerItem(idx++);
12616 data = (KeyframeMotion.DataFormat)dataval;
12617 break;
12618 }
12619 }
12620
12621 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12622
12623 idx = 0;
12624
12625 int elemLength = 2;
12626 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12627 elemLength = 3;
12628
12629 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12630 while (idx < frames.Data.Length)
12631 {
12632 int remain = frames.Data.Length - idx;
12633
12634 if (remain < elemLength)
12635 break;
12636
12637 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12638 frame.Position = null;
12639 frame.Rotation = null;
12640
12641 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12642 {
12643 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12644 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12645 }
12646 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12647 {
12648 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12649 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12650 }
12651
12652 float tempf = (float)frames.GetLSLFloatItem(idx++);
12653 frame.TimeMS = (int)(tempf * 1000.0f);
12654
12655 keyframes.Add(frame);
12656 }
12657
12658 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12659 group.RootPart.KeyframeMotion.Start();
12660 }
12661 else
12662 {
12663 if (group.RootPart.KeyframeMotion == null)
12664 return;
12665
12666 if (options.Data.Length == 0)
12667 {
12668 group.RootPart.KeyframeMotion.Stop();
12669 return;
12670 }
12671
12672 int code = (int)options.GetLSLIntegerItem(0);
12673
12674 int idx = 0;
12675
12676 while (idx < options.Data.Length)
12677 {
12678 int option = (int)options.GetLSLIntegerItem(idx++);
12679 int remain = options.Data.Length - idx;
12680
12681 switch (option)
12682 {
12683 case ScriptBaseClass.KFM_COMMAND:
12684 int cmd = (int)options.GetLSLIntegerItem(idx++);
12685 switch (cmd)
12686 {
12687 case ScriptBaseClass.KFM_CMD_PLAY:
12688 group.RootPart.KeyframeMotion.Start();
12689 break;
12690 case ScriptBaseClass.KFM_CMD_STOP:
12691 group.RootPart.KeyframeMotion.Stop();
12692 break;
12693 case ScriptBaseClass.KFM_CMD_PAUSE:
12694 group.RootPart.KeyframeMotion.Pause();
12695 break;
12696 }
12697 break;
12698 }
12699 }
12700 }
12701 }
12702
12703 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12704 {
12705 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12706
12707 int idx = 0;
12708 int idxStart = 0;
12709
12710 bool positionChanged = false;
12711 Vector3 finalPos = Vector3.Zero;
12712
12713 try
12714 {
12715 while (idx < rules.Length)
12716 {
12717 ++rulesParsed;
12718 int code = rules.GetLSLIntegerItem(idx++);
12719
12720 int remain = rules.Length - idx;
12721 idxStart = idx;
12722
12723 switch (code)
12724 {
12725 case (int)ScriptBaseClass.PRIM_POSITION:
12726 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12727 {
12728 if (remain < 1)
12729 return null;
12730
12731 LSL_Vector v;
12732 v = rules.GetVector3Item(idx++);
12733
12734 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12735 if (part == null)
12736 break;
12737
12738 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12739 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12740 if (part.LinkNum > 1)
12741 {
12742 localRot = GetPartLocalRot(part);
12743 localPos = GetPartLocalPos(part);
12744 }
12745
12746 v -= localPos;
12747 v /= localRot;
12748
12749 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12750
12751 v = v + 2 * sitOffset;
12752
12753 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12754 av.SendAvatarDataToAllAgents();
12755
12756 }
12757 break;
12758
12759 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12760 case (int)ScriptBaseClass.PRIM_ROTATION:
12761 {
12762 if (remain < 1)
12763 return null;
12764
12765 LSL_Rotation r;
12766 r = rules.GetQuaternionItem(idx++);
12767
12768 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12769 if (part == null)
12770 break;
12771
12772 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12773 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12774
12775 if (part.LinkNum > 1)
12776 localRot = GetPartLocalRot(part);
12777
12778 r = r * llGetRootRotation() / localRot;
12779 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12780 av.SendAvatarDataToAllAgents();
12781 }
12782 break;
12783
12784 // parse rest doing nothing but number of parameters error check
12785 case (int)ScriptBaseClass.PRIM_SIZE:
12786 case (int)ScriptBaseClass.PRIM_MATERIAL:
12787 case (int)ScriptBaseClass.PRIM_PHANTOM:
12788 case (int)ScriptBaseClass.PRIM_PHYSICS:
12789 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12790 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12791 case (int)ScriptBaseClass.PRIM_NAME:
12792 case (int)ScriptBaseClass.PRIM_DESC:
12793 if (remain < 1)
12794 return null;
12795 idx++;
12796 break;
12797
12798 case (int)ScriptBaseClass.PRIM_GLOW:
12799 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12800 case (int)ScriptBaseClass.PRIM_TEXGEN:
12801 if (remain < 2)
12802 return null;
12803 idx += 2;
12804 break;
12805
12806 case (int)ScriptBaseClass.PRIM_TYPE:
12807 if (remain < 3)
12808 return null;
12809 code = (int)rules.GetLSLIntegerItem(idx++);
12810 remain = rules.Length - idx;
12811 switch (code)
12812 {
12813 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12814 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12815 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12816 if (remain < 6)
12817 return null;
12818 idx += 6;
12819 break;
12820
12821 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12822 if (remain < 5)
12823 return null;
12824 idx += 5;
12825 break;
12826
12827 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12828 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12829 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12830 if (remain < 11)
12831 return null;
12832 idx += 11;
12833 break;
12834
12835 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12836 if (remain < 2)
12837 return null;
12838 idx += 2;
12839 break;
12840 }
12841 break;
12842
12843 case (int)ScriptBaseClass.PRIM_COLOR:
12844 case (int)ScriptBaseClass.PRIM_TEXT:
12845 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12846 case (int)ScriptBaseClass.PRIM_OMEGA:
12847 if (remain < 3)
12848 return null;
12849 idx += 3;
12850 break;
12851
12852 case (int)ScriptBaseClass.PRIM_TEXTURE:
12853 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12854 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12855 if (remain < 5)
12856 return null;
12857 idx += 5;
12858 break;
12859
12860 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12861 if (remain < 7)
12862 return null;
12863
12864 idx += 7;
12865 break;
12866
12867 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12868 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12869 return null;
12870
12871 return rules.GetSublist(idx, -1);
12872 }
12873 }
12874 }
12875 catch (InvalidCastException e)
12876 {
12877 ShoutError(string.Format(
12878 "{0} error running rule #{1}: arg #{2} ",
12879 originFunc, rulesParsed, idx - idxStart) + e.Message);
12880 }
12881 finally
12882 {
12883 if (positionChanged)
12884 {
12885 av.OffsetPosition = finalPos;
12886// av.SendAvatarDataToAllAgents();
12887 av.SendTerseUpdateToAllClients();
12888 positionChanged = false;
12889 }
12890 }
12891 return null;
12892 }
12893
12894 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12895 {
12896 // avatars case
12897 // replies as SL wiki
12898
12899// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12900 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12901
12902 int idx = 0;
12903 while (idx < rules.Length)
12904 {
12905 int code = (int)rules.GetLSLIntegerItem(idx++);
12906 int remain = rules.Length - idx;
12907
12908 switch (code)
12909 {
12910 case (int)ScriptBaseClass.PRIM_MATERIAL:
12911 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12912 break;
12913
12914 case (int)ScriptBaseClass.PRIM_PHYSICS:
12915 res.Add(new LSL_Integer(0));
12916 break;
12917
12918 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12919 res.Add(new LSL_Integer(0));
12920 break;
12921
12922 case (int)ScriptBaseClass.PRIM_PHANTOM:
12923 res.Add(new LSL_Integer(0));
12924 break;
12925
12926 case (int)ScriptBaseClass.PRIM_POSITION:
12927
12928 Vector3 pos = avatar.OffsetPosition;
12929
12930 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12931 pos -= sitOffset;
12932
12933 if( sitPart != null)
12934 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12935
12936 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12937 break;
12938
12939 case (int)ScriptBaseClass.PRIM_SIZE:
12940 // as in llGetAgentSize above
12941 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12942 break;
12943
12944 case (int)ScriptBaseClass.PRIM_ROTATION:
12945 Quaternion rot = avatar.Rotation;
12946 if (sitPart != null)
12947 {
12948 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12949 }
12950
12951 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12952 break;
12953
12954 case (int)ScriptBaseClass.PRIM_TYPE:
12955 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12956 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12957 res.Add(new LSL_Vector(0f,1.0f,0f));
12958 res.Add(new LSL_Float(0.0f));
12959 res.Add(new LSL_Vector(0, 0, 0));
12960 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12961 res.Add(new LSL_Vector(0, 0, 0));
12962 break;
12963
12964 case (int)ScriptBaseClass.PRIM_TEXTURE:
12965 if (remain < 1)
12966 return null;
12967
12968 int face = (int)rules.GetLSLIntegerItem(idx++);
12969 if (face == ScriptBaseClass.ALL_SIDES)
12970 {
12971 for (face = 0; face < 21; face++)
12972 {
12973 res.Add(new LSL_String(""));
12974 res.Add(new LSL_Vector(0,0,0));
12975 res.Add(new LSL_Vector(0,0,0));
12976 res.Add(new LSL_Float(0.0));
12977 }
12978 }
12979 else
12980 {
12981 if (face >= 0 && face < 21)
12982 {
12983 res.Add(new LSL_String(""));
12984 res.Add(new LSL_Vector(0,0,0));
12985 res.Add(new LSL_Vector(0,0,0));
12986 res.Add(new LSL_Float(0.0));
12987 }
12988 }
12989 break;
12990
12991 case (int)ScriptBaseClass.PRIM_COLOR:
12992 if (remain < 1)
12993 return null;
12994
12995 face = (int)rules.GetLSLIntegerItem(idx++);
12996
12997 if (face == ScriptBaseClass.ALL_SIDES)
12998 {
12999 for (face = 0; face < 21; face++)
13000 {
13001 res.Add(new LSL_Vector(0,0,0));
13002 res.Add(new LSL_Float(0));
13003 }
13004 }
13005 else
13006 {
13007 res.Add(new LSL_Vector(0,0,0));
13008 res.Add(new LSL_Float(0));
13009 }
13010 break;
13011
13012 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13013 if (remain < 1)
13014 return null;
13015 face = (int)rules.GetLSLIntegerItem(idx++);
13016
13017 if (face == ScriptBaseClass.ALL_SIDES)
13018 {
13019 for (face = 0; face < 21; face++)
13020 {
13021 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13022 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13023 }
13024 }
13025 else
13026 {
13027 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13028 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13029 }
13030 break;
13031
13032 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13033 if (remain < 1)
13034 return null;
13035 face = (int)rules.GetLSLIntegerItem(idx++);
13036
13037 if (face == ScriptBaseClass.ALL_SIDES)
13038 {
13039 for (face = 0; face < 21; face++)
13040 {
13041 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13042 }
13043 }
13044 else
13045 {
13046 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13047 }
13048 break;
13049
13050 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13051 res.Add(new LSL_Integer(0));
13052 res.Add(new LSL_Integer(0));// softness
13053 res.Add(new LSL_Float(0.0f)); // gravity
13054 res.Add(new LSL_Float(0.0f)); // friction
13055 res.Add(new LSL_Float(0.0f)); // wind
13056 res.Add(new LSL_Float(0.0f)); // tension
13057 res.Add(new LSL_Vector(0f,0f,0f));
13058 break;
13059
13060 case (int)ScriptBaseClass.PRIM_TEXGEN:
13061 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13062 if (remain < 1)
13063 return null;
13064 face = (int)rules.GetLSLIntegerItem(idx++);
13065
13066 if (face == ScriptBaseClass.ALL_SIDES)
13067 {
13068 for (face = 0; face < 21; face++)
13069 {
13070 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13071 }
13072 }
13073 else
13074 {
13075 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13076 }
13077 break;
13078
13079 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13080 res.Add(new LSL_Integer(0));
13081 res.Add(new LSL_Vector(0f,0f,0f));
13082 res.Add(new LSL_Float(0f)); // intensity
13083 res.Add(new LSL_Float(0f)); // radius
13084 res.Add(new LSL_Float(0f)); // falloff
13085 break;
13086
13087 case (int)ScriptBaseClass.PRIM_GLOW:
13088 if (remain < 1)
13089 return null;
13090 face = (int)rules.GetLSLIntegerItem(idx++);
13091
13092 if (face == ScriptBaseClass.ALL_SIDES)
13093 {
13094 for (face = 0; face < 21; face++)
13095 {
13096 res.Add(new LSL_Float(0f));
13097 }
13098 }
13099 else
13100 {
13101 res.Add(new LSL_Float(0f));
13102 }
13103 break;
13104
13105 case (int)ScriptBaseClass.PRIM_TEXT:
13106 res.Add(new LSL_String(""));
13107 res.Add(new LSL_Vector(0f,0f,0f));
13108 res.Add(new LSL_Float(1.0f));
13109 break;
13110
13111 case (int)ScriptBaseClass.PRIM_NAME:
13112 res.Add(new LSL_String(avatar.Name));
13113 break;
13114
13115 case (int)ScriptBaseClass.PRIM_DESC:
13116 res.Add(new LSL_String(""));
13117 break;
13118
13119 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13120 Quaternion lrot = avatar.Rotation;
13121
13122 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13123 {
13124 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13125 }
13126 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13127 break;
13128
13129 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13130 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13131 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13132 lpos -= lsitOffset;
13133
13134 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13135 {
13136 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13137 }
13138 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13139 break;
13140
13141 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13142 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13143 return null;
13144
13145 return rules.GetSublist(idx, -1);
13146 }
13147 }
13148
13149 return null;
13150 }
11460 } 13151 }
11461 13152
11462 public class NotecardCache 13153 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 828288d..51c8c7e 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);
@@ -1814,6 +1823,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1814 1823
1815 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1824 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1816 { 1825 {
1826 m_host.TaskInventory.LockItemsForRead(true);
1817 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1827 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1818 { 1828 {
1819 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1829 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1821,6 +1831,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1821 assetID = item.AssetID; 1831 assetID = item.AssetID;
1822 } 1832 }
1823 } 1833 }
1834 m_host.TaskInventory.LockItemsForRead(false);
1824 } 1835 }
1825 1836
1826 if (assetID == UUID.Zero) 1837 if (assetID == UUID.Zero)
@@ -2306,7 +2317,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2306 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2317 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2307 m_host.AddScriptLPS(1); 2318 m_host.AddScriptLPS(1);
2308 2319
2309 return NpcCreate(firstname, lastname, position, notecard, false, false); 2320 return NpcCreate(firstname, lastname, position, notecard, true, false);
2310 } 2321 }
2311 2322
2312 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2323 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2317,24 +2328,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2317 return NpcCreate( 2328 return NpcCreate(
2318 firstname, lastname, position, notecard, 2329 firstname, lastname, position, notecard,
2319 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2330 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2320 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2331 false);
2332// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2321 } 2333 }
2322 2334
2323 private LSL_Key NpcCreate( 2335 private LSL_Key NpcCreate(
2324 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2336 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2325 { 2337 {
2338 if (!owned)
2339 OSSLError("Unowned NPCs are unsupported");
2340
2341 string groupTitle = String.Empty;
2342
2343 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2344 return new LSL_Key(UUID.Zero.ToString());
2345
2346 if (firstname != String.Empty || lastname != String.Empty)
2347 {
2348 if (firstname != "Shown outfit:")
2349 groupTitle = "- NPC -";
2350 }
2351
2326 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2352 INPCModule module = World.RequestModuleInterface<INPCModule>();
2327 if (module != null) 2353 if (module != null)
2328 { 2354 {
2329 AvatarAppearance appearance = null; 2355 AvatarAppearance appearance = null;
2330 2356
2331 UUID id; 2357// UUID id;
2332 if (UUID.TryParse(notecard, out id)) 2358// if (UUID.TryParse(notecard, out id))
2333 { 2359// {
2334 ScenePresence clonePresence = World.GetScenePresence(id); 2360// ScenePresence clonePresence = World.GetScenePresence(id);
2335 if (clonePresence != null) 2361// if (clonePresence != null)
2336 appearance = clonePresence.Appearance; 2362// appearance = clonePresence.Appearance;
2337 } 2363// }
2338 2364
2339 if (appearance == null) 2365 if (appearance == null)
2340 { 2366 {
@@ -2342,9 +2368,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2342 2368
2343 if (appearanceSerialized != null) 2369 if (appearanceSerialized != null)
2344 { 2370 {
2345 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2371 try
2346 appearance = new AvatarAppearance(); 2372 {
2347 appearance.Unpack(appearanceOsd); 2373 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2374 appearance = new AvatarAppearance();
2375 appearance.Unpack(appearanceOsd);
2376 }
2377 catch
2378 {
2379 return UUID.Zero.ToString();
2380 }
2348 } 2381 }
2349 else 2382 else
2350 { 2383 {
@@ -2363,6 +2396,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2363 World, 2396 World,
2364 appearance); 2397 appearance);
2365 2398
2399 ScenePresence sp;
2400 if (World.TryGetScenePresence(x, out sp))
2401 {
2402 sp.Grouptitle = groupTitle;
2403 sp.SendAvatarDataToAllAgents();
2404 }
2366 return new LSL_Key(x.ToString()); 2405 return new LSL_Key(x.ToString());
2367 } 2406 }
2368 2407
@@ -2666,16 +2705,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2666 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2705 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2667 m_host.AddScriptLPS(1); 2706 m_host.AddScriptLPS(1);
2668 2707
2669 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2708 ManualResetEvent ev = new ManualResetEvent(false);
2670 if (module != null)
2671 {
2672 UUID npcId = new UUID(npc.m_string);
2673 2709
2674 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2710 Util.FireAndForget(delegate(object x) {
2675 return; 2711 try
2712 {
2713 INPCModule module = World.RequestModuleInterface<INPCModule>();
2714 if (module != null)
2715 {
2716 UUID npcId = new UUID(npc.m_string);
2676 2717
2677 module.DeleteNPC(npcId, World); 2718 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2678 } 2719 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2720 {
2721 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2722 return;
2723 }
2724
2725 module.DeleteNPC(npcId, World);
2726 }
2727 }
2728 finally
2729 {
2730 ev.Set();
2731 }
2732 });
2733 ev.WaitOne();
2679 } 2734 }
2680 2735
2681 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2736 public void osNpcPlayAnimation(LSL_Key npc, string animation)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 24cceea..4dd795d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -70,7 +70,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
70 private const int AGENT = 1; 70 private const int AGENT = 1;
71 private const int AGENT_BY_USERNAME = 0x10; 71 private const int AGENT_BY_USERNAME = 0x10;
72 private const int NPC = 0x20; 72 private const int NPC = 0x20;
73 private const int OS_NPC = 0x01000000;
74 private const int ACTIVE = 2; 73 private const int ACTIVE = 2;
75 private const int PASSIVE = 4; 74 private const int PASSIVE = 4;
76 private const int SCRIPTED = 8; 75 private const int SCRIPTED = 8;
@@ -235,7 +234,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
235 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 234 List<SensedEntity> sensedEntities = new List<SensedEntity>();
236 235
237 // Is the sensor type is AGENT and not SCRIPTED then include agents 236 // Is the sensor type is AGENT and not SCRIPTED then include agents
238 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 237 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
239 { 238 {
240 sensedEntities.AddRange(doAgentSensor(ts)); 239 sensedEntities.AddRange(doAgentSensor(ts));
241 } 240 }
@@ -334,7 +333,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
334 float dy; 333 float dy;
335 float dz; 334 float dz;
336 335
337 Quaternion q = SensePoint.GetWorldRotation(); 336// Quaternion q = SensePoint.RotationOffset;
337 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
338 if (SensePoint.ParentGroup.IsAttachment) 338 if (SensePoint.ParentGroup.IsAttachment)
339 { 339 {
340 // In attachments, rotate the sensor cone with the 340 // In attachments, rotate the sensor cone with the
@@ -348,7 +348,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
348 // Position of a sensor in a child prim attached to an avatar 348 // Position of a sensor in a child prim attached to an avatar
349 // will be still wrong. 349 // will be still wrong.
350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
351 q = avatar.Rotation * q; 351 fromRegionPos = avatar.AbsolutePosition;
352 q = avatar.Rotation;
352 } 353 }
353 354
354 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -475,7 +476,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
475 // Position of a sensor in a child prim attached to an avatar 476 // Position of a sensor in a child prim attached to an avatar
476 // will be still wrong. 477 // will be still wrong.
477 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 478 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
478 q = avatar.Rotation * q; 479 if (avatar == null)
480 return sensedEntities;
481 fromRegionPos = avatar.AbsolutePosition;
482 q = avatar.Rotation;
479 } 483 }
480 484
481 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 485 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -491,7 +495,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
491// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 495// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
492// presence.Name, presence.PresenceType, ts.name, ts.type); 496// presence.Name, presence.PresenceType, ts.name, ts.type);
493 497
494 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 498 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
495 { 499 {
496 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 500 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
497 if (npcData == null || !npcData.SenseAsAgent) 501 if (npcData == null || !npcData.SenseAsAgent)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index bc63030..9ee6946 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -118,25 +118,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
118 if (Timers.Count == 0) 118 if (Timers.Count == 0)
119 return; 119 return;
120 120
121 Dictionary<string, TimerClass>.ValueCollection tvals;
121 lock (TimerListLock) 122 lock (TimerListLock)
122 { 123 {
123 // Go through all timers 124 // Go through all timers
124 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 125 tvals = Timers.Values;
125 foreach (TimerClass ts in tvals) 126 }
127
128 foreach (TimerClass ts in tvals)
129 {
130 // Time has passed?
131 if (ts.next < DateTime.Now.Ticks)
126 { 132 {
127 // Time has passed? 133 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
128 if (ts.next < DateTime.Now.Ticks) 134 // Add it to queue
129 { 135 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
130 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 136 new EventParams("timer", new Object[0],
131 // Add it to queue 137 new DetectParams[0]));
132 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 138 // set next interval
133 new EventParams("timer", new Object[0], 139
134 new DetectParams[0])); 140 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 // set next interval 141 ts.next = DateTime.Now.Ticks + ts.interval;
136
137 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
138 ts.next = DateTime.Now.Ticks + ts.interval;
139 }
140 } 142 }
141 } 143 }
142 } 144 }