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.cs3163
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs105
-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, 2667 insertions, 785 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 52d96bc..8d06d83 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;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -103,15 +107,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
103 protected int m_notecardLineReadCharsMax = 255; 107 protected int m_notecardLineReadCharsMax = 255;
104 protected int m_scriptConsoleChannel = 0; 108 protected int m_scriptConsoleChannel = 0;
105 protected bool m_scriptConsoleChannelEnabled = false; 109 protected bool m_scriptConsoleChannelEnabled = false;
110 protected bool m_debuggerSafe = false;
106 protected IUrlModule m_UrlModule = null; 111 protected IUrlModule m_UrlModule = null;
107 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 112 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
108 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 113 new Dictionary<UUID, UserInfoCacheEntry>();
114 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
115
116// protected Timer m_ShoutSayTimer;
117 protected int m_SayShoutCount = 0;
118 DateTime m_lastSayShoutCheck;
119
120 private Dictionary<string, string> MovementAnimationsForLSL =
121 new Dictionary<string, string> {
122 {"FLY", "Flying"},
123 {"FLYSLOW", "FlyingSlow"},
124 {"HOVER_UP", "Hovering Up"},
125 {"HOVER_DOWN", "Hovering Down"},
126 {"HOVER", "Hovering"},
127 {"LAND", "Landing"},
128 {"FALLDOWN", "Falling Down"},
129 {"PREJUMP", "PreJumping"},
130 {"JUMP", "Jumping"},
131 {"STANDUP", "Standing Up"},
132 {"SOFT_LAND", "Soft Landing"},
133 {"STAND", "Standing"},
134 {"CROUCHWALK", "CrouchWalking"},
135 {"RUN", "Running"},
136 {"WALK", "Walking"},
137 {"CROUCH", "Crouching"},
138 {"TURNLEFT", "Turning Left"},
139 {"TURNRIGHT", "Turning Right"}
140 };
109 141
110 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
111 { 143 {
144/*
145 m_ShoutSayTimer = new Timer(1000);
146 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
147 m_ShoutSayTimer.AutoReset = true;
148 m_ShoutSayTimer.Start();
149*/
150 m_lastSayShoutCheck = DateTime.UtcNow;
151
112 m_ScriptEngine = ScriptEngine; 152 m_ScriptEngine = ScriptEngine;
113 m_host = host; 153 m_host = host;
114 m_item = item; 154 m_item = item;
155 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
115 156
116 LoadLimits(); // read script limits from config. 157 LoadLimits(); // read script limits from config.
117 158
@@ -171,6 +212,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
171 get { return m_ScriptEngine.World; } 212 get { return m_ScriptEngine.World; }
172 } 213 }
173 214
215 [DebuggerNonUserCode]
174 public void state(string newState) 216 public void state(string newState)
175 { 217 {
176 m_ScriptEngine.SetState(m_item.ItemID, newState); 218 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -180,6 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
180 /// Reset the named script. The script must be present 222 /// Reset the named script. The script must be present
181 /// in the same prim. 223 /// in the same prim.
182 /// </summary> 224 /// </summary>
225 [DebuggerNonUserCode]
183 public void llResetScript() 226 public void llResetScript()
184 { 227 {
185 m_host.AddScriptLPS(1); 228 m_host.AddScriptLPS(1);
@@ -242,6 +285,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
242 } 285 }
243 } 286 }
244 287
288 public List<ScenePresence> GetLinkAvatars(int linkType)
289 {
290 List<ScenePresence> ret = new List<ScenePresence>();
291 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
292 return ret;
293
294 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
295
296 switch (linkType)
297 {
298 case ScriptBaseClass.LINK_SET:
299 return avs;
300
301 case ScriptBaseClass.LINK_ROOT:
302 return ret;
303
304 case ScriptBaseClass.LINK_ALL_OTHERS:
305 return avs;
306
307 case ScriptBaseClass.LINK_ALL_CHILDREN:
308 return avs;
309
310 case ScriptBaseClass.LINK_THIS:
311 return ret;
312
313 default:
314 if (linkType < 0)
315 return ret;
316
317 int partCount = m_host.ParentGroup.GetPartCount();
318
319 if (linkType <= partCount)
320 {
321 return ret;
322 }
323 else
324 {
325 linkType = linkType - partCount;
326 if (linkType > avs.Count)
327 {
328 return ret;
329 }
330 else
331 {
332 ret.Add(avs[linkType-1]);
333 return ret;
334 }
335 }
336 }
337 }
338
245 public List<SceneObjectPart> GetLinkParts(int linkType) 339 public List<SceneObjectPart> GetLinkParts(int linkType)
246 { 340 {
247 return GetLinkParts(m_host, linkType); 341 return GetLinkParts(m_host, linkType);
@@ -250,6 +344,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
250 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 344 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
251 { 345 {
252 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 346 List<SceneObjectPart> ret = new List<SceneObjectPart>();
347 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
348 return ret;
253 ret.Add(part); 349 ret.Add(part);
254 350
255 switch (linkType) 351 switch (linkType)
@@ -440,31 +536,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
440 536
441 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 537 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
442 538
443 /// <summary> 539 // Utility function for llRot2Euler
444 /// Convert an LSL rotation to a Euler vector. 540
445 /// </summary> 541 // normalize an angle between -PI and PI (-180 to +180 degrees)
446 /// <remarks> 542 protected double NormalizeAngle(double angle)
447 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
448 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
449 /// </remarks>
450 /// <param name="r"></param>
451 /// <returns></returns>
452 public LSL_Vector llRot2Euler(LSL_Rotation r)
453 { 543 {
454 m_host.AddScriptLPS(1); 544 if (angle > -Math.PI && angle < Math.PI)
545 return angle;
455 546
456 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 547 int numPis = (int)(Math.PI / angle);
457 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 548 double remainder = angle - Math.PI * numPis;
458 if (m == 0.0) return new LSL_Vector(); 549 if (numPis % 2 == 1)
459 double x = Math.Atan2(-v.y, v.z); 550 return Math.PI - angle;
460 double sin = v.x / m; 551 return remainder;
461 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 552 }
462 double y = Math.Asin(sin);
463 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
464 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)));
465 double z = Math.Atan2(v.y, v.x);
466 553
467 return new LSL_Vector(x, y, z); 554 public LSL_Vector llRot2Euler(LSL_Rotation q1)
555 {
556 m_host.AddScriptLPS(1);
557 LSL_Vector eul = new LSL_Vector();
558
559 double sqw = q1.s*q1.s;
560 double sqx = q1.x*q1.x;
561 double sqy = q1.z*q1.z;
562 double sqz = q1.y*q1.y;
563 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
564 double test = q1.x*q1.z + q1.y*q1.s;
565 if (test > 0.4999*unit) { // singularity at north pole
566 eul.z = 2 * Math.Atan2(q1.x,q1.s);
567 eul.y = Math.PI/2;
568 eul.x = 0;
569 return eul;
570 }
571 if (test < -0.4999*unit) { // singularity at south pole
572 eul.z = -2 * Math.Atan2(q1.x,q1.s);
573 eul.y = -Math.PI/2;
574 eul.x = 0;
575 return eul;
576 }
577 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
578 eul.y = Math.Asin(2*test/unit);
579 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
580 return eul;
468 } 581 }
469 582
470 /* From wiki: 583 /* From wiki:
@@ -517,18 +630,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
517 m_host.AddScriptLPS(1); 630 m_host.AddScriptLPS(1);
518 631
519 double x,y,z,s; 632 double x,y,z,s;
520 633 v.x *= 0.5;
521 double c1 = Math.Cos(v.x * 0.5); 634 v.y *= 0.5;
522 double c2 = Math.Cos(v.y * 0.5); 635 v.z *= 0.5;
523 double c3 = Math.Cos(v.z * 0.5); 636 double c1 = Math.Cos(v.x);
524 double s1 = Math.Sin(v.x * 0.5); 637 double c2 = Math.Cos(v.y);
525 double s2 = Math.Sin(v.y * 0.5); 638 double c1c2 = c1 * c2;
526 double s3 = Math.Sin(v.z * 0.5); 639 double s1 = Math.Sin(v.x);
527 640 double s2 = Math.Sin(v.y);
528 x = s1 * c2 * c3 + c1 * s2 * s3; 641 double s1s2 = s1 * s2;
529 y = c1 * s2 * c3 - s1 * c2 * s3; 642 double c1s2 = c1 * s2;
530 z = s1 * s2 * c3 + c1 * c2 * s3; 643 double s1c2 = s1 * c2;
531 s = c1 * c2 * c3 - s1 * s2 * s3; 644 double c3 = Math.Cos(v.z);
645 double s3 = Math.Sin(v.z);
646
647 x = s1c2 * c3 + c1s2 * s3;
648 y = c1s2 * c3 - s1c2 * s3;
649 z = s1s2 * c3 + c1c2 * s3;
650 s = c1c2 * c3 - s1s2 * s3;
532 651
533 return new LSL_Rotation(x, y, z, s); 652 return new LSL_Rotation(x, y, z, s);
534 } 653 }
@@ -666,77 +785,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
666 { 785 {
667 //A and B should both be normalized 786 //A and B should both be normalized
668 m_host.AddScriptLPS(1); 787 m_host.AddScriptLPS(1);
669 LSL_Rotation rotBetween; 788 /* This method is more accurate than the SL one, and thus causes problems
670 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 789 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
671 // continue calculation. 790
672 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 791 double dotProduct = LSL_Vector.Dot(a, b);
792 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
793 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
794 double angle = Math.Acos(dotProduct / magProduct);
795 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
796 double s = Math.Sin(angle / 2);
797
798 double x = axis.x * s;
799 double y = axis.y * s;
800 double z = axis.z * s;
801 double w = Math.Cos(angle / 2);
802
803 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
804 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
805
806 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
807 */
808
809 // This method mimics the 180 errors found in SL
810 // See www.euclideanspace.com... angleBetween
811 LSL_Vector vec_a = a;
812 LSL_Vector vec_b = b;
813
814 // Eliminate zero length
815 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
816 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
817 if (vec_a_mag < 0.00001 ||
818 vec_b_mag < 0.00001)
673 { 819 {
674 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 820 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
675 } 821 }
676 else 822
823 // Normalize
824 vec_a = llVecNorm(vec_a);
825 vec_b = llVecNorm(vec_b);
826
827 // Calculate axis and rotation angle
828 LSL_Vector axis = vec_a % vec_b;
829 LSL_Float cos_theta = vec_a * vec_b;
830
831 // Check if parallel
832 if (cos_theta > 0.99999)
677 { 833 {
678 a = LSL_Vector.Norm(a); 834 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
679 b = LSL_Vector.Norm(b); 835 }
680 double dotProduct = LSL_Vector.Dot(a, b); 836
681 // There are two degenerate cases possible. These are for vectors 180 or 837 // Check if anti-parallel
682 // 0 degrees apart. These have to be detected and handled individually. 838 else if (cos_theta < -0.99999)
683 // 839 {
684 // Check for vectors 180 degrees apart. 840 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
685 // A dot product of -1 would mean the angle between vectors is 180 degrees. 841 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
686 if (dotProduct < -0.9999999f) 842 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
687 { 843 }
688 // First assume X axis is orthogonal to the vectors. 844 else // other rotation
689 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 845 {
690 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 846 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
691 // Check for near zero vector. A very small non-zero number here will create 847 axis = llVecNorm(axis);
692 // a rotation in an undesired direction. 848 double x, y, z, s, t;
693 if (LSL_Vector.Mag(orthoVector) > 0.0001) 849 s = Math.Cos(theta);
694 { 850 t = Math.Sin(theta);
695 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 851 x = axis.x * t;
696 } 852 y = axis.y * t;
697 // If the magnitude of the vector was near zero, then assume the X axis is not 853 z = axis.z * t;
698 // orthogonal and use the Z axis instead. 854 return new LSL_Rotation(x,y,z,s);
699 else
700 {
701 // Set 180 z rotation.
702 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
703 }
704 }
705 // Check for parallel vectors.
706 // A dot product of 1 would mean the angle between vectors is 0 degrees.
707 else if (dotProduct > 0.9999999f)
708 {
709 // Set zero rotation.
710 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
711 }
712 else
713 {
714 // All special checks have been performed so get the axis of rotation.
715 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
716 // Quarternion s value is the length of the unit vector + dot product.
717 double qs = 1.0 + dotProduct;
718 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
719 // Normalize the rotation.
720 double mag = LSL_Rotation.Mag(rotBetween);
721 // We shouldn't have to worry about a divide by zero here. The qs value will be
722 // non-zero because we already know if we're here, then the dotProduct is not -1 so
723 // qs will not be zero. Also, we've already handled the input vectors being zero so the
724 // crossProduct vector should also not be zero.
725 rotBetween.x = rotBetween.x / mag;
726 rotBetween.y = rotBetween.y / mag;
727 rotBetween.z = rotBetween.z / mag;
728 rotBetween.s = rotBetween.s / mag;
729 // Check for undefined values and set zero rotation if any found. This code might not actually be required
730 // any longer since zero vectors are checked for at the top.
731 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
732 {
733 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
734 }
735 }
736 } 855 }
737 return rotBetween;
738 } 856 }
739 857
740 public void llWhisper(int channelID, string text) 858 public void llWhisper(int channelID, string text)
741 { 859 {
742 m_host.AddScriptLPS(1); 860 m_host.AddScriptLPS(1);
@@ -752,10 +870,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
752 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 870 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
753 } 871 }
754 872
873 private void CheckSayShoutTime()
874 {
875 DateTime now = DateTime.UtcNow;
876 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
877 {
878 m_lastSayShoutCheck = now;
879 m_SayShoutCount = 0;
880 }
881 else
882 m_SayShoutCount++;
883 }
884
755 public void llSay(int channelID, string text) 885 public void llSay(int channelID, string text)
756 { 886 {
757 m_host.AddScriptLPS(1); 887 m_host.AddScriptLPS(1);
758 888
889 if (channelID == 0)
890// m_SayShoutCount++;
891 CheckSayShoutTime();
892
893 if (m_SayShoutCount >= 11)
894 ScriptSleep(2000);
895
759 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 896 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
760 { 897 {
761 Console.WriteLine(text); 898 Console.WriteLine(text);
@@ -778,6 +915,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
778 { 915 {
779 m_host.AddScriptLPS(1); 916 m_host.AddScriptLPS(1);
780 917
918 if (channelID == 0)
919// m_SayShoutCount++;
920 CheckSayShoutTime();
921
922 if (m_SayShoutCount >= 11)
923 ScriptSleep(2000);
924
781 if (text.Length > 1023) 925 if (text.Length > 1023)
782 text = text.Substring(0, 1023); 926 text = text.Substring(0, 1023);
783 927
@@ -809,22 +953,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
809 953
810 public void llRegionSayTo(string target, int channel, string msg) 954 public void llRegionSayTo(string target, int channel, string msg)
811 { 955 {
956 string error = String.Empty;
957
812 if (msg.Length > 1023) 958 if (msg.Length > 1023)
813 msg = msg.Substring(0, 1023); 959 msg = msg.Substring(0, 1023);
814 960
815 m_host.AddScriptLPS(1); 961 m_host.AddScriptLPS(1);
816 962
817 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
818 {
819 return;
820 }
821
822 UUID TargetID; 963 UUID TargetID;
823 UUID.TryParse(target, out TargetID); 964 UUID.TryParse(target, out TargetID);
824 965
825 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 966 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
826 if (wComm != null) 967 if (wComm != null)
827 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 968 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
969 LSLError(error);
828 } 970 }
829 971
830 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 972 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1080,10 +1222,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1080 return detectedParams.TouchUV; 1222 return detectedParams.TouchUV;
1081 } 1223 }
1082 1224
1225 [DebuggerNonUserCode]
1083 public virtual void llDie() 1226 public virtual void llDie()
1084 { 1227 {
1085 m_host.AddScriptLPS(1); 1228 m_host.AddScriptLPS(1);
1086 throw new SelfDeleteException(); 1229 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1087 } 1230 }
1088 1231
1089 public LSL_Float llGround(LSL_Vector offset) 1232 public LSL_Float llGround(LSL_Vector offset)
@@ -1154,6 +1297,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1154 1297
1155 public void llSetStatus(int status, int value) 1298 public void llSetStatus(int status, int value)
1156 { 1299 {
1300 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1301 return;
1157 m_host.AddScriptLPS(1); 1302 m_host.AddScriptLPS(1);
1158 1303
1159 int statusrotationaxis = 0; 1304 int statusrotationaxis = 0;
@@ -1177,6 +1322,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 if (!allow) 1322 if (!allow)
1178 return; 1323 return;
1179 1324
1325 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1326 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1327 return;
1328
1180 m_host.ScriptSetPhysicsStatus(true); 1329 m_host.ScriptSetPhysicsStatus(true);
1181 } 1330 }
1182 else 1331 else
@@ -1376,6 +1525,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1376 { 1525 {
1377 m_host.AddScriptLPS(1); 1526 m_host.AddScriptLPS(1);
1378 1527
1528 SetColor(m_host, color, face);
1529 }
1530
1531 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1532 {
1533 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1534 return;
1535
1536 Primitive.TextureEntry tex = part.Shape.Textures;
1537 Color4 texcolor;
1538 if (face >= 0 && face < GetNumberOfSides(part))
1539 {
1540 texcolor = tex.CreateFace((uint)face).RGBA;
1541 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1542 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1543 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1544 tex.FaceTextures[face].RGBA = texcolor;
1545 part.UpdateTextureEntry(tex.GetBytes());
1546 return;
1547 }
1548 else if (face == ScriptBaseClass.ALL_SIDES)
1549 {
1550 for (uint i = 0; i < GetNumberOfSides(part); i++)
1551 {
1552 if (tex.FaceTextures[i] != null)
1553 {
1554 texcolor = tex.FaceTextures[i].RGBA;
1555 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1556 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1557 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1558 tex.FaceTextures[i].RGBA = texcolor;
1559 }
1560 texcolor = tex.DefaultTexture.RGBA;
1561 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1562 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1563 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1564 tex.DefaultTexture.RGBA = texcolor;
1565 }
1566 part.UpdateTextureEntry(tex.GetBytes());
1567 return;
1568 }
1569
1379 if (face == ScriptBaseClass.ALL_SIDES) 1570 if (face == ScriptBaseClass.ALL_SIDES)
1380 face = SceneObjectPart.ALL_SIDES; 1571 face = SceneObjectPart.ALL_SIDES;
1381 1572
@@ -1384,6 +1575,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1384 1575
1385 public void SetTexGen(SceneObjectPart part, int face,int style) 1576 public void SetTexGen(SceneObjectPart part, int face,int style)
1386 { 1577 {
1578 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1579 return;
1580
1387 Primitive.TextureEntry tex = part.Shape.Textures; 1581 Primitive.TextureEntry tex = part.Shape.Textures;
1388 MappingType textype; 1582 MappingType textype;
1389 textype = MappingType.Default; 1583 textype = MappingType.Default;
@@ -1414,6 +1608,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1414 1608
1415 public void SetGlow(SceneObjectPart part, int face, float glow) 1609 public void SetGlow(SceneObjectPart part, int face, float glow)
1416 { 1610 {
1611 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1612 return;
1613
1417 Primitive.TextureEntry tex = part.Shape.Textures; 1614 Primitive.TextureEntry tex = part.Shape.Textures;
1418 if (face >= 0 && face < GetNumberOfSides(part)) 1615 if (face >= 0 && face < GetNumberOfSides(part))
1419 { 1616 {
@@ -1439,6 +1636,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1439 1636
1440 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1637 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1441 { 1638 {
1639 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1640 return;
1442 1641
1443 Shininess sval = new Shininess(); 1642 Shininess sval = new Shininess();
1444 1643
@@ -1489,6 +1688,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1489 1688
1490 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1689 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1491 { 1690 {
1691 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1692 return;
1693
1492 Primitive.TextureEntry tex = part.Shape.Textures; 1694 Primitive.TextureEntry tex = part.Shape.Textures;
1493 if (face >= 0 && face < GetNumberOfSides(part)) 1695 if (face >= 0 && face < GetNumberOfSides(part))
1494 { 1696 {
@@ -1549,13 +1751,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1549 m_host.AddScriptLPS(1); 1751 m_host.AddScriptLPS(1);
1550 1752
1551 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1753 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1552 1754 if (parts.Count > 0)
1553 foreach (SceneObjectPart part in parts) 1755 {
1554 SetAlpha(part, alpha, face); 1756 try
1757 {
1758 foreach (SceneObjectPart part in parts)
1759 SetAlpha(part, alpha, face);
1760 }
1761 finally
1762 {
1763 }
1764 }
1555 } 1765 }
1556 1766
1557 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1767 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1558 { 1768 {
1769 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1770 return;
1771
1559 Primitive.TextureEntry tex = part.Shape.Textures; 1772 Primitive.TextureEntry tex = part.Shape.Textures;
1560 Color4 texcolor; 1773 Color4 texcolor;
1561 if (face >= 0 && face < GetNumberOfSides(part)) 1774 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1608,7 +1821,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1608 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1821 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1609 float wind, float tension, LSL_Vector Force) 1822 float wind, float tension, LSL_Vector Force)
1610 { 1823 {
1611 if (part == null) 1824 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1612 return; 1825 return;
1613 1826
1614 if (flexi) 1827 if (flexi)
@@ -1642,7 +1855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1642 /// <param name="falloff"></param> 1855 /// <param name="falloff"></param>
1643 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1856 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1644 { 1857 {
1645 if (part == null) 1858 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1646 return; 1859 return;
1647 1860
1648 if (light) 1861 if (light)
@@ -1675,11 +1888,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1675 Primitive.TextureEntry tex = part.Shape.Textures; 1888 Primitive.TextureEntry tex = part.Shape.Textures;
1676 Color4 texcolor; 1889 Color4 texcolor;
1677 LSL_Vector rgb = new LSL_Vector(); 1890 LSL_Vector rgb = new LSL_Vector();
1891 int nsides = GetNumberOfSides(part);
1892
1678 if (face == ScriptBaseClass.ALL_SIDES) 1893 if (face == ScriptBaseClass.ALL_SIDES)
1679 { 1894 {
1680 int i; 1895 int i;
1681 1896 for (i = 0; i < nsides; i++)
1682 for (i = 0 ; i < GetNumberOfSides(part); i++)
1683 { 1897 {
1684 texcolor = tex.GetFace((uint)i).RGBA; 1898 texcolor = tex.GetFace((uint)i).RGBA;
1685 rgb.x += texcolor.R; 1899 rgb.x += texcolor.R;
@@ -1687,14 +1901,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1687 rgb.z += texcolor.B; 1901 rgb.z += texcolor.B;
1688 } 1902 }
1689 1903
1690 rgb.x /= (float)GetNumberOfSides(part); 1904 float invnsides = 1.0f / (float)nsides;
1691 rgb.y /= (float)GetNumberOfSides(part); 1905
1692 rgb.z /= (float)GetNumberOfSides(part); 1906 rgb.x *= invnsides;
1907 rgb.y *= invnsides;
1908 rgb.z *= invnsides;
1693 1909
1694 return rgb; 1910 return rgb;
1695 } 1911 }
1696 1912 if (face >= 0 && face < nsides)
1697 if (face >= 0 && face < GetNumberOfSides(part))
1698 { 1913 {
1699 texcolor = tex.GetFace((uint)face).RGBA; 1914 texcolor = tex.GetFace((uint)face).RGBA;
1700 rgb.x = texcolor.R; 1915 rgb.x = texcolor.R;
@@ -1721,15 +1936,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1721 m_host.AddScriptLPS(1); 1936 m_host.AddScriptLPS(1);
1722 1937
1723 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1938 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1724 1939 if (parts.Count > 0)
1725 foreach (SceneObjectPart part in parts) 1940 {
1726 SetTexture(part, texture, face); 1941 try
1727 1942 {
1943 foreach (SceneObjectPart part in parts)
1944 SetTexture(part, texture, face);
1945 }
1946 finally
1947 {
1948 }
1949 }
1728 ScriptSleep(200); 1950 ScriptSleep(200);
1729 } 1951 }
1730 1952
1731 protected void SetTexture(SceneObjectPart part, string texture, int face) 1953 protected void SetTexture(SceneObjectPart part, string texture, int face)
1732 { 1954 {
1955 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1956 return;
1957
1733 UUID textureID = new UUID(); 1958 UUID textureID = new UUID();
1734 1959
1735 textureID = InventoryKey(texture, (int)AssetType.Texture); 1960 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1774,6 +1999,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1774 1999
1775 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2000 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1776 { 2001 {
2002 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2003 return;
2004
1777 Primitive.TextureEntry tex = part.Shape.Textures; 2005 Primitive.TextureEntry tex = part.Shape.Textures;
1778 if (face >= 0 && face < GetNumberOfSides(part)) 2006 if (face >= 0 && face < GetNumberOfSides(part))
1779 { 2007 {
@@ -1810,6 +2038,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1810 2038
1811 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2039 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1812 { 2040 {
2041 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2042 return;
2043
1813 Primitive.TextureEntry tex = part.Shape.Textures; 2044 Primitive.TextureEntry tex = part.Shape.Textures;
1814 if (face >= 0 && face < GetNumberOfSides(part)) 2045 if (face >= 0 && face < GetNumberOfSides(part))
1815 { 2046 {
@@ -1846,6 +2077,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1846 2077
1847 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2078 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1848 { 2079 {
2080 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2081 return;
2082
1849 Primitive.TextureEntry tex = part.Shape.Textures; 2083 Primitive.TextureEntry tex = part.Shape.Textures;
1850 if (face >= 0 && face < GetNumberOfSides(part)) 2084 if (face >= 0 && face < GetNumberOfSides(part))
1851 { 2085 {
@@ -2016,24 +2250,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2016 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2250 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2017 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2251 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2018 { 2252 {
2019 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2253 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2254 return;
2255
2020 LSL_Vector currentPos = GetPartLocalPos(part); 2256 LSL_Vector currentPos = GetPartLocalPos(part);
2257 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2021 2258
2022 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2023 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2024 2259
2025 if (part.ParentGroup.RootPart == part) 2260 if (part.ParentGroup.RootPart == part)
2026 { 2261 {
2027 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2028 targetPos.z = ground;
2029 SceneObjectGroup parent = part.ParentGroup; 2262 SceneObjectGroup parent = part.ParentGroup;
2030 parent.UpdateGroupPosition(!adjust ? targetPos : 2263 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2031 SetPosAdjust(currentPos, targetPos)); 2264 return;
2265 Util.FireAndForget(delegate(object x) {
2266 parent.UpdateGroupPosition((Vector3)toPos);
2267 });
2032 } 2268 }
2033 else 2269 else
2034 { 2270 {
2035 part.OffsetPosition = !adjust ? targetPos : 2271 part.OffsetPosition = (Vector3)toPos;
2036 SetPosAdjust(currentPos, targetPos);
2037 SceneObjectGroup parent = part.ParentGroup; 2272 SceneObjectGroup parent = part.ParentGroup;
2038 parent.HasGroupChanged = true; 2273 parent.HasGroupChanged = true;
2039 parent.ScheduleGroupForTerseUpdate(); 2274 parent.ScheduleGroupForTerseUpdate();
@@ -2066,13 +2301,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2066 else 2301 else
2067 { 2302 {
2068 if (part.ParentGroup.IsAttachment) 2303 if (part.ParentGroup.IsAttachment)
2069 {
2070 pos = part.AttachedPos; 2304 pos = part.AttachedPos;
2071 }
2072 else 2305 else
2073 {
2074 pos = part.AbsolutePosition; 2306 pos = part.AbsolutePosition;
2075 }
2076 } 2307 }
2077 2308
2078// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2309// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2112,25 +2343,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2112 2343
2113 protected void SetRot(SceneObjectPart part, Quaternion rot) 2344 protected void SetRot(SceneObjectPart part, Quaternion rot)
2114 { 2345 {
2115 part.UpdateRotation(rot); 2346 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2116 // Update rotation does not move the object in the physics scene if it's a linkset. 2347 return;
2117 2348
2118//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2349 bool isroot = (part == part.ParentGroup.RootPart);
2119// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2350 bool isphys;
2120 2351
2121 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2122 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2123 // It's perfectly okay when the object is not an active physical body though.
2124 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2125 // but only if the object is not physial and active. This is important for rotating doors.
2126 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2127 // scene
2128 PhysicsActor pa = part.PhysActor; 2352 PhysicsActor pa = part.PhysActor;
2129 2353
2130 if (pa != null && !pa.IsPhysical) 2354 // keep using physactor ideia of isphysical
2355 // it should be SOP ideia of that
2356 // not much of a issue with ubitODE
2357 if (pa != null && pa.IsPhysical)
2358 isphys = true;
2359 else
2360 isphys = false;
2361
2362 // SL doesn't let scripts rotate root of physical linksets
2363 if (isroot && isphys)
2364 return;
2365
2366 part.UpdateRotation(rot);
2367
2368 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2369 // so do a nasty update of parts positions if is a root part rotation
2370 if (isroot && pa != null) // with if above implies non physical root part
2131 { 2371 {
2132 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2372 part.ParentGroup.ResetChildPrimPhysicsPositions();
2133 } 2373 }
2374 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2375 {
2376 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2377 if (sittingavas.Count > 0)
2378 {
2379 foreach (ScenePresence av in sittingavas)
2380 {
2381 if (isroot || part.LocalId == av.ParentID)
2382 av.SendTerseUpdateToAllClients();
2383 }
2384 }
2385 }
2134 } 2386 }
2135 2387
2136 /// <summary> 2388 /// <summary>
@@ -2178,8 +2430,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2178 2430
2179 public LSL_Rotation llGetLocalRot() 2431 public LSL_Rotation llGetLocalRot()
2180 { 2432 {
2433 return GetPartLocalRot(m_host);
2434 }
2435
2436 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2437 {
2181 m_host.AddScriptLPS(1); 2438 m_host.AddScriptLPS(1);
2182 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2439 Quaternion rot = part.RotationOffset;
2440 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2183 } 2441 }
2184 2442
2185 public void llSetForce(LSL_Vector force, int local) 2443 public void llSetForce(LSL_Vector force, int local)
@@ -2259,16 +2517,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2259 m_host.ApplyImpulse(v, local != 0); 2517 m_host.ApplyImpulse(v, local != 0);
2260 } 2518 }
2261 2519
2520
2262 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2521 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2263 { 2522 {
2264 m_host.AddScriptLPS(1); 2523 m_host.AddScriptLPS(1);
2265 m_host.ApplyAngularImpulse(force, local != 0); 2524 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2266 } 2525 }
2267 2526
2268 public void llSetTorque(LSL_Vector torque, int local) 2527 public void llSetTorque(LSL_Vector torque, int local)
2269 { 2528 {
2270 m_host.AddScriptLPS(1); 2529 m_host.AddScriptLPS(1);
2271 m_host.SetAngularImpulse(torque, local != 0); 2530 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2272 } 2531 }
2273 2532
2274 public LSL_Vector llGetTorque() 2533 public LSL_Vector llGetTorque()
@@ -2285,20 +2544,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2285 llSetTorque(torque, local); 2544 llSetTorque(torque, local);
2286 } 2545 }
2287 2546
2547 public void llSetVelocity(LSL_Vector vel, int local)
2548 {
2549 m_host.AddScriptLPS(1);
2550 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2551 }
2552
2288 public LSL_Vector llGetVel() 2553 public LSL_Vector llGetVel()
2289 { 2554 {
2290 m_host.AddScriptLPS(1); 2555 m_host.AddScriptLPS(1);
2291 2556
2292 Vector3 vel; 2557 Vector3 vel = Vector3.Zero;
2293 2558
2294 if (m_host.ParentGroup.IsAttachment) 2559 if (m_host.ParentGroup.IsAttachment)
2295 { 2560 {
2296 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2561 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2297 vel = avatar.Velocity; 2562 if (avatar != null)
2563 vel = avatar.Velocity;
2298 } 2564 }
2299 else 2565 else
2300 { 2566 {
2301 vel = m_host.Velocity; 2567 vel = m_host.ParentGroup.RootPart.Velocity;
2302 } 2568 }
2303 2569
2304 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2570 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2310,10 +2576,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2310 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2576 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2311 } 2577 }
2312 2578
2579 public void llSetAngularVelocity(LSL_Vector avel, int local)
2580 {
2581 m_host.AddScriptLPS(1);
2582 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2583 }
2584
2313 public LSL_Vector llGetOmega() 2585 public LSL_Vector llGetOmega()
2314 { 2586 {
2315 m_host.AddScriptLPS(1); 2587 m_host.AddScriptLPS(1);
2316 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2588 Vector3 avel = m_host.AngularVelocity;
2589 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2317 } 2590 }
2318 2591
2319 public LSL_Float llGetTimeOfDay() 2592 public LSL_Float llGetTimeOfDay()
@@ -2839,16 +3112,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2839 new_group.RootPart.UUID.ToString()) }, 3112 new_group.RootPart.UUID.ToString()) },
2840 new DetectParams[0])); 3113 new DetectParams[0]));
2841 3114
2842 float groupmass = new_group.GetMass(); 3115 // do recoil
3116 SceneObjectGroup hostgrp = m_host.ParentGroup;
3117 if (hostgrp == null)
3118 return;
3119
3120 if (hostgrp.IsAttachment) // don't recoil avatars
3121 return;
2843 3122
2844 PhysicsActor pa = new_group.RootPart.PhysActor; 3123 PhysicsActor pa = new_group.RootPart.PhysActor;
2845 3124
2846 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3125 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2847 { 3126 {
2848 //Recoil. 3127 float groupmass = new_group.GetMass();
2849 llApplyImpulse(vel * groupmass, 0); 3128 vel *= -groupmass;
3129 llApplyImpulse(vel, 0);
2850 } 3130 }
2851 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3131 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3132 return;
3133
2852 }); 3134 });
2853 3135
2854 //ScriptSleep((int)((groupmass * velmag) / 10)); 3136 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2863,35 +3145,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2863 public void llLookAt(LSL_Vector target, double strength, double damping) 3145 public void llLookAt(LSL_Vector target, double strength, double damping)
2864 { 3146 {
2865 m_host.AddScriptLPS(1); 3147 m_host.AddScriptLPS(1);
2866 // Determine where we are looking from
2867 LSL_Vector from = llGetPos();
2868 3148
2869 // Work out the normalised vector from the source to the target 3149 // Get the normalized vector to the target
2870 LSL_Vector delta = llVecNorm(target - from); 3150 LSL_Vector d1 = llVecNorm(target - llGetPos());
2871 LSL_Vector angle = new LSL_Vector(0,0,0);
2872 3151
2873 // Calculate the yaw 3152 // Get the bearing (yaw)
2874 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3153 LSL_Vector a1 = new LSL_Vector(0,0,0);
2875 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3154 a1.z = llAtan2(d1.y, d1.x);
2876 3155
2877 // Calculate pitch 3156 // Get the elevation (pitch)
2878 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3157 LSL_Vector a2 = new LSL_Vector(0,0,0);
3158 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2879 3159
2880 // we need to convert from a vector describing 3160 LSL_Rotation r1 = llEuler2Rot(a1);
2881 // the angles of rotation in radians into rotation value 3161 LSL_Rotation r2 = llEuler2Rot(a2);
2882 LSL_Rotation rot = llEuler2Rot(angle); 3162 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2883
2884 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2885 // set the rotation of the object, copy that behavior
2886 PhysicsActor pa = m_host.PhysActor;
2887 3163
2888 if (strength == 0 || pa == null || !pa.IsPhysical) 3164 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2889 { 3165 {
2890 llSetRot(rot); 3166 // Do nothing if either value is 0 (this has been checked in SL)
3167 if (strength <= 0.0 || damping <= 0.0)
3168 return;
3169
3170 llSetRot(r3 * r2 * r1);
2891 } 3171 }
2892 else 3172 else
2893 { 3173 {
2894 m_host.StartLookAt(rot, (float)strength, (float)damping); 3174 if (strength == 0)
3175 {
3176 llSetRot(r3 * r2 * r1);
3177 return;
3178 }
3179
3180 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2895 } 3181 }
2896 } 3182 }
2897 3183
@@ -2937,17 +3223,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2937 } 3223 }
2938 else 3224 else
2939 { 3225 {
2940 if (m_host.IsRoot) 3226 // new SL always returns object mass
2941 { 3227// if (m_host.IsRoot)
3228// {
2942 return m_host.ParentGroup.GetMass(); 3229 return m_host.ParentGroup.GetMass();
2943 } 3230// }
2944 else 3231// else
2945 { 3232// {
2946 return m_host.GetMass(); 3233// return m_host.GetMass();
2947 } 3234// }
2948 } 3235 }
2949 } 3236 }
2950 3237
3238
3239 public LSL_Float llGetMassMKS()
3240 {
3241 return 100f * llGetMass();
3242 }
3243
2951 public void llCollisionFilter(string name, string id, int accept) 3244 public void llCollisionFilter(string name, string id, int accept)
2952 { 3245 {
2953 m_host.AddScriptLPS(1); 3246 m_host.AddScriptLPS(1);
@@ -2995,8 +3288,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2995 { 3288 {
2996 // Unregister controls from Presence 3289 // Unregister controls from Presence
2997 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3290 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2998 // Remove Take Control permission.
2999 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3000 } 3291 }
3001 } 3292 }
3002 } 3293 }
@@ -3022,7 +3313,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3022 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3313 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3023 3314
3024 if (attachmentsModule != null) 3315 if (attachmentsModule != null)
3025 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3316 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3026 else 3317 else
3027 return false; 3318 return false;
3028 } 3319 }
@@ -3052,9 +3343,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3052 { 3343 {
3053 m_host.AddScriptLPS(1); 3344 m_host.AddScriptLPS(1);
3054 3345
3055// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3056// return;
3057
3058 if (m_item.PermsGranter != m_host.OwnerID) 3346 if (m_item.PermsGranter != m_host.OwnerID)
3059 return; 3347 return;
3060 3348
@@ -3097,6 +3385,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3097 3385
3098 public void llInstantMessage(string user, string message) 3386 public void llInstantMessage(string user, string message)
3099 { 3387 {
3388 UUID result;
3389 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3390 {
3391 ShoutError("An invalid key was passed to llInstantMessage");
3392 ScriptSleep(2000);
3393 return;
3394 }
3395
3396
3100 m_host.AddScriptLPS(1); 3397 m_host.AddScriptLPS(1);
3101 3398
3102 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3399 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3111,14 +3408,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3111 UUID friendTransactionID = UUID.Random(); 3408 UUID friendTransactionID = UUID.Random();
3112 3409
3113 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3410 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3114 3411
3115 GridInstantMessage msg = new GridInstantMessage(); 3412 GridInstantMessage msg = new GridInstantMessage();
3116 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3413 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3117 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3414 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3118 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3415 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3119// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3416// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3120// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3417// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3121 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3418// DateTime dt = DateTime.UtcNow;
3419//
3420// // Ticks from UtcNow, but make it look like local. Evil, huh?
3421// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3422//
3423// try
3424// {
3425// // Convert that to the PST timezone
3426// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3427// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3428// }
3429// catch
3430// {
3431// // No logging here, as it could be VERY spammy
3432// }
3433//
3434// // And make it look local again to fool the unix time util
3435// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3436
3437 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3438
3122 //if (client != null) 3439 //if (client != null)
3123 //{ 3440 //{
3124 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3441 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3132,12 +3449,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3132 msg.message = message.Substring(0, 1024); 3449 msg.message = message.Substring(0, 1024);
3133 else 3450 else
3134 msg.message = message; 3451 msg.message = message;
3135 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3452 msg.dialog = (byte)19; // MessageFromObject
3136 msg.fromGroup = false;// fromGroup; 3453 msg.fromGroup = false;// fromGroup;
3137 msg.offline = (byte)0; //offline; 3454 msg.offline = (byte)0; //offline;
3138 msg.ParentEstateID = 0; //ParentEstateID; 3455 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3139 msg.Position = new Vector3(m_host.AbsolutePosition); 3456 msg.Position = new Vector3(m_host.AbsolutePosition);
3140 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3457 msg.RegionID = World.RegionInfo.RegionID.Guid;
3141 msg.binaryBucket 3458 msg.binaryBucket
3142 = Util.StringToBytes256( 3459 = Util.StringToBytes256(
3143 "{0}/{1}/{2}/{3}", 3460 "{0}/{1}/{2}/{3}",
@@ -3165,7 +3482,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3165 } 3482 }
3166 3483
3167 emailModule.SendEmail(m_host.UUID, address, subject, message); 3484 emailModule.SendEmail(m_host.UUID, address, subject, message);
3168 llSleep(EMAIL_PAUSE_TIME); 3485 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3169 } 3486 }
3170 3487
3171 public void llGetNextEmail(string address, string subject) 3488 public void llGetNextEmail(string address, string subject)
@@ -3411,7 +3728,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3411 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3728 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3412 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3729 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3413 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3730 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3731 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3414 ScriptBaseClass.PERMISSION_ATTACH; 3732 ScriptBaseClass.PERMISSION_ATTACH;
3733
3415 } 3734 }
3416 else 3735 else
3417 { 3736 {
@@ -3446,11 +3765,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3446 3765
3447 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3766 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3448 { 3767 {
3449 lock (m_host.TaskInventory) 3768 m_host.TaskInventory.LockItemsForWrite(true);
3450 { 3769 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3451 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3770 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3452 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3771 m_host.TaskInventory.LockItemsForWrite(false);
3453 }
3454 3772
3455 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3773 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3456 "run_time_permissions", new Object[] { 3774 "run_time_permissions", new Object[] {
@@ -3493,11 +3811,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3493 3811
3494 if (!m_waitingForScriptAnswer) 3812 if (!m_waitingForScriptAnswer)
3495 { 3813 {
3496 lock (m_host.TaskInventory) 3814 m_host.TaskInventory.LockItemsForWrite(true);
3497 { 3815 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3498 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3816 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3499 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3817 m_host.TaskInventory.LockItemsForWrite(false);
3500 }
3501 3818
3502 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3819 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3503 m_waitingForScriptAnswer=true; 3820 m_waitingForScriptAnswer=true;
@@ -3526,14 +3843,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3526 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3843 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3527 llReleaseControls(); 3844 llReleaseControls();
3528 3845
3529 lock (m_host.TaskInventory) 3846 m_host.TaskInventory.LockItemsForWrite(true);
3530 { 3847 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3531 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3848 m_host.TaskInventory.LockItemsForWrite(false);
3532 } 3849
3533 3850 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3534 m_ScriptEngine.PostScriptEvent( 3851 "run_time_permissions", new Object[] {
3535 m_item.ItemID, 3852 new LSL_Integer(answer) },
3536 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3853 new DetectParams[0]));
3537 } 3854 }
3538 3855
3539 public LSL_String llGetPermissionsKey() 3856 public LSL_String llGetPermissionsKey()
@@ -3572,14 +3889,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3572 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3889 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3573 { 3890 {
3574 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3891 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3575 3892 if (parts.Count > 0)
3576 foreach (SceneObjectPart part in parts) 3893 {
3577 part.SetFaceColorAlpha(face, color, null); 3894 try
3895 {
3896 foreach (SceneObjectPart part in parts)
3897 part.SetFaceColorAlpha(face, color, null);
3898 }
3899 finally
3900 {
3901 }
3902 }
3578 } 3903 }
3579 3904
3580 public void llCreateLink(string target, int parent) 3905 public void llCreateLink(string target, int parent)
3581 { 3906 {
3582 m_host.AddScriptLPS(1); 3907 m_host.AddScriptLPS(1);
3908
3583 UUID targetID; 3909 UUID targetID;
3584 3910
3585 if (!UUID.TryParse(target, out targetID)) 3911 if (!UUID.TryParse(target, out targetID))
@@ -3685,10 +4011,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3685 // Restructuring Multiple Prims. 4011 // Restructuring Multiple Prims.
3686 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4012 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3687 parts.Remove(parentPrim.RootPart); 4013 parts.Remove(parentPrim.RootPart);
3688 foreach (SceneObjectPart part in parts) 4014 if (parts.Count > 0)
3689 { 4015 {
3690 parentPrim.DelinkFromGroup(part.LocalId, true); 4016 try
4017 {
4018 foreach (SceneObjectPart part in parts)
4019 {
4020 parentPrim.DelinkFromGroup(part.LocalId, true);
4021 }
4022 }
4023 finally
4024 {
4025 }
3691 } 4026 }
4027
3692 parentPrim.HasGroupChanged = true; 4028 parentPrim.HasGroupChanged = true;
3693 parentPrim.ScheduleGroupForFullUpdate(); 4029 parentPrim.ScheduleGroupForFullUpdate();
3694 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4030 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3697,12 +4033,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3697 { 4033 {
3698 SceneObjectPart newRoot = parts[0]; 4034 SceneObjectPart newRoot = parts[0];
3699 parts.Remove(newRoot); 4035 parts.Remove(newRoot);
3700 foreach (SceneObjectPart part in parts) 4036
4037 try
3701 { 4038 {
3702 // Required for linking 4039 foreach (SceneObjectPart part in parts)
3703 part.ClearUpdateSchedule(); 4040 {
3704 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4041 part.ClearUpdateSchedule();
4042 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4043 }
3705 } 4044 }
4045 finally
4046 {
4047 }
4048
4049
3706 newRoot.ParentGroup.HasGroupChanged = true; 4050 newRoot.ParentGroup.HasGroupChanged = true;
3707 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4051 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3708 } 4052 }
@@ -3722,6 +4066,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3722 public void llBreakAllLinks() 4066 public void llBreakAllLinks()
3723 { 4067 {
3724 m_host.AddScriptLPS(1); 4068 m_host.AddScriptLPS(1);
4069
4070 TaskInventoryItem item = m_item;
4071
4072 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4073 && !m_automaticLinkPermission)
4074 {
4075 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4076 return;
4077 }
4078
3725 SceneObjectGroup parentPrim = m_host.ParentGroup; 4079 SceneObjectGroup parentPrim = m_host.ParentGroup;
3726 if (parentPrim.AttachmentPoint != 0) 4080 if (parentPrim.AttachmentPoint != 0)
3727 return; // Fail silently if attached 4081 return; // Fail silently if attached
@@ -3741,25 +4095,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3741 public LSL_String llGetLinkKey(int linknum) 4095 public LSL_String llGetLinkKey(int linknum)
3742 { 4096 {
3743 m_host.AddScriptLPS(1); 4097 m_host.AddScriptLPS(1);
3744 List<UUID> keytable = new List<UUID>();
3745 // parse for sitting avatare-uuids
3746 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3747 {
3748 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3749 keytable.Add(presence.UUID);
3750 });
3751
3752 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3753 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3754 {
3755 return keytable[totalprims - linknum].ToString();
3756 }
3757
3758 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3759 {
3760 return m_host.UUID.ToString();
3761 }
3762
3763 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4098 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3764 if (part != null) 4099 if (part != null)
3765 { 4100 {
@@ -3767,6 +4102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3767 } 4102 }
3768 else 4103 else
3769 { 4104 {
4105 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4106 {
4107 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4108
4109 if (linknum < 0)
4110 return UUID.Zero.ToString();
4111
4112 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4113 if (avatars.Count > linknum)
4114 {
4115 return avatars[linknum].UUID.ToString();
4116 }
4117 }
3770 return UUID.Zero.ToString(); 4118 return UUID.Zero.ToString();
3771 } 4119 }
3772 } 4120 }
@@ -3866,17 +4214,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3866 m_host.AddScriptLPS(1); 4214 m_host.AddScriptLPS(1);
3867 int count = 0; 4215 int count = 0;
3868 4216
3869 lock (m_host.TaskInventory) 4217 m_host.TaskInventory.LockItemsForRead(true);
4218 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3870 { 4219 {
3871 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4220 if (inv.Value.Type == type || type == -1)
3872 { 4221 {
3873 if (inv.Value.Type == type || type == -1) 4222 count = count + 1;
3874 {
3875 count = count + 1;
3876 }
3877 } 4223 }
3878 } 4224 }
3879 4225
4226 m_host.TaskInventory.LockItemsForRead(false);
3880 return count; 4227 return count;
3881 } 4228 }
3882 4229
@@ -3885,16 +4232,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3885 m_host.AddScriptLPS(1); 4232 m_host.AddScriptLPS(1);
3886 ArrayList keys = new ArrayList(); 4233 ArrayList keys = new ArrayList();
3887 4234
3888 lock (m_host.TaskInventory) 4235 m_host.TaskInventory.LockItemsForRead(true);
4236 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3889 { 4237 {
3890 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4238 if (inv.Value.Type == type || type == -1)
3891 { 4239 {
3892 if (inv.Value.Type == type || type == -1) 4240 keys.Add(inv.Value.Name);
3893 {
3894 keys.Add(inv.Value.Name);
3895 }
3896 } 4241 }
3897 } 4242 }
4243 m_host.TaskInventory.LockItemsForRead(false);
3898 4244
3899 if (keys.Count == 0) 4245 if (keys.Count == 0)
3900 { 4246 {
@@ -3932,7 +4278,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3932 if (item == null) 4278 if (item == null)
3933 { 4279 {
3934 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4280 llSay(0, String.Format("Could not find object '{0}'", inventory));
3935 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4281 return;
4282// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3936 } 4283 }
3937 4284
3938 UUID objId = item.ItemID; 4285 UUID objId = item.ItemID;
@@ -3960,33 +4307,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3960 return; 4307 return;
3961 } 4308 }
3962 } 4309 }
4310
3963 // destination is an avatar 4311 // destination is an avatar
3964 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4312 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3965 4313
3966 if (agentItem == null) 4314 if (agentItem == null)
3967 return; 4315 return;
3968 4316
3969 if (m_TransferModule != null) 4317 byte[] bucket = new byte[1];
3970 { 4318 bucket[0] = (byte)item.Type;
3971 byte[] bucket = new byte[] { (byte)item.Type }; 4319 //byte[] objBytes = agentItem.ID.GetBytes();
4320 //Array.Copy(objBytes, 0, bucket, 1, 16);
3972 4321
3973 GridInstantMessage msg = new GridInstantMessage(World, 4322 GridInstantMessage msg = new GridInstantMessage(World,
3974 m_host.UUID, m_host.Name + ", an object owned by " + 4323 m_host.OwnerID, m_host.Name, destId,
3975 resolveName(m_host.OwnerID) + ",", destId, 4324 (byte)InstantMessageDialog.TaskInventoryOffered,
3976 (byte)InstantMessageDialog.TaskInventoryOffered, 4325 false, item.Name+". "+m_host.Name+" is located at "+
3977 false, item.Name + "\n" + m_host.Name + " is located at " + 4326 World.RegionInfo.RegionName+" "+
3978 World.RegionInfo.RegionName+" "+ 4327 m_host.AbsolutePosition.ToString(),
3979 m_host.AbsolutePosition.ToString(), 4328 agentItem.ID, true, m_host.AbsolutePosition,
3980 agentItem.ID, true, m_host.AbsolutePosition, 4329 bucket);
3981 bucket);
3982 4330
3983 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4331 ScenePresence sp;
3984 }
3985 4332
4333 if (World.TryGetScenePresence(destId, out sp))
4334 {
4335 sp.ControllingClient.SendInstantMessage(msg);
4336 }
4337 else
4338 {
4339 if (m_TransferModule != null)
4340 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4341 }
4342
4343 //This delay should only occur when giving inventory to avatars.
3986 ScriptSleep(3000); 4344 ScriptSleep(3000);
3987 } 4345 }
3988 } 4346 }
3989 4347
4348 [DebuggerNonUserCode]
3990 public void llRemoveInventory(string name) 4349 public void llRemoveInventory(string name)
3991 { 4350 {
3992 m_host.AddScriptLPS(1); 4351 m_host.AddScriptLPS(1);
@@ -4030,109 +4389,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4030 { 4389 {
4031 m_host.AddScriptLPS(1); 4390 m_host.AddScriptLPS(1);
4032 4391
4033 UUID uuid = (UUID)id; 4392 UUID uuid;
4034 PresenceInfo pinfo = null; 4393 if (UUID.TryParse(id, out uuid))
4035 UserAccount account;
4036
4037 UserInfoCacheEntry ce;
4038 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4039 { 4394 {
4040 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4395 PresenceInfo pinfo = null;
4041 if (account == null) 4396 UserAccount account;
4397
4398 UserInfoCacheEntry ce;
4399 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4042 { 4400 {
4043 m_userInfoCache[uuid] = null; // Cache negative 4401 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4044 return UUID.Zero.ToString(); 4402 if (account == null)
4045 } 4403 {
4404 m_userInfoCache[uuid] = null; // Cache negative
4405 return UUID.Zero.ToString();
4406 }
4046 4407
4047 4408
4048 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4409 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4049 if (pinfos != null && pinfos.Length > 0) 4410 if (pinfos != null && pinfos.Length > 0)
4050 {
4051 foreach (PresenceInfo p in pinfos)
4052 { 4411 {
4053 if (p.RegionID != UUID.Zero) 4412 foreach (PresenceInfo p in pinfos)
4054 { 4413 {
4055 pinfo = p; 4414 if (p.RegionID != UUID.Zero)
4415 {
4416 pinfo = p;
4417 }
4056 } 4418 }
4057 } 4419 }
4058 }
4059 4420
4060 ce = new UserInfoCacheEntry(); 4421 ce = new UserInfoCacheEntry();
4061 ce.time = Util.EnvironmentTickCount(); 4422 ce.time = Util.EnvironmentTickCount();
4062 ce.account = account; 4423 ce.account = account;
4063 ce.pinfo = pinfo; 4424 ce.pinfo = pinfo;
4064 } 4425 m_userInfoCache[uuid] = ce;
4065 else 4426 }
4066 { 4427 else
4067 if (ce == null) 4428 {
4068 return UUID.Zero.ToString(); 4429 if (ce == null)
4430 return UUID.Zero.ToString();
4069 4431
4070 account = ce.account; 4432 account = ce.account;
4071 pinfo = ce.pinfo; 4433 pinfo = ce.pinfo;
4072 } 4434 }
4073 4435
4074 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4436 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4075 {
4076 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4077 if (pinfos != null && pinfos.Length > 0)
4078 { 4437 {
4079 foreach (PresenceInfo p in pinfos) 4438 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4439 if (pinfos != null && pinfos.Length > 0)
4080 { 4440 {
4081 if (p.RegionID != UUID.Zero) 4441 foreach (PresenceInfo p in pinfos)
4082 { 4442 {
4083 pinfo = p; 4443 if (p.RegionID != UUID.Zero)
4444 {
4445 pinfo = p;
4446 }
4084 } 4447 }
4085 } 4448 }
4086 } 4449 else
4087 else 4450 pinfo = null;
4088 pinfo = null;
4089 4451
4090 ce.time = Util.EnvironmentTickCount(); 4452 ce.time = Util.EnvironmentTickCount();
4091 ce.pinfo = pinfo; 4453 ce.pinfo = pinfo;
4092 } 4454 }
4093 4455
4094 string reply = String.Empty; 4456 string reply = String.Empty;
4095 4457
4096 switch (data) 4458 switch (data)
4097 { 4459 {
4098 case 1: // DATA_ONLINE (0|1) 4460 case 1: // DATA_ONLINE (0|1)
4099 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4461 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4100 reply = "1"; 4462 reply = "1";
4101 else 4463 else
4102 reply = "0"; 4464 reply = "0";
4103 break; 4465 break;
4104 case 2: // DATA_NAME (First Last) 4466 case 2: // DATA_NAME (First Last)
4105 reply = account.FirstName + " " + account.LastName; 4467 reply = account.FirstName + " " + account.LastName;
4106 break; 4468 break;
4107 case 3: // DATA_BORN (YYYY-MM-DD) 4469 case 3: // DATA_BORN (YYYY-MM-DD)
4108 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4470 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4109 born = born.AddSeconds(account.Created); 4471 born = born.AddSeconds(account.Created);
4110 reply = born.ToString("yyyy-MM-dd"); 4472 reply = born.ToString("yyyy-MM-dd");
4111 break; 4473 break;
4112 case 4: // DATA_RATING (0,0,0,0,0,0) 4474 case 4: // DATA_RATING (0,0,0,0,0,0)
4113 reply = "0,0,0,0,0,0"; 4475 reply = "0,0,0,0,0,0";
4114 break; 4476 break;
4115 case 7: // DATA_USERLEVEL (integer) 4477 case 8: // DATA_PAYINFO (0|1|2|3)
4116 reply = account.UserLevel.ToString(); 4478 reply = "0";
4117 break; 4479 break;
4118 case 8: // DATA_PAYINFO (0|1|2|3) 4480 default:
4119 reply = "0"; 4481 return UUID.Zero.ToString(); // Raise no event
4120 break; 4482 }
4121 default:
4122 return UUID.Zero.ToString(); // Raise no event
4123 }
4124 4483
4125 UUID rq = UUID.Random(); 4484 UUID rq = UUID.Random();
4126 4485
4127 UUID tid = AsyncCommands. 4486 UUID tid = AsyncCommands.
4128 DataserverPlugin.RegisterRequest(m_host.LocalId, 4487 DataserverPlugin.RegisterRequest(m_host.LocalId,
4129 m_item.ItemID, rq.ToString()); 4488 m_item.ItemID, rq.ToString());
4130 4489
4131 AsyncCommands. 4490 AsyncCommands.
4132 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4491 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4133 4492
4134 ScriptSleep(100); 4493 ScriptSleep(100);
4135 return tid.ToString(); 4494 return tid.ToString();
4495 }
4496 else
4497 {
4498 ShoutError("Invalid UUID passed to llRequestAgentData.");
4499 }
4500 return "";
4136 } 4501 }
4137 4502
4138 public LSL_String llRequestInventoryData(string name) 4503 public LSL_String llRequestInventoryData(string name)
@@ -4189,13 +4554,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4189 if (UUID.TryParse(agent, out agentId)) 4554 if (UUID.TryParse(agent, out agentId))
4190 { 4555 {
4191 ScenePresence presence = World.GetScenePresence(agentId); 4556 ScenePresence presence = World.GetScenePresence(agentId);
4192 if (presence != null) 4557 if (presence != null && presence.PresenceType != PresenceType.Npc)
4193 { 4558 {
4559 // agent must not be a god
4560 if (presence.UserLevel >= 200) return;
4561
4194 // agent must be over the owners land 4562 // agent must be over the owners land
4195 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4563 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4196 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4564 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4197 { 4565 {
4198 World.TeleportClientHome(agentId, presence.ControllingClient); 4566 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4567 {
4568 // They can't be teleported home for some reason
4569 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4570 if (regionInfo != null)
4571 {
4572 World.RequestTeleportLocation(
4573 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4574 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4575 }
4576 }
4199 } 4577 }
4200 } 4578 }
4201 } 4579 }
@@ -4302,7 +4680,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4302 UUID av = new UUID(); 4680 UUID av = new UUID();
4303 if (!UUID.TryParse(agent,out av)) 4681 if (!UUID.TryParse(agent,out av))
4304 { 4682 {
4305 LSLError("First parameter to llDialog needs to be a key"); 4683 //LSLError("First parameter to llDialog needs to be a key");
4306 return; 4684 return;
4307 } 4685 }
4308 4686
@@ -4334,7 +4712,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4334 public void llCollisionSound(string impact_sound, double impact_volume) 4712 public void llCollisionSound(string impact_sound, double impact_volume)
4335 { 4713 {
4336 m_host.AddScriptLPS(1); 4714 m_host.AddScriptLPS(1);
4337 4715
4716 if(impact_sound == "")
4717 {
4718 m_host.CollisionSoundVolume = (float)impact_volume;
4719 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4720 m_host.CollisionSoundType = 0;
4721 return;
4722 }
4338 // TODO: Parameter check logic required. 4723 // TODO: Parameter check logic required.
4339 UUID soundId = UUID.Zero; 4724 UUID soundId = UUID.Zero;
4340 if (!UUID.TryParse(impact_sound, out soundId)) 4725 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4347,6 +4732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4347 4732
4348 m_host.CollisionSound = soundId; 4733 m_host.CollisionSound = soundId;
4349 m_host.CollisionSoundVolume = (float)impact_volume; 4734 m_host.CollisionSoundVolume = (float)impact_volume;
4735 m_host.CollisionSoundType = 1;
4350 } 4736 }
4351 4737
4352 public LSL_String llGetAnimation(string id) 4738 public LSL_String llGetAnimation(string id)
@@ -4360,14 +4746,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4360 4746
4361 if (m_host.RegionHandle == presence.RegionHandle) 4747 if (m_host.RegionHandle == presence.RegionHandle)
4362 { 4748 {
4363 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4364
4365 if (presence != null) 4749 if (presence != null)
4366 { 4750 {
4367 AnimationSet currentAnims = presence.Animator.Animations; 4751 if (presence.SitGround)
4368 string currentAnimationState = String.Empty; 4752 return "Sitting on Ground";
4369 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4753 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4370 return currentAnimationState; 4754 return "Sitting";
4755
4756 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4757 string lslMovementAnimation;
4758
4759 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4760 return lslMovementAnimation;
4371 } 4761 }
4372 } 4762 }
4373 4763
@@ -4514,7 +4904,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4514 { 4904 {
4515 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4905 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4516 float distance_term = distance * distance * distance; // Script Energy 4906 float distance_term = distance * distance * distance; // Script Energy
4517 float pusher_mass = m_host.GetMass(); 4907 // use total object mass and not part
4908 float pusher_mass = m_host.ParentGroup.GetMass();
4518 4909
4519 float PUSH_ATTENUATION_DISTANCE = 17f; 4910 float PUSH_ATTENUATION_DISTANCE = 17f;
4520 float PUSH_ATTENUATION_SCALE = 5f; 4911 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4764,6 +5155,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4764 { 5155 {
4765 return item.AssetID.ToString(); 5156 return item.AssetID.ToString();
4766 } 5157 }
5158 m_host.TaskInventory.LockItemsForRead(false);
4767 5159
4768 return UUID.Zero.ToString(); 5160 return UUID.Zero.ToString();
4769 } 5161 }
@@ -4897,7 +5289,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4897 public LSL_Vector llGetCenterOfMass() 5289 public LSL_Vector llGetCenterOfMass()
4898 { 5290 {
4899 m_host.AddScriptLPS(1); 5291 m_host.AddScriptLPS(1);
4900 Vector3 center = m_host.GetGeometricCenter(); 5292 Vector3 center = m_host.GetCenterOfMass();
4901 return new LSL_Vector(center.X,center.Y,center.Z); 5293 return new LSL_Vector(center.X,center.Y,center.Z);
4902 } 5294 }
4903 5295
@@ -4916,14 +5308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4916 { 5308 {
4917 m_host.AddScriptLPS(1); 5309 m_host.AddScriptLPS(1);
4918 5310
4919 if (src == null) 5311 return src.Length;
4920 {
4921 return 0;
4922 }
4923 else
4924 {
4925 return src.Length;
4926 }
4927 } 5312 }
4928 5313
4929 public LSL_Integer llList2Integer(LSL_List src, int index) 5314 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4994,7 +5379,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4994 else if (src.Data[index] is LSL_Float) 5379 else if (src.Data[index] is LSL_Float)
4995 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5380 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4996 else if (src.Data[index] is LSL_String) 5381 else if (src.Data[index] is LSL_String)
4997 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5382 {
5383 string str = ((LSL_String) src.Data[index]).m_string;
5384 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5385 if (m != Match.Empty)
5386 {
5387 str = m.Value;
5388 double d = 0.0;
5389 if (!Double.TryParse(str, out d))
5390 return 0.0;
5391
5392 return d;
5393 }
5394 return 0.0;
5395 }
4998 return Convert.ToDouble(src.Data[index]); 5396 return Convert.ToDouble(src.Data[index]);
4999 } 5397 }
5000 catch (FormatException) 5398 catch (FormatException)
@@ -5036,7 +5434,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5036 // for completion and should LSL_Key ever be implemented 5434 // for completion and should LSL_Key ever be implemented
5037 // as it's own struct 5435 // as it's own struct
5038 else if (!(src.Data[index] is LSL_String || 5436 else if (!(src.Data[index] is LSL_String ||
5039 src.Data[index] is LSL_Key)) 5437 src.Data[index] is LSL_Key ||
5438 src.Data[index] is String))
5040 { 5439 {
5041 return ""; 5440 return "";
5042 } 5441 }
@@ -5294,7 +5693,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5294 } 5693 }
5295 } 5694 }
5296 } 5695 }
5297 else { 5696 else
5697 {
5298 object[] array = new object[src.Length]; 5698 object[] array = new object[src.Length];
5299 Array.Copy(src.Data, 0, array, 0, src.Length); 5699 Array.Copy(src.Data, 0, array, 0, src.Length);
5300 result = new LSL_List(array); 5700 result = new LSL_List(array);
@@ -5401,7 +5801,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5401 public LSL_Integer llGetRegionAgentCount() 5801 public LSL_Integer llGetRegionAgentCount()
5402 { 5802 {
5403 m_host.AddScriptLPS(1); 5803 m_host.AddScriptLPS(1);
5404 return new LSL_Integer(World.GetRootAgentCount()); 5804
5805 int count = 0;
5806 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5807 count++;
5808 });
5809
5810 return new LSL_Integer(count);
5405 } 5811 }
5406 5812
5407 public LSL_Vector llGetRegionCorner() 5813 public LSL_Vector llGetRegionCorner()
@@ -5642,6 +6048,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5642 flags |= ScriptBaseClass.AGENT_AWAY; 6048 flags |= ScriptBaseClass.AGENT_AWAY;
5643 } 6049 }
5644 6050
6051 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6052 UUID[] anims = agent.Animator.GetAnimationArray();
6053 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6054 {
6055 flags |= ScriptBaseClass.AGENT_BUSY;
6056 }
6057
5645 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6058 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5646 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6059 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5647 { 6060 {
@@ -5689,6 +6102,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5689 flags |= ScriptBaseClass.AGENT_SITTING; 6102 flags |= ScriptBaseClass.AGENT_SITTING;
5690 } 6103 }
5691 6104
6105 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6106 {
6107 flags |= ScriptBaseClass.AGENT_MALE;
6108 }
6109
5692 return flags; 6110 return flags;
5693 } 6111 }
5694 6112
@@ -5836,9 +6254,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5836 6254
5837 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6255 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5838 6256
5839 foreach (SceneObjectPart part in parts) 6257 try
6258 {
6259 foreach (SceneObjectPart part in parts)
6260 {
6261 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6262 }
6263 }
6264 finally
5840 { 6265 {
5841 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5842 } 6266 }
5843 } 6267 }
5844 6268
@@ -5890,13 +6314,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5890 6314
5891 if (m_host.OwnerID == land.LandData.OwnerID) 6315 if (m_host.OwnerID == land.LandData.OwnerID)
5892 { 6316 {
5893 World.TeleportClientHome(agentID, presence.ControllingClient); 6317 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6318 presence.TeleportWithMomentum(pos, null);
6319 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5894 } 6320 }
5895 } 6321 }
5896 } 6322 }
5897 ScriptSleep(5000); 6323 ScriptSleep(5000);
5898 } 6324 }
5899 6325
6326 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6327 {
6328 return ParseString2List(str, separators, in_spacers, false);
6329 }
6330
5900 public LSL_Integer llOverMyLand(string id) 6331 public LSL_Integer llOverMyLand(string id)
5901 { 6332 {
5902 m_host.AddScriptLPS(1); 6333 m_host.AddScriptLPS(1);
@@ -5955,20 +6386,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5955 return agentSize; 6386 return agentSize;
5956 } 6387 }
5957 6388
5958 public LSL_Integer llSameGroup(string agent) 6389 public LSL_Integer llSameGroup(string id)
5959 { 6390 {
5960 m_host.AddScriptLPS(1); 6391 m_host.AddScriptLPS(1);
5961 UUID agentId = new UUID(); 6392 UUID uuid = new UUID();
5962 if (!UUID.TryParse(agent, out agentId)) 6393 if (!UUID.TryParse(id, out uuid))
5963 return new LSL_Integer(0); 6394 return new LSL_Integer(0);
5964 ScenePresence presence = World.GetScenePresence(agentId); 6395
5965 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6396 // Check if it's a group key
5966 return new LSL_Integer(0); 6397 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5967 IClientAPI client = presence.ControllingClient;
5968 if (m_host.GroupID == client.ActiveGroupId)
5969 return new LSL_Integer(1); 6398 return new LSL_Integer(1);
5970 else 6399
6400 // We got passed a UUID.Zero
6401 if (uuid == UUID.Zero)
5971 return new LSL_Integer(0); 6402 return new LSL_Integer(0);
6403
6404 // Handle the case where id names an avatar
6405 ScenePresence presence = World.GetScenePresence(uuid);
6406 if (presence != null)
6407 {
6408 if (presence.IsChildAgent)
6409 return new LSL_Integer(0);
6410
6411 IClientAPI client = presence.ControllingClient;
6412 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6413 return new LSL_Integer(1);
6414
6415 return new LSL_Integer(0);
6416 }
6417
6418 // Handle object case
6419 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6420 if (part != null)
6421 {
6422 // This will handle both deed and non-deed and also the no
6423 // group case
6424 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6425 return new LSL_Integer(1);
6426
6427 return new LSL_Integer(0);
6428 }
6429
6430 return new LSL_Integer(0);
5972 } 6431 }
5973 6432
5974 public void llUnSit(string id) 6433 public void llUnSit(string id)
@@ -6093,7 +6552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6093 return m_host.ParentGroup.AttachmentPoint; 6552 return m_host.ParentGroup.AttachmentPoint;
6094 } 6553 }
6095 6554
6096 public LSL_Integer llGetFreeMemory() 6555 public virtual LSL_Integer llGetFreeMemory()
6097 { 6556 {
6098 m_host.AddScriptLPS(1); 6557 m_host.AddScriptLPS(1);
6099 // Make scripts designed for LSO happy 6558 // Make scripts designed for LSO happy
@@ -6210,7 +6669,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6210 SetParticleSystem(m_host, rules); 6669 SetParticleSystem(m_host, rules);
6211 } 6670 }
6212 6671
6213 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6672 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6673 {
6214 6674
6215 6675
6216 if (rules.Length == 0) 6676 if (rules.Length == 0)
@@ -6524,6 +6984,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6524 6984
6525 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6985 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6526 { 6986 {
6987 // LSL quaternions can normalize to 0, normal Quaternions can't.
6988 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6989 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6990
6527 part.SitTargetPosition = offset; 6991 part.SitTargetPosition = offset;
6528 part.SitTargetOrientation = rot; 6992 part.SitTargetOrientation = rot;
6529 part.ParentGroup.HasGroupChanged = true; 6993 part.ParentGroup.HasGroupChanged = true;
@@ -6679,13 +7143,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6679 UUID av = new UUID(); 7143 UUID av = new UUID();
6680 if (!UUID.TryParse(avatar,out av)) 7144 if (!UUID.TryParse(avatar,out av))
6681 { 7145 {
6682 LSLError("First parameter to llDialog needs to be a key"); 7146 //LSLError("First parameter to llDialog needs to be a key");
6683 return; 7147 return;
6684 } 7148 }
6685 if (buttons.Length < 1) 7149 if (buttons.Length < 1)
6686 { 7150 {
6687 LSLError("No less than 1 button can be shown"); 7151 buttons.Add("OK");
6688 return;
6689 } 7152 }
6690 if (buttons.Length > 12) 7153 if (buttons.Length > 12)
6691 { 7154 {
@@ -6702,7 +7165,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6702 } 7165 }
6703 if (buttons.Data[i].ToString().Length > 24) 7166 if (buttons.Data[i].ToString().Length > 24)
6704 { 7167 {
6705 LSLError("button label cannot be longer than 24 characters"); 7168 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6706 return; 7169 return;
6707 } 7170 }
6708 buts[i] = buttons.Data[i].ToString(); 7171 buts[i] = buttons.Data[i].ToString();
@@ -6769,9 +7232,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6769 return; 7232 return;
6770 } 7233 }
6771 7234
6772 // the rest of the permission checks are done in RezScript, so check the pin there as well 7235 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6773 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7236 if (dest != null)
7237 {
7238 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7239 {
7240 // the rest of the permission checks are done in RezScript, so check the pin there as well
7241 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6774 7242
7243 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7244 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7245 }
7246 }
6775 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7247 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6776 ScriptSleep(3000); 7248 ScriptSleep(3000);
6777 } 7249 }
@@ -6834,19 +7306,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6834 public LSL_String llMD5String(string src, int nonce) 7306 public LSL_String llMD5String(string src, int nonce)
6835 { 7307 {
6836 m_host.AddScriptLPS(1); 7308 m_host.AddScriptLPS(1);
6837 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7309 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6838 } 7310 }
6839 7311
6840 public LSL_String llSHA1String(string src) 7312 public LSL_String llSHA1String(string src)
6841 { 7313 {
6842 m_host.AddScriptLPS(1); 7314 m_host.AddScriptLPS(1);
6843 return Util.SHA1Hash(src).ToLower(); 7315 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6844 } 7316 }
6845 7317
6846 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7318 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6847 { 7319 {
6848 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7320 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6849 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7321 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7322 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7323 return shapeBlock;
6850 7324
6851 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7325 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6852 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7326 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6951,6 +7425,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6951 // Prim type box, cylinder and prism. 7425 // Prim type box, cylinder and prism.
6952 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) 7426 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)
6953 { 7427 {
7428 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7429 return;
7430
6954 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7431 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6955 ObjectShapePacket.ObjectDataBlock shapeBlock; 7432 ObjectShapePacket.ObjectDataBlock shapeBlock;
6956 7433
@@ -7004,6 +7481,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7004 // Prim type sphere. 7481 // Prim type sphere.
7005 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7482 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7006 { 7483 {
7484 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7485 return;
7486
7007 ObjectShapePacket.ObjectDataBlock shapeBlock; 7487 ObjectShapePacket.ObjectDataBlock shapeBlock;
7008 7488
7009 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7489 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7045,6 +7525,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7045 // Prim type torus, tube and ring. 7525 // Prim type torus, tube and ring.
7046 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) 7526 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)
7047 { 7527 {
7528 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7529 return;
7530
7048 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7531 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7049 ObjectShapePacket.ObjectDataBlock shapeBlock; 7532 ObjectShapePacket.ObjectDataBlock shapeBlock;
7050 7533
@@ -7180,6 +7663,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7180 // Prim type sculpt. 7663 // Prim type sculpt.
7181 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7664 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7182 { 7665 {
7666 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7667 return;
7668
7183 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7669 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7184 UUID sculptId; 7670 UUID sculptId;
7185 7671
@@ -7204,7 +7690,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7204 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7690 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7205 { 7691 {
7206 // default 7692 // default
7207 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7693 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7208 } 7694 }
7209 7695
7210 part.Shape.SetSculptProperties((byte)type, sculptId); 7696 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7221,48 +7707,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7221 ScriptSleep(200); 7707 ScriptSleep(200);
7222 } 7708 }
7223 7709
7224 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7710 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7225 { 7711 {
7226 m_host.AddScriptLPS(1); 7712 m_host.AddScriptLPS(1);
7227 7713
7228 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7714 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7229 7715
7230 ScriptSleep(200); 7716 ScriptSleep(200);
7231 } 7717 }
7232 7718
7233 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7719 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7234 { 7720 {
7235 m_host.AddScriptLPS(1); 7721 List<object> parts = new List<object>();
7722 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7723 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7724 foreach (SceneObjectPart p in prims)
7725 parts.Add(p);
7726 foreach (ScenePresence p in avatars)
7727 parts.Add(p);
7236 7728
7237 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7729 LSL_List remaining = null;
7730 uint rulesParsed = 0;
7731
7732 if (parts.Count > 0)
7733 {
7734 foreach (object part in parts)
7735 {
7736 if (part is SceneObjectPart)
7737 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7738 else
7739 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7740 }
7741
7742 while ((object)remaining != null && remaining.Length > 2)
7743 {
7744 linknumber = remaining.GetLSLIntegerItem(0);
7745 rules = remaining.GetSublist(1, -1);
7746 parts.Clear();
7747 prims = GetLinkParts(linknumber);
7748 avatars = GetLinkAvatars(linknumber);
7749 foreach (SceneObjectPart p in prims)
7750 parts.Add(p);
7751 foreach (ScenePresence p in avatars)
7752 parts.Add(p);
7753
7754 remaining = null;
7755 foreach (object part in parts)
7756 {
7757 if (part is SceneObjectPart)
7758 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7759 else
7760 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7761 }
7762 }
7763 }
7238 } 7764 }
7239 7765
7240 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7766 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7767 float material_density, float material_friction,
7768 float material_restitution, float material_gravity_modifier)
7241 { 7769 {
7242 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7770 ExtraPhysicsData physdata = new ExtraPhysicsData();
7771 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7772 physdata.Density = part.Density;
7773 physdata.Friction = part.Friction;
7774 physdata.Bounce = part.Bounciness;
7775 physdata.GravitationModifier = part.GravityModifier;
7243 7776
7244 LSL_List remaining = null; 7777 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7245 uint rulesParsed = 0; 7778 physdata.Density = material_density;
7779 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7780 physdata.Friction = material_friction;
7781 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7782 physdata.Bounce = material_restitution;
7783 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7784 physdata.GravitationModifier = material_gravity_modifier;
7246 7785
7247 foreach (SceneObjectPart part in parts) 7786 part.UpdateExtraPhysics(physdata);
7248 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7787 }
7249 7788
7250 while (remaining != null && remaining.Length > 2) 7789 public void llSetPhysicsMaterial(int material_bits,
7251 { 7790 float material_gravity_modifier, float material_restitution,
7252 linknumber = remaining.GetLSLIntegerItem(0); 7791 float material_friction, float material_density)
7253 rules = remaining.GetSublist(1, -1); 7792 {
7254 parts = GetLinkParts(linknumber); 7793 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7794 }
7255 7795
7256 foreach (SceneObjectPart part in parts) 7796 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7257 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7797 {
7798 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7799 llSetLinkPrimitiveParamsFast(linknumber, rules);
7800 ScriptSleep(200);
7801 }
7802
7803 // vector up using libomv (c&p from sop )
7804 // vector up rotated by r
7805 private Vector3 Zrot(Quaternion r)
7806 {
7807 double x, y, z, m;
7808
7809 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7810 if (Math.Abs(1.0 - m) > 0.000001)
7811 {
7812 m = 1.0 / Math.Sqrt(m);
7813 r.X *= (float)m;
7814 r.Y *= (float)m;
7815 r.Z *= (float)m;
7816 r.W *= (float)m;
7258 } 7817 }
7818
7819 x = 2 * (r.X * r.Z + r.Y * r.W);
7820 y = 2 * (-r.X * r.W + r.Y * r.Z);
7821 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7822
7823 return new Vector3((float)x, (float)y, (float)z);
7259 } 7824 }
7260 7825
7261 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7826 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7262 { 7827 {
7828 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7829 return null;
7830
7263 int idx = 0; 7831 int idx = 0;
7264 int idxStart = 0; 7832 int idxStart = 0;
7265 7833
7834 SceneObjectGroup parentgrp = part.ParentGroup;
7835
7266 bool positionChanged = false; 7836 bool positionChanged = false;
7267 LSL_Vector currentPosition = GetPartLocalPos(part); 7837 LSL_Vector currentPosition = GetPartLocalPos(part);
7268 7838
@@ -7287,8 +7857,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7287 return null; 7857 return null;
7288 7858
7289 v=rules.GetVector3Item(idx++); 7859 v=rules.GetVector3Item(idx++);
7290 positionChanged = true;
7291 currentPosition = GetSetPosTarget(part, v, currentPosition); 7860 currentPosition = GetSetPosTarget(part, v, currentPosition);
7861 positionChanged = true;
7292 7862
7293 break; 7863 break;
7294 case (int)ScriptBaseClass.PRIM_SIZE: 7864 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7565,7 +8135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7565 return null; 8135 return null;
7566 8136
7567 string ph = rules.Data[idx++].ToString(); 8137 string ph = rules.Data[idx++].ToString();
7568 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8138 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7569 8139
7570 break; 8140 break;
7571 8141
@@ -7583,12 +8153,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7583 part.ScriptSetPhysicsStatus(physics); 8153 part.ScriptSetPhysicsStatus(physics);
7584 break; 8154 break;
7585 8155
8156 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8157 if (remain < 1)
8158 return null;
8159
8160 int shape_type = rules.GetLSLIntegerItem(idx++);
8161
8162 ExtraPhysicsData physdata = new ExtraPhysicsData();
8163 physdata.Density = part.Density;
8164 physdata.Bounce = part.Bounciness;
8165 physdata.GravitationModifier = part.GravityModifier;
8166 physdata.PhysShapeType = (PhysShapeType)shape_type;
8167
8168 part.UpdateExtraPhysics(physdata);
8169
8170 break;
8171
8172 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8173 if (remain < 5)
8174 return null;
8175
8176 int material_bits = rules.GetLSLIntegerItem(idx++);
8177 float material_density = (float)rules.GetLSLFloatItem(idx++);
8178 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8179 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8180 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8181
8182 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8183
8184 break;
8185
7586 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8186 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7587 if (remain < 1) 8187 if (remain < 1)
7588 return null; 8188 return null;
7589 string temp = rules.Data[idx++].ToString(); 8189 string temp = rules.Data[idx++].ToString();
7590 8190
7591 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8191 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7592 8192
7593 break; 8193 break;
7594 8194
@@ -7662,7 +8262,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7662 if (part.ParentGroup.RootPart == part) 8262 if (part.ParentGroup.RootPart == part)
7663 { 8263 {
7664 SceneObjectGroup parent = part.ParentGroup; 8264 SceneObjectGroup parent = part.ParentGroup;
7665 parent.UpdateGroupPosition(currentPosition); 8265 Util.FireAndForget(delegate(object x) {
8266 parent.UpdateGroupPosition(currentPosition);
8267 });
7666 } 8268 }
7667 else 8269 else
7668 { 8270 {
@@ -7707,10 +8309,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7707 8309
7708 public LSL_String llXorBase64Strings(string str1, string str2) 8310 public LSL_String llXorBase64Strings(string str1, string str2)
7709 { 8311 {
7710 m_host.AddScriptLPS(1); 8312 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7711 Deprecated("llXorBase64Strings"); 8313
7712 ScriptSleep(300); 8314 ScriptSleep(300);
7713 return String.Empty; 8315 m_host.AddScriptLPS(1);
8316
8317 if (str1 == String.Empty)
8318 return String.Empty;
8319 if (str2 == String.Empty)
8320 return str1;
8321
8322 int len = str2.Length;
8323 if ((len % 4) != 0) // LL is EVIL!!!!
8324 {
8325 while (str2.EndsWith("="))
8326 str2 = str2.Substring(0, str2.Length - 1);
8327
8328 len = str2.Length;
8329 int mod = len % 4;
8330
8331 if (mod == 1)
8332 str2 = str2.Substring(0, str2.Length - 1);
8333 else if (mod == 2)
8334 str2 += "==";
8335 else if (mod == 3)
8336 str2 += "=";
8337 }
8338
8339 byte[] data1;
8340 byte[] data2;
8341 try
8342 {
8343 data1 = Convert.FromBase64String(str1);
8344 data2 = Convert.FromBase64String(str2);
8345 }
8346 catch (Exception)
8347 {
8348 return new LSL_String(String.Empty);
8349 }
8350
8351 // For cases where the decoded length of s2 is greater
8352 // than the decoded length of s1, simply perform a normal
8353 // decode and XOR
8354 //
8355 if (data2.Length >= data1.Length)
8356 {
8357 for (int pos = 0 ; pos < data1.Length ; pos++ )
8358 data1[pos] ^= data2[pos];
8359
8360 return Convert.ToBase64String(data1);
8361 }
8362
8363 // Remove padding
8364 while (str1.EndsWith("="))
8365 str1 = str1.Substring(0, str1.Length - 1);
8366 while (str2.EndsWith("="))
8367 str2 = str2.Substring(0, str2.Length - 1);
8368
8369 byte[] d1 = new byte[str1.Length];
8370 byte[] d2 = new byte[str2.Length];
8371
8372 for (int i = 0 ; i < str1.Length ; i++)
8373 {
8374 int idx = b64.IndexOf(str1.Substring(i, 1));
8375 if (idx == -1)
8376 idx = 0;
8377 d1[i] = (byte)idx;
8378 }
8379
8380 for (int i = 0 ; i < str2.Length ; i++)
8381 {
8382 int idx = b64.IndexOf(str2.Substring(i, 1));
8383 if (idx == -1)
8384 idx = 0;
8385 d2[i] = (byte)idx;
8386 }
8387
8388 string output = String.Empty;
8389
8390 for (int pos = 0 ; pos < d1.Length ; pos++)
8391 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8392
8393 while (output.Length % 3 > 0)
8394 output += "=";
8395
8396 return output;
7714 } 8397 }
7715 8398
7716 public void llRemoteDataSetRegion() 8399 public void llRemoteDataSetRegion()
@@ -7834,13 +8517,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7834 public LSL_Integer llGetNumberOfPrims() 8517 public LSL_Integer llGetNumberOfPrims()
7835 { 8518 {
7836 m_host.AddScriptLPS(1); 8519 m_host.AddScriptLPS(1);
7837 int avatarCount = 0; 8520 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7838 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8521
7839 {
7840 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7841 avatarCount++;
7842 });
7843
7844 return m_host.ParentGroup.PrimCount + avatarCount; 8522 return m_host.ParentGroup.PrimCount + avatarCount;
7845 } 8523 }
7846 8524
@@ -7856,55 +8534,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7856 m_host.AddScriptLPS(1); 8534 m_host.AddScriptLPS(1);
7857 UUID objID = UUID.Zero; 8535 UUID objID = UUID.Zero;
7858 LSL_List result = new LSL_List(); 8536 LSL_List result = new LSL_List();
8537
8538 // If the ID is not valid, return null result
7859 if (!UUID.TryParse(obj, out objID)) 8539 if (!UUID.TryParse(obj, out objID))
7860 { 8540 {
7861 result.Add(new LSL_Vector()); 8541 result.Add(new LSL_Vector());
7862 result.Add(new LSL_Vector()); 8542 result.Add(new LSL_Vector());
7863 return result; 8543 return result;
7864 } 8544 }
8545
8546 // Check if this is an attached prim. If so, replace
8547 // the UUID with the avatar UUID and report it's bounding box
8548 SceneObjectPart part = World.GetSceneObjectPart(objID);
8549 if (part != null && part.ParentGroup.IsAttachment)
8550 objID = part.ParentGroup.AttachedAvatar;
8551
8552 // Find out if this is an avatar ID. If so, return it's box
7865 ScenePresence presence = World.GetScenePresence(objID); 8553 ScenePresence presence = World.GetScenePresence(objID);
7866 if (presence != null) 8554 if (presence != null)
7867 { 8555 {
7868 if (presence.ParentID == 0) // not sat on an object 8556 // As per LSL Wiki, there is no difference between sitting
8557 // and standing avatar since server 1.36
8558 LSL_Vector lower;
8559 LSL_Vector upper;
8560 if (presence.Animator.Animations.DefaultAnimation.AnimID
8561 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7869 { 8562 {
7870 LSL_Vector lower; 8563 // This is for ground sitting avatars
7871 LSL_Vector upper; 8564 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7872 if (presence.Animator.Animations.DefaultAnimation.AnimID 8565 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7873 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8566 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7874 {
7875 // This is for ground sitting avatars
7876 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7877 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7878 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7879 }
7880 else
7881 {
7882 // This is for standing/flying avatars
7883 float height = presence.Appearance.AvatarHeight / 2.0f;
7884 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7885 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7886 }
7887 result.Add(lower);
7888 result.Add(upper);
7889 return result;
7890 } 8567 }
7891 else 8568 else
7892 { 8569 {
7893 // sitting on an object so we need the bounding box of that 8570 // This is for standing/flying avatars
7894 // which should include the avatar so set the UUID to the 8571 float height = presence.Appearance.AvatarHeight / 2.0f;
7895 // UUID of the object the avatar is sat on and allow it to fall through 8572 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7896 // to processing an object 8573 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7897 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7898 objID = p.UUID;
7899 } 8574 }
8575
8576 // Adjust to the documented error offsets (see LSL Wiki)
8577 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8578 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8579
8580 if (lower.x > upper.x)
8581 lower.x = upper.x;
8582 if (lower.y > upper.y)
8583 lower.y = upper.y;
8584 if (lower.z > upper.z)
8585 lower.z = upper.z;
8586
8587 result.Add(lower);
8588 result.Add(upper);
8589 return result;
7900 } 8590 }
7901 SceneObjectPart part = World.GetSceneObjectPart(objID); 8591
8592 part = World.GetSceneObjectPart(objID);
7902 // Currently only works for single prims without a sitting avatar 8593 // Currently only works for single prims without a sitting avatar
7903 if (part != null) 8594 if (part != null)
7904 { 8595 {
7905 Vector3 halfSize = part.Scale / 2.0f; 8596 float minX;
7906 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8597 float maxX;
7907 LSL_Vector upper = new LSL_Vector(halfSize); 8598 float minY;
8599 float maxY;
8600 float minZ;
8601 float maxZ;
8602
8603 // This BBox is in sim coordinates, with the offset being
8604 // a contained point.
8605 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8606 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8607
8608 minX -= offsets[0].X;
8609 maxX -= offsets[0].X;
8610 minY -= offsets[0].Y;
8611 maxY -= offsets[0].Y;
8612 minZ -= offsets[0].Z;
8613 maxZ -= offsets[0].Z;
8614
8615 LSL_Vector lower;
8616 LSL_Vector upper;
8617
8618 // Adjust to the documented error offsets (see LSL Wiki)
8619 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8620 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8621
8622 if (lower.x > upper.x)
8623 lower.x = upper.x;
8624 if (lower.y > upper.y)
8625 lower.y = upper.y;
8626 if (lower.z > upper.z)
8627 lower.z = upper.z;
8628
7908 result.Add(lower); 8629 result.Add(lower);
7909 result.Add(upper); 8630 result.Add(upper);
7910 return result; 8631 return result;
@@ -7918,7 +8639,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7918 8639
7919 public LSL_Vector llGetGeometricCenter() 8640 public LSL_Vector llGetGeometricCenter()
7920 { 8641 {
7921 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8642 Vector3 tmp = m_host.GetGeometricCenter();
8643 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7922 } 8644 }
7923 8645
7924 public LSL_List llGetPrimitiveParams(LSL_List rules) 8646 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7946,24 +8668,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7946 { 8668 {
7947 m_host.AddScriptLPS(1); 8669 m_host.AddScriptLPS(1);
7948 8670
7949 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8671 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8672 // keep other options as before
7950 8673
8674 List<SceneObjectPart> parts;
8675 List<ScenePresence> avatars;
8676
7951 LSL_List res = new LSL_List(); 8677 LSL_List res = new LSL_List();
7952 LSL_List remaining = null; 8678 LSL_List remaining = null;
7953 8679
7954 foreach (SceneObjectPart part in parts) 8680 while (rules.Length > 0)
7955 {
7956 remaining = GetPrimParams(part, rules, ref res);
7957 }
7958
7959 while (remaining != null && remaining.Length > 2)
7960 { 8681 {
7961 linknumber = remaining.GetLSLIntegerItem(0);
7962 rules = remaining.GetSublist(1, -1);
7963 parts = GetLinkParts(linknumber); 8682 parts = GetLinkParts(linknumber);
8683 avatars = GetLinkAvatars(linknumber);
7964 8684
8685 remaining = null;
7965 foreach (SceneObjectPart part in parts) 8686 foreach (SceneObjectPart part in parts)
8687 {
7966 remaining = GetPrimParams(part, rules, ref res); 8688 remaining = GetPrimParams(part, rules, ref res);
8689 }
8690 foreach (ScenePresence avatar in avatars)
8691 {
8692 remaining = GetPrimParams(avatar, rules, ref res);
8693 }
8694
8695 if (remaining != null && remaining.Length > 0)
8696 {
8697 linknumber = remaining.GetLSLIntegerItem(0);
8698 rules = remaining.GetSublist(1, -1);
8699 }
7967 } 8700 }
7968 8701
7969 return res; 8702 return res;
@@ -8008,13 +8741,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8008 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8741 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8009 part.AbsolutePosition.Y, 8742 part.AbsolutePosition.Y,
8010 part.AbsolutePosition.Z); 8743 part.AbsolutePosition.Z);
8011 // For some reason, the part.AbsolutePosition.* values do not change if the
8012 // linkset is rotated; they always reflect the child prim's world position
8013 // as though the linkset is unrotated. This is incompatible behavior with SL's
8014 // implementation, so will break scripts imported from there (not to mention it
8015 // makes it more difficult to determine a child prim's actual inworld position).
8016 if (part.ParentID != 0)
8017 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8018 res.Add(v); 8744 res.Add(v);
8019 break; 8745 break;
8020 8746
@@ -8186,30 +8912,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8186 if (remain < 1) 8912 if (remain < 1)
8187 return null; 8913 return null;
8188 8914
8189 face=(int)rules.GetLSLIntegerItem(idx++); 8915 face = (int)rules.GetLSLIntegerItem(idx++);
8190 8916
8191 tex = part.Shape.Textures; 8917 tex = part.Shape.Textures;
8918 int shiny;
8192 if (face == ScriptBaseClass.ALL_SIDES) 8919 if (face == ScriptBaseClass.ALL_SIDES)
8193 { 8920 {
8194 for (face = 0; face < GetNumberOfSides(part); face++) 8921 for (face = 0; face < GetNumberOfSides(part); face++)
8195 { 8922 {
8196 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8923 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8197 // Convert Shininess to PRIM_SHINY_* 8924 if (shinyness == Shininess.High)
8198 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8925 {
8199 // PRIM_BUMP_* 8926 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8200 res.Add(new LSL_Integer((int)texface.Bump)); 8927 }
8928 else if (shinyness == Shininess.Medium)
8929 {
8930 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8931 }
8932 else if (shinyness == Shininess.Low)
8933 {
8934 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8935 }
8936 else
8937 {
8938 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8939 }
8940 res.Add(new LSL_Integer(shiny));
8941 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8201 } 8942 }
8202 } 8943 }
8203 else 8944 else
8204 { 8945 {
8205 if (face >= 0 && face < GetNumberOfSides(part)) 8946 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8947 if (shinyness == Shininess.High)
8206 { 8948 {
8207 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8949 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8208 // Convert Shininess to PRIM_SHINY_*
8209 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8210 // PRIM_BUMP_*
8211 res.Add(new LSL_Integer((int)texface.Bump));
8212 } 8950 }
8951 else if (shinyness == Shininess.Medium)
8952 {
8953 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8954 }
8955 else if (shinyness == Shininess.Low)
8956 {
8957 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8958 }
8959 else
8960 {
8961 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8962 }
8963 res.Add(new LSL_Integer(shiny));
8964 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8213 } 8965 }
8214 break; 8966 break;
8215 8967
@@ -8217,24 +8969,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8217 if (remain < 1) 8969 if (remain < 1)
8218 return null; 8970 return null;
8219 8971
8220 face=(int)rules.GetLSLIntegerItem(idx++); 8972 face = (int)rules.GetLSLIntegerItem(idx++);
8221 8973
8222 tex = part.Shape.Textures; 8974 tex = part.Shape.Textures;
8975 int fullbright;
8223 if (face == ScriptBaseClass.ALL_SIDES) 8976 if (face == ScriptBaseClass.ALL_SIDES)
8224 { 8977 {
8225 for (face = 0; face < GetNumberOfSides(part); face++) 8978 for (face = 0; face < GetNumberOfSides(part); face++)
8226 { 8979 {
8227 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8980 if (tex.GetFace((uint)face).Fullbright == true)
8228 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8981 {
8982 fullbright = ScriptBaseClass.TRUE;
8983 }
8984 else
8985 {
8986 fullbright = ScriptBaseClass.FALSE;
8987 }
8988 res.Add(new LSL_Integer(fullbright));
8229 } 8989 }
8230 } 8990 }
8231 else 8991 else
8232 { 8992 {
8233 if (face >= 0 && face < GetNumberOfSides(part)) 8993 if (tex.GetFace((uint)face).Fullbright == true)
8234 { 8994 {
8235 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8995 fullbright = ScriptBaseClass.TRUE;
8236 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8996 }
8997 else
8998 {
8999 fullbright = ScriptBaseClass.FALSE;
8237 } 9000 }
9001 res.Add(new LSL_Integer(fullbright));
8238 } 9002 }
8239 break; 9003 break;
8240 9004
@@ -8256,27 +9020,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8256 break; 9020 break;
8257 9021
8258 case (int)ScriptBaseClass.PRIM_TEXGEN: 9022 case (int)ScriptBaseClass.PRIM_TEXGEN:
9023 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8259 if (remain < 1) 9024 if (remain < 1)
8260 return null; 9025 return null;
8261 9026
8262 face=(int)rules.GetLSLIntegerItem(idx++); 9027 face = (int)rules.GetLSLIntegerItem(idx++);
8263 9028
8264 tex = part.Shape.Textures; 9029 tex = part.Shape.Textures;
8265 if (face == ScriptBaseClass.ALL_SIDES) 9030 if (face == ScriptBaseClass.ALL_SIDES)
8266 { 9031 {
8267 for (face = 0; face < GetNumberOfSides(part); face++) 9032 for (face = 0; face < GetNumberOfSides(part); face++)
8268 { 9033 {
8269 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9034 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8270 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9035 {
8271 res.Add(new LSL_Integer((uint)texgen >> 1)); 9036 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9037 }
9038 else
9039 {
9040 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9041 }
8272 } 9042 }
8273 } 9043 }
8274 else 9044 else
8275 { 9045 {
8276 if (face >= 0 && face < GetNumberOfSides(part)) 9046 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9047 {
9048 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9049 }
9050 else
8277 { 9051 {
8278 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9052 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8279 res.Add(new LSL_Integer((uint)texgen >> 1));
8280 } 9053 }
8281 } 9054 }
8282 break; 9055 break;
@@ -8300,24 +9073,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8300 if (remain < 1) 9073 if (remain < 1)
8301 return null; 9074 return null;
8302 9075
8303 face=(int)rules.GetLSLIntegerItem(idx++); 9076 face = (int)rules.GetLSLIntegerItem(idx++);
8304 9077
8305 tex = part.Shape.Textures; 9078 tex = part.Shape.Textures;
9079 float primglow;
8306 if (face == ScriptBaseClass.ALL_SIDES) 9080 if (face == ScriptBaseClass.ALL_SIDES)
8307 { 9081 {
8308 for (face = 0; face < GetNumberOfSides(part); face++) 9082 for (face = 0; face < GetNumberOfSides(part); face++)
8309 { 9083 {
8310 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9084 primglow = tex.GetFace((uint)face).Glow;
8311 res.Add(new LSL_Float(texface.Glow)); 9085 res.Add(new LSL_Float(primglow));
8312 } 9086 }
8313 } 9087 }
8314 else 9088 else
8315 { 9089 {
8316 if (face >= 0 && face < GetNumberOfSides(part)) 9090 primglow = tex.GetFace((uint)face).Glow;
8317 { 9091 res.Add(new LSL_Float(primglow));
8318 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8319 res.Add(new LSL_Float(texface.Glow));
8320 }
8321 } 9092 }
8322 break; 9093 break;
8323 9094
@@ -8329,15 +9100,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8329 textColor.B)); 9100 textColor.B));
8330 res.Add(new LSL_Float(textColor.A)); 9101 res.Add(new LSL_Float(textColor.A));
8331 break; 9102 break;
9103
8332 case (int)ScriptBaseClass.PRIM_NAME: 9104 case (int)ScriptBaseClass.PRIM_NAME:
8333 res.Add(new LSL_String(part.Name)); 9105 res.Add(new LSL_String(part.Name));
8334 break; 9106 break;
9107
8335 case (int)ScriptBaseClass.PRIM_DESC: 9108 case (int)ScriptBaseClass.PRIM_DESC:
8336 res.Add(new LSL_String(part.Description)); 9109 res.Add(new LSL_String(part.Description));
8337 break; 9110 break;
9111
8338 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9112 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8339 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9113 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8340 break; 9114 break;
9115
8341 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9116 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8342 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9117 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8343 break; 9118 break;
@@ -8948,8 +9723,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8948 // The function returns an ordered list 9723 // The function returns an ordered list
8949 // representing the tokens found in the supplied 9724 // representing the tokens found in the supplied
8950 // sources string. If two successive tokenizers 9725 // sources string. If two successive tokenizers
8951 // are encountered, then a NULL entry is added 9726 // are encountered, then a null-string entry is
8952 // to the list. 9727 // added to the list.
8953 // 9728 //
8954 // It is a precondition that the source and 9729 // It is a precondition that the source and
8955 // toekizer lisst are non-null. If they are null, 9730 // toekizer lisst are non-null. If they are null,
@@ -8957,7 +9732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8957 // while their lengths are being determined. 9732 // while their lengths are being determined.
8958 // 9733 //
8959 // A small amount of working memoryis required 9734 // A small amount of working memoryis required
8960 // of approximately 8*#tokenizers. 9735 // of approximately 8*#tokenizers + 8*srcstrlen.
8961 // 9736 //
8962 // There are many ways in which this function 9737 // There are many ways in which this function
8963 // can be implemented, this implementation is 9738 // can be implemented, this implementation is
@@ -8973,155 +9748,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8973 // and eliminates redundant tokenizers as soon 9748 // and eliminates redundant tokenizers as soon
8974 // as is possible. 9749 // as is possible.
8975 // 9750 //
8976 // The implementation tries to avoid any copying 9751 // The implementation tries to minimize temporary
8977 // of arrays or other objects. 9752 // garbage generation.
8978 // </remarks> 9753 // </remarks>
8979 9754
8980 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9755 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8981 { 9756 {
8982 int beginning = 0; 9757 return ParseString2List(src, separators, spacers, true);
8983 int srclen = src.Length; 9758 }
8984 int seplen = separators.Length;
8985 object[] separray = separators.Data;
8986 int spclen = spacers.Length;
8987 object[] spcarray = spacers.Data;
8988 int mlen = seplen+spclen;
8989
8990 int[] offset = new int[mlen+1];
8991 bool[] active = new bool[mlen];
8992
8993 int best;
8994 int j;
8995
8996 // Initial capacity reduces resize cost
8997 9759
8998 LSL_List tokens = new LSL_List(); 9760 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9761 {
9762 int srclen = src.Length;
9763 int seplen = separators.Length;
9764 object[] separray = separators.Data;
9765 int spclen = spacers.Length;
9766 object[] spcarray = spacers.Data;
9767 int dellen = 0;
9768 string[] delarray = new string[seplen+spclen];
8999 9769
9000 // All entries are initially valid 9770 int outlen = 0;
9771 string[] outarray = new string[srclen*2+1];
9001 9772
9002 for (int i = 0; i < mlen; i++) 9773 int i, j;
9003 active[i] = true; 9774 string d;
9004 9775
9005 offset[mlen] = srclen; 9776 m_host.AddScriptLPS(1);
9006 9777
9007 while (beginning < srclen) 9778 /*
9779 * Convert separator and spacer lists to C# strings.
9780 * Also filter out null strings so we don't hang.
9781 */
9782 for (i = 0; i < seplen; i ++)
9008 { 9783 {
9784 d = separray[i].ToString();
9785 if (d.Length > 0)
9786 {
9787 delarray[dellen++] = d;
9788 }
9789 }
9790 seplen = dellen;
9009 9791
9010 best = mlen; // as bad as it gets 9792 for (i = 0; i < spclen; i ++)
9793 {
9794 d = spcarray[i].ToString();
9795 if (d.Length > 0)
9796 {
9797 delarray[dellen++] = d;
9798 }
9799 }
9011 9800
9012 // Scan for separators 9801 /*
9802 * Scan through source string from beginning to end.
9803 */
9804 for (i = 0;;)
9805 {
9013 9806
9014 for (j = 0; j < seplen; j++) 9807 /*
9808 * Find earliest delimeter in src starting at i (if any).
9809 */
9810 int earliestDel = -1;
9811 int earliestSrc = srclen;
9812 string earliestStr = null;
9813 for (j = 0; j < dellen; j ++)
9015 { 9814 {
9016 if (separray[j].ToString() == String.Empty) 9815 d = delarray[j];
9017 active[j] = false; 9816 if (d != null)
9018
9019 if (active[j])
9020 { 9817 {
9021 // scan all of the markers 9818 int index = src.IndexOf(d, i);
9022 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9819 if (index < 0)
9023 { 9820 {
9024 // not present at all 9821 delarray[j] = null; // delim nowhere in src, don't check it anymore
9025 active[j] = false;
9026 } 9822 }
9027 else 9823 else if (index < earliestSrc)
9028 { 9824 {
9029 // present and correct 9825 earliestSrc = index; // where delimeter starts in source string
9030 if (offset[j] < offset[best]) 9826 earliestDel = j; // where delimeter is in delarray[]
9031 { 9827 earliestStr = d; // the delimeter string from delarray[]
9032 // closest so far 9828 if (index == i) break; // can't do any better than found at beg of string
9033 best = j;
9034 if (offset[best] == beginning)
9035 break;
9036 }
9037 } 9829 }
9038 } 9830 }
9039 } 9831 }
9040 9832
9041 // Scan for spacers 9833 /*
9042 9834 * Output source string starting at i through start of earliest delimeter.
9043 if (offset[best] != beginning) 9835 */
9836 if (keepNulls || (earliestSrc > i))
9044 { 9837 {
9045 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9838 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9046 {
9047 if (spcarray[j-seplen].ToString() == String.Empty)
9048 active[j] = false;
9049
9050 if (active[j])
9051 {
9052 // scan all of the markers
9053 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9054 {
9055 // not present at all
9056 active[j] = false;
9057 }
9058 else
9059 {
9060 // present and correct
9061 if (offset[j] < offset[best])
9062 {
9063 // closest so far
9064 best = j;
9065 }
9066 }
9067 }
9068 }
9069 } 9839 }
9070 9840
9071 // This is the normal exit from the scanning loop 9841 /*
9842 * If no delimeter found at or after i, we're done scanning.
9843 */
9844 if (earliestDel < 0) break;
9072 9845
9073 if (best == mlen) 9846 /*
9847 * If delimeter was a spacer, output the spacer.
9848 */
9849 if (earliestDel >= seplen)
9074 { 9850 {
9075 // no markers were found on this pass 9851 outarray[outlen++] = earliestStr;
9076 // so we're pretty much done
9077 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9078 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9079 break;
9080 } 9852 }
9081 9853
9082 // Otherwise we just add the newly delimited token 9854 /*
9083 // and recalculate where the search should continue. 9855 * Look at rest of src string following delimeter.
9084 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9856 */
9085 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9857 i = earliestSrc + earliestStr.Length;
9086
9087 if (best < seplen)
9088 {
9089 beginning = offset[best] + (separray[best].ToString()).Length;
9090 }
9091 else
9092 {
9093 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9094 string str = spcarray[best - seplen].ToString();
9095 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9096 tokens.Add(new LSL_String(str));
9097 }
9098 } 9858 }
9099 9859
9100 // This an awkward an not very intuitive boundary case. If the 9860 /*
9101 // last substring is a tokenizer, then there is an implied trailing 9861 * Make up an exact-sized output array suitable for an LSL_List object.
9102 // null list entry. Hopefully the single comparison will not be too 9862 */
9103 // arduous. Alternatively the 'break' could be replced with a return 9863 object[] outlist = new object[outlen];
9104 // but that's shabby programming. 9864 for (i = 0; i < outlen; i ++)
9105
9106 if ((beginning == srclen) && (keepNulls))
9107 { 9865 {
9108 if (srclen != 0) 9866 outlist[i] = new LSL_String(outarray[i]);
9109 tokens.Add(new LSL_String(""));
9110 } 9867 }
9111 9868 return new LSL_List(outlist);
9112 return tokens;
9113 }
9114
9115 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9116 {
9117 m_host.AddScriptLPS(1);
9118 return this.ParseString(src, separators, spacers, false);
9119 }
9120
9121 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9122 {
9123 m_host.AddScriptLPS(1);
9124 return this.ParseString(src, separators, spacers, true);
9125 } 9869 }
9126 9870
9127 public LSL_Integer llGetObjectPermMask(int mask) 9871 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9216,6 +9960,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9216 case 4: 9960 case 4:
9217 return (int)item.NextPermissions; 9961 return (int)item.NextPermissions;
9218 } 9962 }
9963 m_host.TaskInventory.LockItemsForRead(false);
9219 9964
9220 return -1; 9965 return -1;
9221 } 9966 }
@@ -9406,9 +10151,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9406 { 10151 {
9407 try 10152 try
9408 { 10153 {
10154 /*
9409 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10155 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9410 if (obj != null) 10156 if (obj != null)
9411 return (double)obj.GetMass(); 10157 return (double)obj.GetMass();
10158 */
10159 // return total object mass
10160 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10161 if (obj != null)
10162 return obj.GetMass();
10163
9412 // the object is null so the key is for an avatar 10164 // the object is null so the key is for an avatar
9413 ScenePresence avatar = World.GetScenePresence(key); 10165 ScenePresence avatar = World.GetScenePresence(key);
9414 if (avatar != null) 10166 if (avatar != null)
@@ -9428,7 +10180,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9428 } 10180 }
9429 10181
9430 /// <summary> 10182 /// <summary>
9431 /// illListReplaceList removes the sub-list defined by the inclusive indices 10183 /// llListReplaceList removes the sub-list defined by the inclusive indices
9432 /// start and end and inserts the src list in its place. The inclusive 10184 /// start and end and inserts the src list in its place. The inclusive
9433 /// nature of the indices means that at least one element must be deleted 10185 /// nature of the indices means that at least one element must be deleted
9434 /// if the indices are within the bounds of the existing list. I.e. 2,2 10186 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9485,16 +10237,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9485 // based upon end. Note that if end exceeds the upper 10237 // based upon end. Note that if end exceeds the upper
9486 // bound in this case, the entire destination list 10238 // bound in this case, the entire destination list
9487 // is removed. 10239 // is removed.
9488 else 10240 else if (start == 0)
9489 { 10241 {
9490 if (end + 1 < dest.Length) 10242 if (end + 1 < dest.Length)
9491 {
9492 return src + dest.GetSublist(end + 1, -1); 10243 return src + dest.GetSublist(end + 1, -1);
9493 }
9494 else 10244 else
9495 {
9496 return src; 10245 return src;
9497 } 10246 }
10247 else // Start < 0
10248 {
10249 if (end + 1 < dest.Length)
10250 return dest.GetSublist(end + 1, -1);
10251 else
10252 return new LSL_List();
9498 } 10253 }
9499 } 10254 }
9500 // Finally, if start > end, we strip away a prefix and 10255 // Finally, if start > end, we strip away a prefix and
@@ -9545,17 +10300,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9545 int width = 0; 10300 int width = 0;
9546 int height = 0; 10301 int height = 0;
9547 10302
9548 ParcelMediaCommandEnum? commandToSend = null; 10303 uint commandToSend = 0;
9549 float time = 0.0f; // default is from start 10304 float time = 0.0f; // default is from start
9550 10305
9551 ScenePresence presence = null; 10306 ScenePresence presence = null;
9552 10307
9553 for (int i = 0; i < commandList.Data.Length; i++) 10308 for (int i = 0; i < commandList.Data.Length; i++)
9554 { 10309 {
9555 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10310 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9556 switch (command) 10311 switch (command)
9557 { 10312 {
9558 case ParcelMediaCommandEnum.Agent: 10313 case (uint)ParcelMediaCommandEnum.Agent:
9559 // we send only to one agent 10314 // we send only to one agent
9560 if ((i + 1) < commandList.Length) 10315 if ((i + 1) < commandList.Length)
9561 { 10316 {
@@ -9572,25 +10327,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9572 } 10327 }
9573 break; 10328 break;
9574 10329
9575 case ParcelMediaCommandEnum.Loop: 10330 case (uint)ParcelMediaCommandEnum.Loop:
9576 loop = 1; 10331 loop = 1;
9577 commandToSend = command; 10332 commandToSend = command;
9578 update = true; //need to send the media update packet to set looping 10333 update = true; //need to send the media update packet to set looping
9579 break; 10334 break;
9580 10335
9581 case ParcelMediaCommandEnum.Play: 10336 case (uint)ParcelMediaCommandEnum.Play:
9582 loop = 0; 10337 loop = 0;
9583 commandToSend = command; 10338 commandToSend = command;
9584 update = true; //need to send the media update packet to make sure it doesn't loop 10339 update = true; //need to send the media update packet to make sure it doesn't loop
9585 break; 10340 break;
9586 10341
9587 case ParcelMediaCommandEnum.Pause: 10342 case (uint)ParcelMediaCommandEnum.Pause:
9588 case ParcelMediaCommandEnum.Stop: 10343 case (uint)ParcelMediaCommandEnum.Stop:
9589 case ParcelMediaCommandEnum.Unload: 10344 case (uint)ParcelMediaCommandEnum.Unload:
9590 commandToSend = command; 10345 commandToSend = command;
9591 break; 10346 break;
9592 10347
9593 case ParcelMediaCommandEnum.Url: 10348 case (uint)ParcelMediaCommandEnum.Url:
9594 if ((i + 1) < commandList.Length) 10349 if ((i + 1) < commandList.Length)
9595 { 10350 {
9596 if (commandList.Data[i + 1] is LSL_String) 10351 if (commandList.Data[i + 1] is LSL_String)
@@ -9603,7 +10358,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9603 } 10358 }
9604 break; 10359 break;
9605 10360
9606 case ParcelMediaCommandEnum.Texture: 10361 case (uint)ParcelMediaCommandEnum.Texture:
9607 if ((i + 1) < commandList.Length) 10362 if ((i + 1) < commandList.Length)
9608 { 10363 {
9609 if (commandList.Data[i + 1] is LSL_String) 10364 if (commandList.Data[i + 1] is LSL_String)
@@ -9616,7 +10371,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9616 } 10371 }
9617 break; 10372 break;
9618 10373
9619 case ParcelMediaCommandEnum.Time: 10374 case (uint)ParcelMediaCommandEnum.Time:
9620 if ((i + 1) < commandList.Length) 10375 if ((i + 1) < commandList.Length)
9621 { 10376 {
9622 if (commandList.Data[i + 1] is LSL_Float) 10377 if (commandList.Data[i + 1] is LSL_Float)
@@ -9628,7 +10383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9628 } 10383 }
9629 break; 10384 break;
9630 10385
9631 case ParcelMediaCommandEnum.AutoAlign: 10386 case (uint)ParcelMediaCommandEnum.AutoAlign:
9632 if ((i + 1) < commandList.Length) 10387 if ((i + 1) < commandList.Length)
9633 { 10388 {
9634 if (commandList.Data[i + 1] is LSL_Integer) 10389 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9642,7 +10397,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9642 } 10397 }
9643 break; 10398 break;
9644 10399
9645 case ParcelMediaCommandEnum.Type: 10400 case (uint)ParcelMediaCommandEnum.Type:
9646 if ((i + 1) < commandList.Length) 10401 if ((i + 1) < commandList.Length)
9647 { 10402 {
9648 if (commandList.Data[i + 1] is LSL_String) 10403 if (commandList.Data[i + 1] is LSL_String)
@@ -9655,7 +10410,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9655 } 10410 }
9656 break; 10411 break;
9657 10412
9658 case ParcelMediaCommandEnum.Desc: 10413 case (uint)ParcelMediaCommandEnum.Desc:
9659 if ((i + 1) < commandList.Length) 10414 if ((i + 1) < commandList.Length)
9660 { 10415 {
9661 if (commandList.Data[i + 1] is LSL_String) 10416 if (commandList.Data[i + 1] is LSL_String)
@@ -9668,7 +10423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9668 } 10423 }
9669 break; 10424 break;
9670 10425
9671 case ParcelMediaCommandEnum.Size: 10426 case (uint)ParcelMediaCommandEnum.Size:
9672 if ((i + 2) < commandList.Length) 10427 if ((i + 2) < commandList.Length)
9673 { 10428 {
9674 if (commandList.Data[i + 1] is LSL_Integer) 10429 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9738,7 +10493,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9738 } 10493 }
9739 } 10494 }
9740 10495
9741 if (commandToSend != null) 10496 if (commandToSend != 0)
9742 { 10497 {
9743 // the commandList contained a start/stop/... command, too 10498 // the commandList contained a start/stop/... command, too
9744 if (presence == null) 10499 if (presence == null)
@@ -9775,7 +10530,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9775 10530
9776 if (aList.Data[i] != null) 10531 if (aList.Data[i] != null)
9777 { 10532 {
9778 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10533 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9779 { 10534 {
9780 case ParcelMediaCommandEnum.Url: 10535 case ParcelMediaCommandEnum.Url:
9781 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10536 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9832,15 +10587,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9832 10587
9833 if (quick_pay_buttons.Data.Length < 4) 10588 if (quick_pay_buttons.Data.Length < 4)
9834 { 10589 {
9835 LSLError("List must have at least 4 elements"); 10590 int x;
9836 return; 10591 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10592 {
10593 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10594 }
9837 } 10595 }
9838 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10596 int[] nPrice = new int[5];
9839 10597 nPrice[0] = price;
9840 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10598 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9841 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10599 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9842 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10600 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9843 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10601 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10602 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9844 m_host.ParentGroup.HasGroupChanged = true; 10603 m_host.ParentGroup.HasGroupChanged = true;
9845 } 10604 }
9846 10605
@@ -9857,7 +10616,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9857 return new LSL_Vector(); 10616 return new LSL_Vector();
9858 } 10617 }
9859 10618
9860 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10619// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10620 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9861 if (presence != null) 10621 if (presence != null)
9862 { 10622 {
9863 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10623 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9879,7 +10639,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9879 return new LSL_Rotation(); 10639 return new LSL_Rotation();
9880 } 10640 }
9881 10641
9882 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10642// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10643 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9883 if (presence != null) 10644 if (presence != null)
9884 { 10645 {
9885 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10646 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9939,14 +10700,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9939 { 10700 {
9940 m_host.AddScriptLPS(1); 10701 m_host.AddScriptLPS(1);
9941 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10702 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9942 if (detectedParams == null) return; // only works on the first detected avatar 10703 if (detectedParams == null)
9943 10704 {
10705 if (m_host.ParentGroup.IsAttachment == true)
10706 {
10707 detectedParams = new DetectParams();
10708 detectedParams.Key = m_host.OwnerID;
10709 }
10710 else
10711 {
10712 return;
10713 }
10714 }
10715
9944 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10716 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9945 if (avatar != null) 10717 if (avatar != null)
9946 { 10718 {
9947 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10719 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9948 simname, pos, lookAt); 10720 simname, pos, lookAt);
9949 } 10721 }
10722
9950 ScriptSleep(1000); 10723 ScriptSleep(1000);
9951 } 10724 }
9952 10725
@@ -10070,12 +10843,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10070 10843
10071 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10844 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10072 object[] data = rules.Data; 10845 object[] data = rules.Data;
10073 for (int i = 0; i < data.Length; ++i) { 10846 for (int i = 0; i < data.Length; ++i)
10847 {
10074 int type = Convert.ToInt32(data[i++].ToString()); 10848 int type = Convert.ToInt32(data[i++].ToString());
10075 if (i >= data.Length) break; // odd number of entries => ignore the last 10849 if (i >= data.Length) break; // odd number of entries => ignore the last
10076 10850
10077 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10851 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10078 switch (type) { 10852 switch (type)
10853 {
10079 case ScriptBaseClass.CAMERA_FOCUS: 10854 case ScriptBaseClass.CAMERA_FOCUS:
10080 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10855 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10081 case ScriptBaseClass.CAMERA_POSITION: 10856 case ScriptBaseClass.CAMERA_POSITION:
@@ -10180,19 +10955,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10180 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10955 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10181 { 10956 {
10182 m_host.AddScriptLPS(1); 10957 m_host.AddScriptLPS(1);
10183 string ret = String.Empty; 10958
10184 string src1 = llBase64ToString(str1); 10959 if (str1 == String.Empty)
10185 string src2 = llBase64ToString(str2); 10960 return String.Empty;
10186 int c = 0; 10961 if (str2 == String.Empty)
10187 for (int i = 0; i < src1.Length; i++) 10962 return str1;
10963
10964 int len = str2.Length;
10965 if ((len % 4) != 0) // LL is EVIL!!!!
10188 { 10966 {
10189 ret += (char) (src1[i] ^ src2[c]); 10967 while (str2.EndsWith("="))
10968 str2 = str2.Substring(0, str2.Length - 1);
10969
10970 len = str2.Length;
10971 int mod = len % 4;
10190 10972
10191 c++; 10973 if (mod == 1)
10192 if (c >= src2.Length) 10974 str2 = str2.Substring(0, str2.Length - 1);
10193 c = 0; 10975 else if (mod == 2)
10976 str2 += "==";
10977 else if (mod == 3)
10978 str2 += "=";
10194 } 10979 }
10195 return llStringToBase64(ret); 10980
10981 byte[] data1;
10982 byte[] data2;
10983 try
10984 {
10985 data1 = Convert.FromBase64String(str1);
10986 data2 = Convert.FromBase64String(str2);
10987 }
10988 catch (Exception)
10989 {
10990 return new LSL_String(String.Empty);
10991 }
10992
10993 byte[] d2 = new Byte[data1.Length];
10994 int pos = 0;
10995
10996 if (data1.Length <= data2.Length)
10997 {
10998 Array.Copy(data2, 0, d2, 0, data1.Length);
10999 }
11000 else
11001 {
11002 while (pos < data1.Length)
11003 {
11004 len = data1.Length - pos;
11005 if (len > data2.Length)
11006 len = data2.Length;
11007
11008 Array.Copy(data2, 0, d2, pos, len);
11009 pos += len;
11010 }
11011 }
11012
11013 for (pos = 0 ; pos < data1.Length ; pos++ )
11014 data1[pos] ^= d2[pos];
11015
11016 return Convert.ToBase64String(data1);
10196 } 11017 }
10197 11018
10198 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11019 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10245,16 +11066,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10245 if (userAgent != null) 11066 if (userAgent != null)
10246 httpHeaders["User-Agent"] = userAgent; 11067 httpHeaders["User-Agent"] = userAgent;
10247 11068
11069 // See if the URL contains any header hacks
11070 string[] urlParts = url.Split(new char[] {'\n'});
11071 if (urlParts.Length > 1)
11072 {
11073 // Iterate the passed headers and parse them
11074 for (int i = 1 ; i < urlParts.Length ; i++ )
11075 {
11076 // The rest of those would be added to the body in SL.
11077 // Let's not do that.
11078 if (urlParts[i] == String.Empty)
11079 break;
11080
11081 // See if this could be a valid header
11082 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11083 if (headerParts.Length != 2)
11084 continue;
11085
11086 string headerName = headerParts[0].Trim();
11087 string headerValue = headerParts[1].Trim();
11088
11089 // Filter out headers that could be used to abuse
11090 // another system or cloak the request
11091 if (headerName.ToLower() == "x-secondlife-shard" ||
11092 headerName.ToLower() == "x-secondlife-object-name" ||
11093 headerName.ToLower() == "x-secondlife-object-key" ||
11094 headerName.ToLower() == "x-secondlife-region" ||
11095 headerName.ToLower() == "x-secondlife-local-position" ||
11096 headerName.ToLower() == "x-secondlife-local-velocity" ||
11097 headerName.ToLower() == "x-secondlife-local-rotation" ||
11098 headerName.ToLower() == "x-secondlife-owner-name" ||
11099 headerName.ToLower() == "x-secondlife-owner-key" ||
11100 headerName.ToLower() == "connection" ||
11101 headerName.ToLower() == "content-length" ||
11102 headerName.ToLower() == "from" ||
11103 headerName.ToLower() == "host" ||
11104 headerName.ToLower() == "proxy-authorization" ||
11105 headerName.ToLower() == "referer" ||
11106 headerName.ToLower() == "trailer" ||
11107 headerName.ToLower() == "transfer-encoding" ||
11108 headerName.ToLower() == "via" ||
11109 headerName.ToLower() == "authorization")
11110 continue;
11111
11112 httpHeaders[headerName] = headerValue;
11113 }
11114
11115 // Finally, strip any protocol specifier from the URL
11116 url = urlParts[0].Trim();
11117 int idx = url.IndexOf(" HTTP/");
11118 if (idx != -1)
11119 url = url.Substring(0, idx);
11120 }
11121
10248 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11122 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10249 Regex r = new Regex(authregex); 11123 Regex r = new Regex(authregex);
10250 int[] gnums = r.GetGroupNumbers(); 11124 int[] gnums = r.GetGroupNumbers();
10251 Match m = r.Match(url); 11125 Match m = r.Match(url);
10252 if (m.Success) { 11126 if (m.Success)
10253 for (int i = 1; i < gnums.Length; i++) { 11127 {
11128 for (int i = 1; i < gnums.Length; i++)
11129 {
10254 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11130 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10255 //CaptureCollection cc = g.Captures; 11131 //CaptureCollection cc = g.Captures;
10256 } 11132 }
10257 if (m.Groups.Count == 5) { 11133 if (m.Groups.Count == 5)
11134 {
10258 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11135 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10259 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11136 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10260 } 11137 }
@@ -10457,6 +11334,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10457 11334
10458 LSL_List ret = new LSL_List(); 11335 LSL_List ret = new LSL_List();
10459 UUID key = new UUID(); 11336 UUID key = new UUID();
11337
11338
10460 if (UUID.TryParse(id, out key)) 11339 if (UUID.TryParse(id, out key))
10461 { 11340 {
10462 ScenePresence av = World.GetScenePresence(key); 11341 ScenePresence av = World.GetScenePresence(key);
@@ -10474,13 +11353,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10474 ret.Add(new LSL_String("")); 11353 ret.Add(new LSL_String(""));
10475 break; 11354 break;
10476 case ScriptBaseClass.OBJECT_POS: 11355 case ScriptBaseClass.OBJECT_POS:
10477 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11356 Vector3 avpos;
11357
11358 if (av.ParentID != 0 && av.ParentPart != null)
11359 {
11360 avpos = av.OffsetPosition;
11361
11362 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11363 avpos -= sitOffset;
11364
11365 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11366 }
11367 else
11368 avpos = av.AbsolutePosition;
11369
11370 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10478 break; 11371 break;
10479 case ScriptBaseClass.OBJECT_ROT: 11372 case ScriptBaseClass.OBJECT_ROT:
10480 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11373 Quaternion avrot = av.Rotation;
11374 if (av.ParentID != 0 && av.ParentPart != null)
11375 {
11376 avrot = av.ParentPart.GetWorldRotation() * avrot;
11377 }
11378 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10481 break; 11379 break;
10482 case ScriptBaseClass.OBJECT_VELOCITY: 11380 case ScriptBaseClass.OBJECT_VELOCITY:
10483 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11381 Vector3 avvel = av.Velocity;
11382 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10484 break; 11383 break;
10485 case ScriptBaseClass.OBJECT_OWNER: 11384 case ScriptBaseClass.OBJECT_OWNER:
10486 ret.Add(new LSL_String(id)); 11385 ret.Add(new LSL_String(id));
@@ -10536,11 +11435,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10536 case ScriptBaseClass.OBJECT_NAME: 11435 case ScriptBaseClass.OBJECT_NAME:
10537 ret.Add(new LSL_String(obj.Name)); 11436 ret.Add(new LSL_String(obj.Name));
10538 break; 11437 break;
10539 case ScriptBaseClass.OBJECT_DESC: 11438 case ScriptBaseClass.OBJECT_DESC:
10540 ret.Add(new LSL_String(obj.Description)); 11439 ret.Add(new LSL_String(obj.Description));
10541 break; 11440 break;
10542 case ScriptBaseClass.OBJECT_POS: 11441 case ScriptBaseClass.OBJECT_POS:
10543 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11442 Vector3 opos = obj.AbsolutePosition;
11443 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10544 break; 11444 break;
10545 case ScriptBaseClass.OBJECT_ROT: 11445 case ScriptBaseClass.OBJECT_ROT:
10546 { 11446 {
@@ -10590,9 +11490,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10590 // The value returned in SL for normal prims is prim count 11490 // The value returned in SL for normal prims is prim count
10591 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11491 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10592 break; 11492 break;
10593 // The following 3 costs I have intentionaly coded to return zero. They are part of 11493
10594 // "Land Impact" calculations. These calculations are probably not applicable 11494 // costs below may need to be diferent for root parts, need to check
10595 // to OpenSim and are not yet complete in SL
10596 case ScriptBaseClass.OBJECT_SERVER_COST: 11495 case ScriptBaseClass.OBJECT_SERVER_COST:
10597 // The linden calculation is here 11496 // The linden calculation is here
10598 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11497 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10600,16 +11499,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10600 ret.Add(new LSL_Float(0)); 11499 ret.Add(new LSL_Float(0));
10601 break; 11500 break;
10602 case ScriptBaseClass.OBJECT_STREAMING_COST: 11501 case ScriptBaseClass.OBJECT_STREAMING_COST:
10603 // The linden calculation is here 11502 // The value returned in SL for normal prims is prim count * 0.06
10604 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11503 ret.Add(new LSL_Float(obj.StreamingCost));
10605 // The value returned in SL for normal prims looks like the prim count * 0.06
10606 ret.Add(new LSL_Float(0));
10607 break; 11504 break;
10608 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11505 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10609 // The linden calculation is here 11506 // The value returned in SL for normal prims is prim count
10610 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11507 ret.Add(new LSL_Float(obj.PhysicsCost));
10611 // The value returned in SL for normal prims looks like the prim count
10612 ret.Add(new LSL_Float(0));
10613 break; 11508 break;
10614 default: 11509 default:
10615 // Invalid or unhandled constant. 11510 // Invalid or unhandled constant.
@@ -10820,15 +11715,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10820 return result; 11715 return result;
10821 } 11716 }
10822 11717
10823 public void print(string str) 11718 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10824 { 11719 {
10825 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11720 List<SceneObjectPart> parts = GetLinkParts(link);
10826 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11721 if (parts.Count < 1)
10827 if (ossl != null) 11722 return 0;
10828 { 11723
10829 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11724 return GetNumberOfSides(parts[0]);
10830 m_log.Info("LSL print():" + str);
10831 }
10832 } 11725 }
10833 11726
10834 private string Name2Username(string name) 11727 private string Name2Username(string name)
@@ -10873,7 +11766,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10873 11766
10874 return rq.ToString(); 11767 return rq.ToString();
10875 } 11768 }
10876 11769/*
11770 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11771 {
11772 m_SayShoutCount = 0;
11773 }
11774*/
10877 private struct Tri 11775 private struct Tri
10878 { 11776 {
10879 public Vector3 p1; 11777 public Vector3 p1;
@@ -11013,9 +11911,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11013 11911
11014 ContactResult result = new ContactResult (); 11912 ContactResult result = new ContactResult ();
11015 result.ConsumerID = group.LocalId; 11913 result.ConsumerID = group.LocalId;
11016 result.Depth = intersection.distance; 11914// result.Depth = intersection.distance;
11017 result.Normal = intersection.normal; 11915 result.Normal = intersection.normal;
11018 result.Pos = intersection.ipoint; 11916 result.Pos = intersection.ipoint;
11917 result.Depth = Vector3.Mag(rayStart - result.Pos);
11019 11918
11020 contacts.Add(result); 11919 contacts.Add(result);
11021 }); 11920 });
@@ -11148,6 +12047,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11148 12047
11149 return contacts[0]; 12048 return contacts[0];
11150 } 12049 }
12050/*
12051 // not done:
12052 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12053 {
12054 ContactResult[] contacts = null;
12055 World.ForEachSOG(delegate(SceneObjectGroup group)
12056 {
12057 if (m_host.ParentGroup == group)
12058 return;
12059
12060 if (group.IsAttachment)
12061 return;
12062
12063 if(group.RootPart.PhysActor != null)
12064 return;
12065
12066 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12067 });
12068 return contacts;
12069 }
12070*/
11151 12071
11152 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12072 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11153 { 12073 {
@@ -11189,32 +12109,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11189 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12109 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11190 12110
11191 12111
11192 if (checkTerrain) 12112 if (World.SuportsRayCastFiltered())
11193 { 12113 {
11194 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12114 if (dist == 0)
11195 if (groundContact != null) 12115 return list;
11196 results.Add((ContactResult)groundContact);
11197 }
11198 12116
11199 if (checkAgents) 12117 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11200 { 12118 if (checkTerrain)
11201 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12119 rayfilter |= RayFilterFlags.land;
11202 foreach (ContactResult r in agentHits) 12120// if (checkAgents)
11203 results.Add(r); 12121// rayfilter |= RayFilterFlags.agent;
11204 } 12122 if (checkPhysical)
12123 rayfilter |= RayFilterFlags.physical;
12124 if (checkNonPhysical)
12125 rayfilter |= RayFilterFlags.nonphysical;
12126 if (detectPhantom)
12127 rayfilter |= RayFilterFlags.LSLPhanton;
12128
12129 Vector3 direction = dir * ( 1/dist);
12130
12131 if(rayfilter == 0)
12132 {
12133 list.Add(new LSL_Integer(0));
12134 return list;
12135 }
12136
12137 // get some more contacts to sort ???
12138 int physcount = 4 * count;
12139 if (physcount > 20)
12140 physcount = 20;
12141
12142 object physresults;
12143 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12144
12145 if (physresults == null)
12146 {
12147 list.Add(new LSL_Integer(-3)); // timeout error
12148 return list;
12149 }
11205 12150
11206 if (checkPhysical || checkNonPhysical || detectPhantom) 12151 results = (List<ContactResult>)physresults;
12152
12153 // for now physics doesn't detect sitted avatars so do it outside physics
12154 if (checkAgents)
12155 {
12156 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12157 foreach (ContactResult r in agentHits)
12158 results.Add(r);
12159 }
12160
12161 // TODO: Replace this with a better solution. ObjectIntersection can only
12162 // detect nonphysical phantoms. They are detected by virtue of being
12163 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12164 // physicsl phantoms as done by the physics scene
12165 // We don't want anything else but phantoms here.
12166 if (detectPhantom)
12167 {
12168 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12169 foreach (ContactResult r in objectHits)
12170 results.Add(r);
12171 }
12172 }
12173 else
11207 { 12174 {
11208 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12175 if (checkTerrain)
11209 foreach (ContactResult r in objectHits) 12176 {
11210 results.Add(r); 12177 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12178 if (groundContact != null)
12179 results.Add((ContactResult)groundContact);
12180 }
12181
12182 if (checkAgents)
12183 {
12184 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12185 foreach (ContactResult r in agentHits)
12186 results.Add(r);
12187 }
12188
12189 if (checkPhysical || checkNonPhysical || detectPhantom)
12190 {
12191 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12192 foreach (ContactResult r in objectHits)
12193 results.Add(r);
12194 }
11211 } 12195 }
11212 12196
11213 results.Sort(delegate(ContactResult a, ContactResult b) 12197 results.Sort(delegate(ContactResult a, ContactResult b)
11214 { 12198 {
11215 return a.Depth.CompareTo(b.Depth); 12199 return a.Depth.CompareTo(b.Depth);
11216 }); 12200 });
11217 12201
11218 int values = 0; 12202 int values = 0;
11219 SceneObjectGroup thisgrp = m_host.ParentGroup; 12203 SceneObjectGroup thisgrp = m_host.ParentGroup;
11220 12204
@@ -11307,7 +12291,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11307 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12291 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11308 if (!isAccount) return 0; 12292 if (!isAccount) return 0;
11309 if (estate.HasAccess(id)) return 1; 12293 if (estate.HasAccess(id)) return 1;
11310 if (estate.IsBanned(id)) 12294 if (estate.IsBanned(id, World.GetUserFlags(id)))
11311 estate.RemoveBan(id); 12295 estate.RemoveBan(id);
11312 estate.AddEstateUser(id); 12296 estate.AddEstateUser(id);
11313 break; 12297 break;
@@ -11326,14 +12310,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11326 break; 12310 break;
11327 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12311 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11328 if (!isAccount) return 0; 12312 if (!isAccount) return 0;
11329 if (estate.IsBanned(id)) return 1; 12313 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11330 EstateBan ban = new EstateBan(); 12314 EstateBan ban = new EstateBan();
11331 ban.EstateID = estate.EstateID; 12315 ban.EstateID = estate.EstateID;
11332 ban.BannedUserID = id; 12316 ban.BannedUserID = id;
11333 estate.AddBan(ban); 12317 estate.AddBan(ban);
11334 break; 12318 break;
11335 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12319 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11336 if (!isAccount || !estate.IsBanned(id)) return 0; 12320 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11337 estate.RemoveBan(id); 12321 estate.RemoveBan(id);
11338 break; 12322 break;
11339 default: return 0; 12323 default: return 0;
@@ -11362,7 +12346,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11362 return 16384; 12346 return 16384;
11363 } 12347 }
11364 12348
11365 public LSL_Integer llGetUsedMemory() 12349 public virtual LSL_Integer llGetUsedMemory()
11366 { 12350 {
11367 m_host.AddScriptLPS(1); 12351 m_host.AddScriptLPS(1);
11368 // The value returned for LSO scripts in SL 12352 // The value returned for LSO scripts in SL
@@ -11390,22 +12374,731 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11390 public void llSetSoundQueueing(int queue) 12374 public void llSetSoundQueueing(int queue)
11391 { 12375 {
11392 m_host.AddScriptLPS(1); 12376 m_host.AddScriptLPS(1);
11393 NotImplemented("llSetSoundQueueing");
11394 } 12377 }
11395 12378
11396 public void llCollisionSprite(string impact_sprite) 12379 public void llCollisionSprite(string impact_sprite)
11397 { 12380 {
11398 m_host.AddScriptLPS(1); 12381 m_host.AddScriptLPS(1);
11399 NotImplemented("llCollisionSprite"); 12382 // Viewer 2.0 broke this and it's likely LL has no intention
12383 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11400 } 12384 }
11401 12385
11402 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12386 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11403 { 12387 {
11404 m_host.AddScriptLPS(1); 12388 m_host.AddScriptLPS(1);
11405 NotImplemented("llGodLikeRezObject"); 12389
12390 if (!World.Permissions.IsGod(m_host.OwnerID))
12391 NotImplemented("llGodLikeRezObject");
12392
12393 AssetBase rezAsset = World.AssetService.Get(inventory);
12394 if (rezAsset == null)
12395 {
12396 llSay(0, "Asset not found");
12397 return;
12398 }
12399
12400 SceneObjectGroup group = null;
12401
12402 try
12403 {
12404 string xmlData = Utils.BytesToString(rezAsset.Data);
12405 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12406 }
12407 catch
12408 {
12409 llSay(0, "Asset not found");
12410 return;
12411 }
12412
12413 if (group == null)
12414 {
12415 llSay(0, "Asset not found");
12416 return;
12417 }
12418
12419 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12420 group.RootPart.AttachOffset = group.AbsolutePosition;
12421
12422 group.ResetIDs();
12423
12424 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12425 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12426 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12427 group.ScheduleGroupForFullUpdate();
12428
12429 // objects rezzed with this method are die_at_edge by default.
12430 group.RootPart.SetDieAtEdge(true);
12431
12432 group.ResumeScripts();
12433
12434 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12435 "object_rez", new Object[] {
12436 new LSL_String(
12437 group.RootPart.UUID.ToString()) },
12438 new DetectParams[0]));
12439 }
12440
12441 public LSL_String llTransferLindenDollars(string destination, int amount)
12442 {
12443 UUID txn = UUID.Random();
12444
12445 Util.FireAndForget(delegate(object x)
12446 {
12447 int replycode = 0;
12448 string replydata = destination + "," + amount.ToString();
12449
12450 try
12451 {
12452 TaskInventoryItem item = m_item;
12453 if (item == null)
12454 {
12455 replydata = "SERVICE_ERROR";
12456 return;
12457 }
12458
12459 m_host.AddScriptLPS(1);
12460
12461 if (item.PermsGranter == UUID.Zero)
12462 {
12463 replydata = "MISSING_PERMISSION_DEBIT";
12464 return;
12465 }
12466
12467 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12468 {
12469 replydata = "MISSING_PERMISSION_DEBIT";
12470 return;
12471 }
12472
12473 UUID toID = new UUID();
12474
12475 if (!UUID.TryParse(destination, out toID))
12476 {
12477 replydata = "INVALID_AGENT";
12478 return;
12479 }
12480
12481 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12482
12483 if (money == null)
12484 {
12485 replydata = "TRANSFERS_DISABLED";
12486 return;
12487 }
12488
12489 bool result = money.ObjectGiveMoney(
12490 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12491
12492 if (result)
12493 {
12494 replycode = 1;
12495 return;
12496 }
12497
12498 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12499 }
12500 finally
12501 {
12502 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12503 "transaction_result", new Object[] {
12504 new LSL_String(txn.ToString()),
12505 new LSL_Integer(replycode),
12506 new LSL_String(replydata) },
12507 new DetectParams[0]));
12508 }
12509 });
12510
12511 return txn.ToString();
11406 } 12512 }
11407 12513
11408 #endregion 12514 #endregion
12515
12516 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12517 {
12518 SceneObjectGroup group = m_host.ParentGroup;
12519
12520 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12521 return;
12522 if (group.IsAttachment)
12523 return;
12524
12525 if (frames.Data.Length > 0) // We are getting a new motion
12526 {
12527 if (group.RootPart.KeyframeMotion != null)
12528 group.RootPart.KeyframeMotion.Delete();
12529 group.RootPart.KeyframeMotion = null;
12530
12531 int idx = 0;
12532
12533 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12534 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12535
12536 while (idx < options.Data.Length)
12537 {
12538 int option = (int)options.GetLSLIntegerItem(idx++);
12539 int remain = options.Data.Length - idx;
12540
12541 switch (option)
12542 {
12543 case ScriptBaseClass.KFM_MODE:
12544 if (remain < 1)
12545 break;
12546 int modeval = (int)options.GetLSLIntegerItem(idx++);
12547 switch(modeval)
12548 {
12549 case ScriptBaseClass.KFM_FORWARD:
12550 mode = KeyframeMotion.PlayMode.Forward;
12551 break;
12552 case ScriptBaseClass.KFM_REVERSE:
12553 mode = KeyframeMotion.PlayMode.Reverse;
12554 break;
12555 case ScriptBaseClass.KFM_LOOP:
12556 mode = KeyframeMotion.PlayMode.Loop;
12557 break;
12558 case ScriptBaseClass.KFM_PING_PONG:
12559 mode = KeyframeMotion.PlayMode.PingPong;
12560 break;
12561 }
12562 break;
12563 case ScriptBaseClass.KFM_DATA:
12564 if (remain < 1)
12565 break;
12566 int dataval = (int)options.GetLSLIntegerItem(idx++);
12567 data = (KeyframeMotion.DataFormat)dataval;
12568 break;
12569 }
12570 }
12571
12572 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12573
12574 idx = 0;
12575
12576 int elemLength = 2;
12577 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12578 elemLength = 3;
12579
12580 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12581 while (idx < frames.Data.Length)
12582 {
12583 int remain = frames.Data.Length - idx;
12584
12585 if (remain < elemLength)
12586 break;
12587
12588 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12589 frame.Position = null;
12590 frame.Rotation = null;
12591
12592 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12593 {
12594 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12595 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12596 }
12597 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12598 {
12599 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12600 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12601 }
12602
12603 float tempf = (float)frames.GetLSLFloatItem(idx++);
12604 frame.TimeMS = (int)(tempf * 1000.0f);
12605
12606 keyframes.Add(frame);
12607 }
12608
12609 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12610 group.RootPart.KeyframeMotion.Start();
12611 }
12612 else
12613 {
12614 if (group.RootPart.KeyframeMotion == null)
12615 return;
12616
12617 if (options.Data.Length == 0)
12618 {
12619 group.RootPart.KeyframeMotion.Stop();
12620 return;
12621 }
12622
12623 int code = (int)options.GetLSLIntegerItem(0);
12624
12625 int idx = 0;
12626
12627 while (idx < options.Data.Length)
12628 {
12629 int option = (int)options.GetLSLIntegerItem(idx++);
12630 int remain = options.Data.Length - idx;
12631
12632 switch (option)
12633 {
12634 case ScriptBaseClass.KFM_COMMAND:
12635 int cmd = (int)options.GetLSLIntegerItem(idx++);
12636 switch (cmd)
12637 {
12638 case ScriptBaseClass.KFM_CMD_PLAY:
12639 group.RootPart.KeyframeMotion.Start();
12640 break;
12641 case ScriptBaseClass.KFM_CMD_STOP:
12642 group.RootPart.KeyframeMotion.Stop();
12643 break;
12644 case ScriptBaseClass.KFM_CMD_PAUSE:
12645 group.RootPart.KeyframeMotion.Pause();
12646 break;
12647 }
12648 break;
12649 }
12650 }
12651 }
12652 }
12653
12654 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12655 {
12656 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12657
12658 int idx = 0;
12659 int idxStart = 0;
12660
12661 bool positionChanged = false;
12662 Vector3 finalPos = Vector3.Zero;
12663
12664 try
12665 {
12666 while (idx < rules.Length)
12667 {
12668 ++rulesParsed;
12669 int code = rules.GetLSLIntegerItem(idx++);
12670
12671 int remain = rules.Length - idx;
12672 idxStart = idx;
12673
12674 switch (code)
12675 {
12676 case (int)ScriptBaseClass.PRIM_POSITION:
12677 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12678 {
12679 if (remain < 1)
12680 return null;
12681
12682 LSL_Vector v;
12683 v = rules.GetVector3Item(idx++);
12684
12685 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12686 if (part == null)
12687 break;
12688
12689 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12690 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12691 if (part.LinkNum > 1)
12692 {
12693 localRot = GetPartLocalRot(part);
12694 localPos = GetPartLocalPos(part);
12695 }
12696
12697 v -= localPos;
12698 v /= localRot;
12699
12700 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12701
12702 v = v + 2 * sitOffset;
12703
12704 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12705 av.SendAvatarDataToAllAgents();
12706
12707 }
12708 break;
12709
12710 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12711 case (int)ScriptBaseClass.PRIM_ROTATION:
12712 {
12713 if (remain < 1)
12714 return null;
12715
12716 LSL_Rotation r;
12717 r = rules.GetQuaternionItem(idx++);
12718
12719 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12720 if (part == null)
12721 break;
12722
12723 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12724 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12725
12726 if (part.LinkNum > 1)
12727 localRot = GetPartLocalRot(part);
12728
12729 r = r * llGetRootRotation() / localRot;
12730 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12731 av.SendAvatarDataToAllAgents();
12732 }
12733 break;
12734
12735 // parse rest doing nothing but number of parameters error check
12736 case (int)ScriptBaseClass.PRIM_SIZE:
12737 case (int)ScriptBaseClass.PRIM_MATERIAL:
12738 case (int)ScriptBaseClass.PRIM_PHANTOM:
12739 case (int)ScriptBaseClass.PRIM_PHYSICS:
12740 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12741 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12742 case (int)ScriptBaseClass.PRIM_NAME:
12743 case (int)ScriptBaseClass.PRIM_DESC:
12744 if (remain < 1)
12745 return null;
12746 idx++;
12747 break;
12748
12749 case (int)ScriptBaseClass.PRIM_GLOW:
12750 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12751 case (int)ScriptBaseClass.PRIM_TEXGEN:
12752 if (remain < 2)
12753 return null;
12754 idx += 2;
12755 break;
12756
12757 case (int)ScriptBaseClass.PRIM_TYPE:
12758 if (remain < 3)
12759 return null;
12760 code = (int)rules.GetLSLIntegerItem(idx++);
12761 remain = rules.Length - idx;
12762 switch (code)
12763 {
12764 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12765 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12766 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12767 if (remain < 6)
12768 return null;
12769 idx += 6;
12770 break;
12771
12772 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12773 if (remain < 5)
12774 return null;
12775 idx += 5;
12776 break;
12777
12778 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12779 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12780 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12781 if (remain < 11)
12782 return null;
12783 idx += 11;
12784 break;
12785
12786 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12787 if (remain < 2)
12788 return null;
12789 idx += 2;
12790 break;
12791 }
12792 break;
12793
12794 case (int)ScriptBaseClass.PRIM_COLOR:
12795 case (int)ScriptBaseClass.PRIM_TEXT:
12796 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12797 case (int)ScriptBaseClass.PRIM_OMEGA:
12798 if (remain < 3)
12799 return null;
12800 idx += 3;
12801 break;
12802
12803 case (int)ScriptBaseClass.PRIM_TEXTURE:
12804 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12805 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12806 if (remain < 5)
12807 return null;
12808 idx += 5;
12809 break;
12810
12811 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12812 if (remain < 7)
12813 return null;
12814
12815 idx += 7;
12816 break;
12817
12818 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12819 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12820 return null;
12821
12822 return rules.GetSublist(idx, -1);
12823 }
12824 }
12825 }
12826 catch (InvalidCastException e)
12827 {
12828 ShoutError(string.Format(
12829 "{0} error running rule #{1}: arg #{2} ",
12830 originFunc, rulesParsed, idx - idxStart) + e.Message);
12831 }
12832 finally
12833 {
12834 if (positionChanged)
12835 {
12836 av.OffsetPosition = finalPos;
12837// av.SendAvatarDataToAllAgents();
12838 av.SendTerseUpdateToAllClients();
12839 positionChanged = false;
12840 }
12841 }
12842 return null;
12843 }
12844
12845 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12846 {
12847 // avatars case
12848 // replies as SL wiki
12849
12850// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12851 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12852
12853 int idx = 0;
12854 while (idx < rules.Length)
12855 {
12856 int code = (int)rules.GetLSLIntegerItem(idx++);
12857 int remain = rules.Length - idx;
12858
12859 switch (code)
12860 {
12861 case (int)ScriptBaseClass.PRIM_MATERIAL:
12862 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12863 break;
12864
12865 case (int)ScriptBaseClass.PRIM_PHYSICS:
12866 res.Add(new LSL_Integer(0));
12867 break;
12868
12869 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12870 res.Add(new LSL_Integer(0));
12871 break;
12872
12873 case (int)ScriptBaseClass.PRIM_PHANTOM:
12874 res.Add(new LSL_Integer(0));
12875 break;
12876
12877 case (int)ScriptBaseClass.PRIM_POSITION:
12878
12879 Vector3 pos = avatar.OffsetPosition;
12880
12881 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12882 pos -= sitOffset;
12883
12884 if( sitPart != null)
12885 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12886
12887 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12888 break;
12889
12890 case (int)ScriptBaseClass.PRIM_SIZE:
12891 // as in llGetAgentSize above
12892 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12893 break;
12894
12895 case (int)ScriptBaseClass.PRIM_ROTATION:
12896 Quaternion rot = avatar.Rotation;
12897 if (sitPart != null)
12898 {
12899 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12900 }
12901
12902 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12903 break;
12904
12905 case (int)ScriptBaseClass.PRIM_TYPE:
12906 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12907 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12908 res.Add(new LSL_Vector(0f,1.0f,0f));
12909 res.Add(new LSL_Float(0.0f));
12910 res.Add(new LSL_Vector(0, 0, 0));
12911 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12912 res.Add(new LSL_Vector(0, 0, 0));
12913 break;
12914
12915 case (int)ScriptBaseClass.PRIM_TEXTURE:
12916 if (remain < 1)
12917 return null;
12918
12919 int face = (int)rules.GetLSLIntegerItem(idx++);
12920 if (face == ScriptBaseClass.ALL_SIDES)
12921 {
12922 for (face = 0; face < 21; face++)
12923 {
12924 res.Add(new LSL_String(""));
12925 res.Add(new LSL_Vector(0,0,0));
12926 res.Add(new LSL_Vector(0,0,0));
12927 res.Add(new LSL_Float(0.0));
12928 }
12929 }
12930 else
12931 {
12932 if (face >= 0 && face < 21)
12933 {
12934 res.Add(new LSL_String(""));
12935 res.Add(new LSL_Vector(0,0,0));
12936 res.Add(new LSL_Vector(0,0,0));
12937 res.Add(new LSL_Float(0.0));
12938 }
12939 }
12940 break;
12941
12942 case (int)ScriptBaseClass.PRIM_COLOR:
12943 if (remain < 1)
12944 return null;
12945
12946 face = (int)rules.GetLSLIntegerItem(idx++);
12947
12948 if (face == ScriptBaseClass.ALL_SIDES)
12949 {
12950 for (face = 0; face < 21; face++)
12951 {
12952 res.Add(new LSL_Vector(0,0,0));
12953 res.Add(new LSL_Float(0));
12954 }
12955 }
12956 else
12957 {
12958 res.Add(new LSL_Vector(0,0,0));
12959 res.Add(new LSL_Float(0));
12960 }
12961 break;
12962
12963 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12964 if (remain < 1)
12965 return null;
12966 face = (int)rules.GetLSLIntegerItem(idx++);
12967
12968 if (face == ScriptBaseClass.ALL_SIDES)
12969 {
12970 for (face = 0; face < 21; face++)
12971 {
12972 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12973 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12974 }
12975 }
12976 else
12977 {
12978 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12979 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12980 }
12981 break;
12982
12983 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12984 if (remain < 1)
12985 return null;
12986 face = (int)rules.GetLSLIntegerItem(idx++);
12987
12988 if (face == ScriptBaseClass.ALL_SIDES)
12989 {
12990 for (face = 0; face < 21; face++)
12991 {
12992 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12993 }
12994 }
12995 else
12996 {
12997 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12998 }
12999 break;
13000
13001 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13002 res.Add(new LSL_Integer(0));
13003 res.Add(new LSL_Integer(0));// softness
13004 res.Add(new LSL_Float(0.0f)); // gravity
13005 res.Add(new LSL_Float(0.0f)); // friction
13006 res.Add(new LSL_Float(0.0f)); // wind
13007 res.Add(new LSL_Float(0.0f)); // tension
13008 res.Add(new LSL_Vector(0f,0f,0f));
13009 break;
13010
13011 case (int)ScriptBaseClass.PRIM_TEXGEN:
13012 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
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_TEXGEN_DEFAULT));
13022 }
13023 }
13024 else
13025 {
13026 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13027 }
13028 break;
13029
13030 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13031 res.Add(new LSL_Integer(0));
13032 res.Add(new LSL_Vector(0f,0f,0f));
13033 res.Add(new LSL_Float(0f)); // intensity
13034 res.Add(new LSL_Float(0f)); // radius
13035 res.Add(new LSL_Float(0f)); // falloff
13036 break;
13037
13038 case (int)ScriptBaseClass.PRIM_GLOW:
13039 if (remain < 1)
13040 return null;
13041 face = (int)rules.GetLSLIntegerItem(idx++);
13042
13043 if (face == ScriptBaseClass.ALL_SIDES)
13044 {
13045 for (face = 0; face < 21; face++)
13046 {
13047 res.Add(new LSL_Float(0f));
13048 }
13049 }
13050 else
13051 {
13052 res.Add(new LSL_Float(0f));
13053 }
13054 break;
13055
13056 case (int)ScriptBaseClass.PRIM_TEXT:
13057 res.Add(new LSL_String(""));
13058 res.Add(new LSL_Vector(0f,0f,0f));
13059 res.Add(new LSL_Float(1.0f));
13060 break;
13061
13062 case (int)ScriptBaseClass.PRIM_NAME:
13063 res.Add(new LSL_String(avatar.Name));
13064 break;
13065
13066 case (int)ScriptBaseClass.PRIM_DESC:
13067 res.Add(new LSL_String(""));
13068 break;
13069
13070 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13071 Quaternion lrot = avatar.Rotation;
13072
13073 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13074 {
13075 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13076 }
13077 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13078 break;
13079
13080 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13081 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13082 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13083 lpos -= lsitOffset;
13084
13085 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13086 {
13087 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13088 }
13089 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13090 break;
13091
13092 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13093 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13094 return null;
13095
13096 return rules.GetSublist(idx, -1);
13097 }
13098 }
13099
13100 return null;
13101 }
11409 } 13102 }
11410 13103
11411 public class NotecardCache 13104 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 8b73cd9..160e2df 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 Exception("OSSL Runtime Error: " + msg); 215 if (m_debuggerSafe)
216 {
217 OSSLShoutError(msg);
218 }
219 else
220 {
221 throw new Exception("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);
@@ -1808,6 +1817,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1808 1817
1809 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1818 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1810 { 1819 {
1820 m_host.TaskInventory.LockItemsForRead(true);
1811 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1821 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1812 { 1822 {
1813 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1823 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1815,6 +1825,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1815 assetID = item.AssetID; 1825 assetID = item.AssetID;
1816 } 1826 }
1817 } 1827 }
1828 m_host.TaskInventory.LockItemsForRead(false);
1818 } 1829 }
1819 1830
1820 if (assetID == UUID.Zero) 1831 if (assetID == UUID.Zero)
@@ -2300,7 +2311,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2300 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2311 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2301 m_host.AddScriptLPS(1); 2312 m_host.AddScriptLPS(1);
2302 2313
2303 return NpcCreate(firstname, lastname, position, notecard, false, false); 2314 return NpcCreate(firstname, lastname, position, notecard, true, false);
2304 } 2315 }
2305 2316
2306 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2317 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2311,24 +2322,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2311 return NpcCreate( 2322 return NpcCreate(
2312 firstname, lastname, position, notecard, 2323 firstname, lastname, position, notecard,
2313 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2324 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2314 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2325 false);
2326// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2315 } 2327 }
2316 2328
2317 private LSL_Key NpcCreate( 2329 private LSL_Key NpcCreate(
2318 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2330 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2319 { 2331 {
2332 if (!owned)
2333 OSSLError("Unowned NPCs are unsupported");
2334
2335 string groupTitle = String.Empty;
2336
2337 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2338 return new LSL_Key(UUID.Zero.ToString());
2339
2340 if (firstname != String.Empty || lastname != String.Empty)
2341 {
2342 if (firstname != "Shown outfit:")
2343 groupTitle = "- NPC -";
2344 }
2345
2320 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2346 INPCModule module = World.RequestModuleInterface<INPCModule>();
2321 if (module != null) 2347 if (module != null)
2322 { 2348 {
2323 AvatarAppearance appearance = null; 2349 AvatarAppearance appearance = null;
2324 2350
2325 UUID id; 2351// UUID id;
2326 if (UUID.TryParse(notecard, out id)) 2352// if (UUID.TryParse(notecard, out id))
2327 { 2353// {
2328 ScenePresence clonePresence = World.GetScenePresence(id); 2354// ScenePresence clonePresence = World.GetScenePresence(id);
2329 if (clonePresence != null) 2355// if (clonePresence != null)
2330 appearance = clonePresence.Appearance; 2356// appearance = clonePresence.Appearance;
2331 } 2357// }
2332 2358
2333 if (appearance == null) 2359 if (appearance == null)
2334 { 2360 {
@@ -2356,6 +2382,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2356 World, 2382 World,
2357 appearance); 2383 appearance);
2358 2384
2385 ScenePresence sp;
2386 if (World.TryGetScenePresence(x, out sp))
2387 {
2388 sp.Grouptitle = groupTitle;
2389 sp.SendAvatarDataToAllAgents();
2390 }
2359 return new LSL_Key(x.ToString()); 2391 return new LSL_Key(x.ToString());
2360 } 2392 }
2361 2393
@@ -2655,16 +2687,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2655 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2687 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2656 m_host.AddScriptLPS(1); 2688 m_host.AddScriptLPS(1);
2657 2689
2658 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2690 ManualResetEvent ev = new ManualResetEvent(false);
2659 if (module != null)
2660 {
2661 UUID npcId = new UUID(npc.m_string);
2662 2691
2663 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2692 Util.FireAndForget(delegate(object x) {
2664 return; 2693 try
2694 {
2695 INPCModule module = World.RequestModuleInterface<INPCModule>();
2696 if (module != null)
2697 {
2698 UUID npcId = new UUID(npc.m_string);
2665 2699
2666 module.DeleteNPC(npcId, World); 2700 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2667 } 2701 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2702 {
2703 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2704 return;
2705 }
2706
2707 module.DeleteNPC(npcId, World);
2708 }
2709 }
2710 finally
2711 {
2712 ev.Set();
2713 }
2714 });
2715 ev.WaitOne();
2668 } 2716 }
2669 2717
2670 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2718 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3549,6 +3597,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3549 if (m_UrlModule != null) 3597 if (m_UrlModule != null)
3550 m_UrlModule.HttpContentType(new UUID(id),type); 3598 m_UrlModule.HttpContentType(new UUID(id),type);
3551 } 3599 }
3552 3600 }
3553 } 3601}
3554} \ No newline at end of file
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 }