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.cs3188
-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, 2684 insertions, 793 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 be22cb4..bf29288 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);
@@ -2085,18 +2316,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2085 m_host.AddScriptLPS(1); 2316 m_host.AddScriptLPS(1);
2086 2317
2087 // try to let this work as in SL... 2318 // try to let this work as in SL...
2088 if (m_host.ParentID == 0) 2319 if (m_host.LinkNum < 2)
2089 { 2320 {
2090 // special case: If we are root, rotate complete SOG to new rotation 2321 // Special case: If we are root, rotate complete SOG to new
2322 // rotation.
2323 // We are root if the link number is 0 (single prim) or 1
2324 // (root prim). ParentID may be nonzero in attachments and
2325 // using it would cause attachments and HUDs to rotate
2326 // to the wrong positions.
2327
2091 SetRot(m_host, rot); 2328 SetRot(m_host, rot);
2092 } 2329 }
2093 else 2330 else
2094 { 2331 {
2095 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2332 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2096 SceneObjectPart rootPart = m_host.ParentGroup.RootPart; 2333 SceneObjectPart rootPart;
2097 if (rootPart != null) // better safe than sorry 2334 if (m_host.ParentGroup != null) // better safe than sorry
2098 { 2335 {
2099 SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot); 2336 rootPart = m_host.ParentGroup.RootPart;
2337 if (rootPart != null)
2338 SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot);
2100 } 2339 }
2101 } 2340 }
2102 2341
@@ -2112,25 +2351,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2112 2351
2113 protected void SetRot(SceneObjectPart part, Quaternion rot) 2352 protected void SetRot(SceneObjectPart part, Quaternion rot)
2114 { 2353 {
2115 part.UpdateRotation(rot); 2354 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. 2355 return;
2117 2356
2118//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2357 bool isroot = (part == part.ParentGroup.RootPart);
2119// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2358 bool isphys;
2120 2359
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; 2360 PhysicsActor pa = part.PhysActor;
2129 2361
2130 if (pa != null && !pa.IsPhysical) 2362 // keep using physactor ideia of isphysical
2363 // it should be SOP ideia of that
2364 // not much of a issue with ubitODE
2365 if (pa != null && pa.IsPhysical)
2366 isphys = true;
2367 else
2368 isphys = false;
2369
2370 // SL doesn't let scripts rotate root of physical linksets
2371 if (isroot && isphys)
2372 return;
2373
2374 part.UpdateRotation(rot);
2375
2376 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2377 // so do a nasty update of parts positions if is a root part rotation
2378 if (isroot && pa != null) // with if above implies non physical root part
2131 { 2379 {
2132 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2380 part.ParentGroup.ResetChildPrimPhysicsPositions();
2133 } 2381 }
2382 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2383 {
2384 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2385 if (sittingavas.Count > 0)
2386 {
2387 foreach (ScenePresence av in sittingavas)
2388 {
2389 if (isroot || part.LocalId == av.ParentID)
2390 av.SendTerseUpdateToAllClients();
2391 }
2392 }
2393 }
2134 } 2394 }
2135 2395
2136 /// <summary> 2396 /// <summary>
@@ -2178,8 +2438,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2178 2438
2179 public LSL_Rotation llGetLocalRot() 2439 public LSL_Rotation llGetLocalRot()
2180 { 2440 {
2441 return GetPartLocalRot(m_host);
2442 }
2443
2444 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2445 {
2181 m_host.AddScriptLPS(1); 2446 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); 2447 Quaternion rot = part.RotationOffset;
2448 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2183 } 2449 }
2184 2450
2185 public void llSetForce(LSL_Vector force, int local) 2451 public void llSetForce(LSL_Vector force, int local)
@@ -2259,16 +2525,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2259 m_host.ApplyImpulse(v, local != 0); 2525 m_host.ApplyImpulse(v, local != 0);
2260 } 2526 }
2261 2527
2528
2262 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2529 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2263 { 2530 {
2264 m_host.AddScriptLPS(1); 2531 m_host.AddScriptLPS(1);
2265 m_host.ApplyAngularImpulse(force, local != 0); 2532 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2266 } 2533 }
2267 2534
2268 public void llSetTorque(LSL_Vector torque, int local) 2535 public void llSetTorque(LSL_Vector torque, int local)
2269 { 2536 {
2270 m_host.AddScriptLPS(1); 2537 m_host.AddScriptLPS(1);
2271 m_host.SetAngularImpulse(torque, local != 0); 2538 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2272 } 2539 }
2273 2540
2274 public LSL_Vector llGetTorque() 2541 public LSL_Vector llGetTorque()
@@ -2285,20 +2552,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2285 llSetTorque(torque, local); 2552 llSetTorque(torque, local);
2286 } 2553 }
2287 2554
2555 public void llSetVelocity(LSL_Vector vel, int local)
2556 {
2557 m_host.AddScriptLPS(1);
2558 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2559 }
2560
2288 public LSL_Vector llGetVel() 2561 public LSL_Vector llGetVel()
2289 { 2562 {
2290 m_host.AddScriptLPS(1); 2563 m_host.AddScriptLPS(1);
2291 2564
2292 Vector3 vel; 2565 Vector3 vel = Vector3.Zero;
2293 2566
2294 if (m_host.ParentGroup.IsAttachment) 2567 if (m_host.ParentGroup.IsAttachment)
2295 { 2568 {
2296 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2569 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2297 vel = avatar.Velocity; 2570 if (avatar != null)
2571 vel = avatar.Velocity;
2298 } 2572 }
2299 else 2573 else
2300 { 2574 {
2301 vel = m_host.Velocity; 2575 vel = m_host.ParentGroup.RootPart.Velocity;
2302 } 2576 }
2303 2577
2304 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2578 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2310,10 +2584,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2310 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2584 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2311 } 2585 }
2312 2586
2587 public void llSetAngularVelocity(LSL_Vector avel, int local)
2588 {
2589 m_host.AddScriptLPS(1);
2590 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2591 }
2592
2313 public LSL_Vector llGetOmega() 2593 public LSL_Vector llGetOmega()
2314 { 2594 {
2315 m_host.AddScriptLPS(1); 2595 m_host.AddScriptLPS(1);
2316 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2596 Vector3 avel = m_host.AngularVelocity;
2597 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2317 } 2598 }
2318 2599
2319 public LSL_Float llGetTimeOfDay() 2600 public LSL_Float llGetTimeOfDay()
@@ -2839,16 +3120,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2839 new_group.RootPart.UUID.ToString()) }, 3120 new_group.RootPart.UUID.ToString()) },
2840 new DetectParams[0])); 3121 new DetectParams[0]));
2841 3122
2842 float groupmass = new_group.GetMass(); 3123 // do recoil
3124 SceneObjectGroup hostgrp = m_host.ParentGroup;
3125 if (hostgrp == null)
3126 return;
3127
3128 if (hostgrp.IsAttachment) // don't recoil avatars
3129 return;
2843 3130
2844 PhysicsActor pa = new_group.RootPart.PhysActor; 3131 PhysicsActor pa = new_group.RootPart.PhysActor;
2845 3132
2846 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3133 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2847 { 3134 {
2848 //Recoil. 3135 float groupmass = new_group.GetMass();
2849 llApplyImpulse(vel * groupmass, 0); 3136 vel *= -groupmass;
3137 llApplyImpulse(vel, 0);
2850 } 3138 }
2851 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3139 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3140 return;
3141
2852 }); 3142 });
2853 3143
2854 //ScriptSleep((int)((groupmass * velmag) / 10)); 3144 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2863,35 +3153,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2863 public void llLookAt(LSL_Vector target, double strength, double damping) 3153 public void llLookAt(LSL_Vector target, double strength, double damping)
2864 { 3154 {
2865 m_host.AddScriptLPS(1); 3155 m_host.AddScriptLPS(1);
2866 // Determine where we are looking from
2867 LSL_Vector from = llGetPos();
2868 3156
2869 // Work out the normalised vector from the source to the target 3157 // Get the normalized vector to the target
2870 LSL_Vector delta = llVecNorm(target - from); 3158 LSL_Vector d1 = llVecNorm(target - llGetPos());
2871 LSL_Vector angle = new LSL_Vector(0,0,0);
2872 3159
2873 // Calculate the yaw 3160 // Get the bearing (yaw)
2874 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3161 LSL_Vector a1 = new LSL_Vector(0,0,0);
2875 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3162 a1.z = llAtan2(d1.y, d1.x);
2876 3163
2877 // Calculate pitch 3164 // Get the elevation (pitch)
2878 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3165 LSL_Vector a2 = new LSL_Vector(0,0,0);
3166 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2879 3167
2880 // we need to convert from a vector describing 3168 LSL_Rotation r1 = llEuler2Rot(a1);
2881 // the angles of rotation in radians into rotation value 3169 LSL_Rotation r2 = llEuler2Rot(a2);
2882 LSL_Rotation rot = llEuler2Rot(angle); 3170 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 3171
2888 if (strength == 0 || pa == null || !pa.IsPhysical) 3172 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2889 { 3173 {
2890 llSetRot(rot); 3174 // Do nothing if either value is 0 (this has been checked in SL)
3175 if (strength <= 0.0 || damping <= 0.0)
3176 return;
3177
3178 llSetRot(r3 * r2 * r1);
2891 } 3179 }
2892 else 3180 else
2893 { 3181 {
2894 m_host.StartLookAt(rot, (float)strength, (float)damping); 3182 if (strength == 0)
3183 {
3184 llSetRot(r3 * r2 * r1);
3185 return;
3186 }
3187
3188 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2895 } 3189 }
2896 } 3190 }
2897 3191
@@ -2937,17 +3231,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2937 } 3231 }
2938 else 3232 else
2939 { 3233 {
2940 if (m_host.IsRoot) 3234 // new SL always returns object mass
2941 { 3235// if (m_host.IsRoot)
3236// {
2942 return m_host.ParentGroup.GetMass(); 3237 return m_host.ParentGroup.GetMass();
2943 } 3238// }
2944 else 3239// else
2945 { 3240// {
2946 return m_host.GetMass(); 3241// return m_host.GetMass();
2947 } 3242// }
2948 } 3243 }
2949 } 3244 }
2950 3245
3246
3247 public LSL_Float llGetMassMKS()
3248 {
3249 return 100f * llGetMass();
3250 }
3251
2951 public void llCollisionFilter(string name, string id, int accept) 3252 public void llCollisionFilter(string name, string id, int accept)
2952 { 3253 {
2953 m_host.AddScriptLPS(1); 3254 m_host.AddScriptLPS(1);
@@ -2995,8 +3296,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2995 { 3296 {
2996 // Unregister controls from Presence 3297 // Unregister controls from Presence
2997 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3298 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2998 // Remove Take Control permission.
2999 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3000 } 3299 }
3001 } 3300 }
3002 } 3301 }
@@ -3022,7 +3321,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3022 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3321 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3023 3322
3024 if (attachmentsModule != null) 3323 if (attachmentsModule != null)
3025 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3324 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3026 else 3325 else
3027 return false; 3326 return false;
3028 } 3327 }
@@ -3052,9 +3351,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3052 { 3351 {
3053 m_host.AddScriptLPS(1); 3352 m_host.AddScriptLPS(1);
3054 3353
3055// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3056// return;
3057
3058 if (m_item.PermsGranter != m_host.OwnerID) 3354 if (m_item.PermsGranter != m_host.OwnerID)
3059 return; 3355 return;
3060 3356
@@ -3097,6 +3393,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3097 3393
3098 public void llInstantMessage(string user, string message) 3394 public void llInstantMessage(string user, string message)
3099 { 3395 {
3396 UUID result;
3397 if (!UUID.TryParse(user, out result))
3398 {
3399 ShoutError("An invalid key was passed to llInstantMessage");
3400 ScriptSleep(2000);
3401 return;
3402 }
3403
3404
3100 m_host.AddScriptLPS(1); 3405 m_host.AddScriptLPS(1);
3101 3406
3102 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3407 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3111,14 +3416,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3111 UUID friendTransactionID = UUID.Random(); 3416 UUID friendTransactionID = UUID.Random();
3112 3417
3113 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3418 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3114 3419
3115 GridInstantMessage msg = new GridInstantMessage(); 3420 GridInstantMessage msg = new GridInstantMessage();
3116 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3421 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3117 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3422 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3118 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3423 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); 3424// 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()); 3425// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3121 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3426// DateTime dt = DateTime.UtcNow;
3427//
3428// // Ticks from UtcNow, but make it look like local. Evil, huh?
3429// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3430//
3431// try
3432// {
3433// // Convert that to the PST timezone
3434// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3435// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3436// }
3437// catch
3438// {
3439// // No logging here, as it could be VERY spammy
3440// }
3441//
3442// // And make it look local again to fool the unix time util
3443// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3444
3445 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3446
3122 //if (client != null) 3447 //if (client != null)
3123 //{ 3448 //{
3124 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3449 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3132,12 +3457,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3132 msg.message = message.Substring(0, 1024); 3457 msg.message = message.Substring(0, 1024);
3133 else 3458 else
3134 msg.message = message; 3459 msg.message = message;
3135 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3460 msg.dialog = (byte)19; // MessageFromObject
3136 msg.fromGroup = false;// fromGroup; 3461 msg.fromGroup = false;// fromGroup;
3137 msg.offline = (byte)0; //offline; 3462 msg.offline = (byte)0; //offline;
3138 msg.ParentEstateID = 0; //ParentEstateID; 3463 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3139 msg.Position = new Vector3(m_host.AbsolutePosition); 3464 msg.Position = new Vector3(m_host.AbsolutePosition);
3140 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3465 msg.RegionID = World.RegionInfo.RegionID.Guid;
3141 msg.binaryBucket 3466 msg.binaryBucket
3142 = Util.StringToBytes256( 3467 = Util.StringToBytes256(
3143 "{0}/{1}/{2}/{3}", 3468 "{0}/{1}/{2}/{3}",
@@ -3165,7 +3490,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3165 } 3490 }
3166 3491
3167 emailModule.SendEmail(m_host.UUID, address, subject, message); 3492 emailModule.SendEmail(m_host.UUID, address, subject, message);
3168 llSleep(EMAIL_PAUSE_TIME); 3493 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3169 } 3494 }
3170 3495
3171 public void llGetNextEmail(string address, string subject) 3496 public void llGetNextEmail(string address, string subject)
@@ -3411,7 +3736,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3411 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3736 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3412 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3737 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3413 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3738 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3739 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3414 ScriptBaseClass.PERMISSION_ATTACH; 3740 ScriptBaseClass.PERMISSION_ATTACH;
3741
3415 } 3742 }
3416 else 3743 else
3417 { 3744 {
@@ -3446,11 +3773,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3446 3773
3447 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3774 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3448 { 3775 {
3449 lock (m_host.TaskInventory) 3776 m_host.TaskInventory.LockItemsForWrite(true);
3450 { 3777 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3451 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3778 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3452 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3779 m_host.TaskInventory.LockItemsForWrite(false);
3453 }
3454 3780
3455 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3781 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3456 "run_time_permissions", new Object[] { 3782 "run_time_permissions", new Object[] {
@@ -3493,11 +3819,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3493 3819
3494 if (!m_waitingForScriptAnswer) 3820 if (!m_waitingForScriptAnswer)
3495 { 3821 {
3496 lock (m_host.TaskInventory) 3822 m_host.TaskInventory.LockItemsForWrite(true);
3497 { 3823 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3498 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3824 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3499 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3825 m_host.TaskInventory.LockItemsForWrite(false);
3500 }
3501 3826
3502 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3827 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3503 m_waitingForScriptAnswer=true; 3828 m_waitingForScriptAnswer=true;
@@ -3526,14 +3851,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3526 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3851 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3527 llReleaseControls(); 3852 llReleaseControls();
3528 3853
3529 lock (m_host.TaskInventory) 3854 m_host.TaskInventory.LockItemsForWrite(true);
3530 { 3855 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3531 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3856 m_host.TaskInventory.LockItemsForWrite(false);
3532 } 3857
3533 3858 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3534 m_ScriptEngine.PostScriptEvent( 3859 "run_time_permissions", new Object[] {
3535 m_item.ItemID, 3860 new LSL_Integer(answer) },
3536 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3861 new DetectParams[0]));
3537 } 3862 }
3538 3863
3539 public LSL_String llGetPermissionsKey() 3864 public LSL_String llGetPermissionsKey()
@@ -3572,14 +3897,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3572 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3897 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3573 { 3898 {
3574 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3899 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3575 3900 if (parts.Count > 0)
3576 foreach (SceneObjectPart part in parts) 3901 {
3577 part.SetFaceColorAlpha(face, color, null); 3902 try
3903 {
3904 foreach (SceneObjectPart part in parts)
3905 part.SetFaceColorAlpha(face, color, null);
3906 }
3907 finally
3908 {
3909 }
3910 }
3578 } 3911 }
3579 3912
3580 public void llCreateLink(string target, int parent) 3913 public void llCreateLink(string target, int parent)
3581 { 3914 {
3582 m_host.AddScriptLPS(1); 3915 m_host.AddScriptLPS(1);
3916
3583 UUID targetID; 3917 UUID targetID;
3584 3918
3585 if (!UUID.TryParse(target, out targetID)) 3919 if (!UUID.TryParse(target, out targetID))
@@ -3685,10 +4019,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3685 // Restructuring Multiple Prims. 4019 // Restructuring Multiple Prims.
3686 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4020 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3687 parts.Remove(parentPrim.RootPart); 4021 parts.Remove(parentPrim.RootPart);
3688 foreach (SceneObjectPart part in parts) 4022 if (parts.Count > 0)
3689 { 4023 {
3690 parentPrim.DelinkFromGroup(part.LocalId, true); 4024 try
4025 {
4026 foreach (SceneObjectPart part in parts)
4027 {
4028 parentPrim.DelinkFromGroup(part.LocalId, true);
4029 }
4030 }
4031 finally
4032 {
4033 }
3691 } 4034 }
4035
3692 parentPrim.HasGroupChanged = true; 4036 parentPrim.HasGroupChanged = true;
3693 parentPrim.ScheduleGroupForFullUpdate(); 4037 parentPrim.ScheduleGroupForFullUpdate();
3694 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4038 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3697,12 +4041,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3697 { 4041 {
3698 SceneObjectPart newRoot = parts[0]; 4042 SceneObjectPart newRoot = parts[0];
3699 parts.Remove(newRoot); 4043 parts.Remove(newRoot);
3700 foreach (SceneObjectPart part in parts) 4044
4045 try
3701 { 4046 {
3702 // Required for linking 4047 foreach (SceneObjectPart part in parts)
3703 part.ClearUpdateSchedule(); 4048 {
3704 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4049 part.ClearUpdateSchedule();
4050 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4051 }
3705 } 4052 }
4053 finally
4054 {
4055 }
4056
4057
3706 newRoot.ParentGroup.HasGroupChanged = true; 4058 newRoot.ParentGroup.HasGroupChanged = true;
3707 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4059 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3708 } 4060 }
@@ -3722,6 +4074,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3722 public void llBreakAllLinks() 4074 public void llBreakAllLinks()
3723 { 4075 {
3724 m_host.AddScriptLPS(1); 4076 m_host.AddScriptLPS(1);
4077
4078 TaskInventoryItem item = m_item;
4079
4080 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4081 && !m_automaticLinkPermission)
4082 {
4083 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4084 return;
4085 }
4086
3725 SceneObjectGroup parentPrim = m_host.ParentGroup; 4087 SceneObjectGroup parentPrim = m_host.ParentGroup;
3726 if (parentPrim.AttachmentPoint != 0) 4088 if (parentPrim.AttachmentPoint != 0)
3727 return; // Fail silently if attached 4089 return; // Fail silently if attached
@@ -3741,25 +4103,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3741 public LSL_String llGetLinkKey(int linknum) 4103 public LSL_String llGetLinkKey(int linknum)
3742 { 4104 {
3743 m_host.AddScriptLPS(1); 4105 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); 4106 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3764 if (part != null) 4107 if (part != null)
3765 { 4108 {
@@ -3767,6 +4110,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3767 } 4110 }
3768 else 4111 else
3769 { 4112 {
4113 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4114 {
4115 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4116
4117 if (linknum < 0)
4118 return UUID.Zero.ToString();
4119
4120 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4121 if (avatars.Count > linknum)
4122 {
4123 return avatars[linknum].UUID.ToString();
4124 }
4125 }
3770 return UUID.Zero.ToString(); 4126 return UUID.Zero.ToString();
3771 } 4127 }
3772 } 4128 }
@@ -3866,17 +4222,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3866 m_host.AddScriptLPS(1); 4222 m_host.AddScriptLPS(1);
3867 int count = 0; 4223 int count = 0;
3868 4224
3869 lock (m_host.TaskInventory) 4225 m_host.TaskInventory.LockItemsForRead(true);
4226 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3870 { 4227 {
3871 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4228 if (inv.Value.Type == type || type == -1)
3872 { 4229 {
3873 if (inv.Value.Type == type || type == -1) 4230 count = count + 1;
3874 {
3875 count = count + 1;
3876 }
3877 } 4231 }
3878 } 4232 }
3879 4233
4234 m_host.TaskInventory.LockItemsForRead(false);
3880 return count; 4235 return count;
3881 } 4236 }
3882 4237
@@ -3885,16 +4240,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3885 m_host.AddScriptLPS(1); 4240 m_host.AddScriptLPS(1);
3886 ArrayList keys = new ArrayList(); 4241 ArrayList keys = new ArrayList();
3887 4242
3888 lock (m_host.TaskInventory) 4243 m_host.TaskInventory.LockItemsForRead(true);
4244 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3889 { 4245 {
3890 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4246 if (inv.Value.Type == type || type == -1)
3891 { 4247 {
3892 if (inv.Value.Type == type || type == -1) 4248 keys.Add(inv.Value.Name);
3893 {
3894 keys.Add(inv.Value.Name);
3895 }
3896 } 4249 }
3897 } 4250 }
4251 m_host.TaskInventory.LockItemsForRead(false);
3898 4252
3899 if (keys.Count == 0) 4253 if (keys.Count == 0)
3900 { 4254 {
@@ -3932,7 +4286,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3932 if (item == null) 4286 if (item == null)
3933 { 4287 {
3934 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4288 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)); 4289 return;
4290// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3936 } 4291 }
3937 4292
3938 UUID objId = item.ItemID; 4293 UUID objId = item.ItemID;
@@ -3960,33 +4315,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3960 return; 4315 return;
3961 } 4316 }
3962 } 4317 }
4318
3963 // destination is an avatar 4319 // destination is an avatar
3964 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4320 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3965 4321
3966 if (agentItem == null) 4322 if (agentItem == null)
3967 return; 4323 return;
3968 4324
3969 if (m_TransferModule != null) 4325 byte[] bucket = new byte[1];
3970 { 4326 bucket[0] = (byte)item.Type;
3971 byte[] bucket = new byte[] { (byte)item.Type }; 4327 //byte[] objBytes = agentItem.ID.GetBytes();
4328 //Array.Copy(objBytes, 0, bucket, 1, 16);
3972 4329
3973 GridInstantMessage msg = new GridInstantMessage(World, 4330 GridInstantMessage msg = new GridInstantMessage(World,
3974 m_host.UUID, m_host.Name + ", an object owned by " + 4331 m_host.OwnerID, m_host.Name, destId,
3975 resolveName(m_host.OwnerID) + ",", destId, 4332 (byte)InstantMessageDialog.TaskInventoryOffered,
3976 (byte)InstantMessageDialog.TaskInventoryOffered, 4333 false, item.Name+". "+m_host.Name+" is located at "+
3977 false, item.Name + "\n" + m_host.Name + " is located at " + 4334 World.RegionInfo.RegionName+" "+
3978 World.RegionInfo.RegionName+" "+ 4335 m_host.AbsolutePosition.ToString(),
3979 m_host.AbsolutePosition.ToString(), 4336 agentItem.ID, true, m_host.AbsolutePosition,
3980 agentItem.ID, true, m_host.AbsolutePosition, 4337 bucket);
3981 bucket);
3982 4338
3983 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4339 ScenePresence sp;
3984 }
3985 4340
4341 if (World.TryGetScenePresence(destId, out sp))
4342 {
4343 sp.ControllingClient.SendInstantMessage(msg);
4344 }
4345 else
4346 {
4347 if (m_TransferModule != null)
4348 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4349 }
4350
4351 //This delay should only occur when giving inventory to avatars.
3986 ScriptSleep(3000); 4352 ScriptSleep(3000);
3987 } 4353 }
3988 } 4354 }
3989 4355
4356 [DebuggerNonUserCode]
3990 public void llRemoveInventory(string name) 4357 public void llRemoveInventory(string name)
3991 { 4358 {
3992 m_host.AddScriptLPS(1); 4359 m_host.AddScriptLPS(1);
@@ -4030,109 +4397,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4030 { 4397 {
4031 m_host.AddScriptLPS(1); 4398 m_host.AddScriptLPS(1);
4032 4399
4033 UUID uuid = (UUID)id; 4400 UUID uuid;
4034 PresenceInfo pinfo = null; 4401 if (UUID.TryParse(id, out uuid))
4035 UserAccount account;
4036
4037 UserInfoCacheEntry ce;
4038 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4039 { 4402 {
4040 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4403 PresenceInfo pinfo = null;
4041 if (account == null) 4404 UserAccount account;
4405
4406 UserInfoCacheEntry ce;
4407 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4042 { 4408 {
4043 m_userInfoCache[uuid] = null; // Cache negative 4409 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4044 return UUID.Zero.ToString(); 4410 if (account == null)
4045 } 4411 {
4412 m_userInfoCache[uuid] = null; // Cache negative
4413 return UUID.Zero.ToString();
4414 }
4046 4415
4047 4416
4048 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4417 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4049 if (pinfos != null && pinfos.Length > 0) 4418 if (pinfos != null && pinfos.Length > 0)
4050 {
4051 foreach (PresenceInfo p in pinfos)
4052 { 4419 {
4053 if (p.RegionID != UUID.Zero) 4420 foreach (PresenceInfo p in pinfos)
4054 { 4421 {
4055 pinfo = p; 4422 if (p.RegionID != UUID.Zero)
4423 {
4424 pinfo = p;
4425 }
4056 } 4426 }
4057 } 4427 }
4058 }
4059 4428
4060 ce = new UserInfoCacheEntry(); 4429 ce = new UserInfoCacheEntry();
4061 ce.time = Util.EnvironmentTickCount(); 4430 ce.time = Util.EnvironmentTickCount();
4062 ce.account = account; 4431 ce.account = account;
4063 ce.pinfo = pinfo; 4432 ce.pinfo = pinfo;
4064 } 4433 m_userInfoCache[uuid] = ce;
4065 else 4434 }
4066 { 4435 else
4067 if (ce == null) 4436 {
4068 return UUID.Zero.ToString(); 4437 if (ce == null)
4438 return UUID.Zero.ToString();
4069 4439
4070 account = ce.account; 4440 account = ce.account;
4071 pinfo = ce.pinfo; 4441 pinfo = ce.pinfo;
4072 } 4442 }
4073 4443
4074 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4444 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 { 4445 {
4079 foreach (PresenceInfo p in pinfos) 4446 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4447 if (pinfos != null && pinfos.Length > 0)
4080 { 4448 {
4081 if (p.RegionID != UUID.Zero) 4449 foreach (PresenceInfo p in pinfos)
4082 { 4450 {
4083 pinfo = p; 4451 if (p.RegionID != UUID.Zero)
4452 {
4453 pinfo = p;
4454 }
4084 } 4455 }
4085 } 4456 }
4086 } 4457 else
4087 else 4458 pinfo = null;
4088 pinfo = null;
4089 4459
4090 ce.time = Util.EnvironmentTickCount(); 4460 ce.time = Util.EnvironmentTickCount();
4091 ce.pinfo = pinfo; 4461 ce.pinfo = pinfo;
4092 } 4462 }
4093 4463
4094 string reply = String.Empty; 4464 string reply = String.Empty;
4095 4465
4096 switch (data) 4466 switch (data)
4097 { 4467 {
4098 case 1: // DATA_ONLINE (0|1) 4468 case 1: // DATA_ONLINE (0|1)
4099 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4469 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4100 reply = "1"; 4470 reply = "1";
4101 else 4471 else
4102 reply = "0"; 4472 reply = "0";
4103 break; 4473 break;
4104 case 2: // DATA_NAME (First Last) 4474 case 2: // DATA_NAME (First Last)
4105 reply = account.FirstName + " " + account.LastName; 4475 reply = account.FirstName + " " + account.LastName;
4106 break; 4476 break;
4107 case 3: // DATA_BORN (YYYY-MM-DD) 4477 case 3: // DATA_BORN (YYYY-MM-DD)
4108 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4478 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4109 born = born.AddSeconds(account.Created); 4479 born = born.AddSeconds(account.Created);
4110 reply = born.ToString("yyyy-MM-dd"); 4480 reply = born.ToString("yyyy-MM-dd");
4111 break; 4481 break;
4112 case 4: // DATA_RATING (0,0,0,0,0,0) 4482 case 4: // DATA_RATING (0,0,0,0,0,0)
4113 reply = "0,0,0,0,0,0"; 4483 reply = "0,0,0,0,0,0";
4114 break; 4484 break;
4115 case 7: // DATA_USERLEVEL (integer) 4485 case 8: // DATA_PAYINFO (0|1|2|3)
4116 reply = account.UserLevel.ToString(); 4486 reply = "0";
4117 break; 4487 break;
4118 case 8: // DATA_PAYINFO (0|1|2|3) 4488 default:
4119 reply = "0"; 4489 return UUID.Zero.ToString(); // Raise no event
4120 break; 4490 }
4121 default:
4122 return UUID.Zero.ToString(); // Raise no event
4123 }
4124 4491
4125 UUID rq = UUID.Random(); 4492 UUID rq = UUID.Random();
4126 4493
4127 UUID tid = AsyncCommands. 4494 UUID tid = AsyncCommands.
4128 DataserverPlugin.RegisterRequest(m_host.LocalId, 4495 DataserverPlugin.RegisterRequest(m_host.LocalId,
4129 m_item.ItemID, rq.ToString()); 4496 m_item.ItemID, rq.ToString());
4130 4497
4131 AsyncCommands. 4498 AsyncCommands.
4132 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4499 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4133 4500
4134 ScriptSleep(100); 4501 ScriptSleep(100);
4135 return tid.ToString(); 4502 return tid.ToString();
4503 }
4504 else
4505 {
4506 ShoutError("Invalid UUID passed to llRequestAgentData.");
4507 }
4508 return "";
4136 } 4509 }
4137 4510
4138 public LSL_String llRequestInventoryData(string name) 4511 public LSL_String llRequestInventoryData(string name)
@@ -4189,13 +4562,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4189 if (UUID.TryParse(agent, out agentId)) 4562 if (UUID.TryParse(agent, out agentId))
4190 { 4563 {
4191 ScenePresence presence = World.GetScenePresence(agentId); 4564 ScenePresence presence = World.GetScenePresence(agentId);
4192 if (presence != null) 4565 if (presence != null && presence.PresenceType != PresenceType.Npc)
4193 { 4566 {
4567 // agent must not be a god
4568 if (presence.UserLevel >= 200) return;
4569
4194 // agent must be over the owners land 4570 // agent must be over the owners land
4195 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4571 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4196 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4572 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4197 { 4573 {
4198 World.TeleportClientHome(agentId, presence.ControllingClient); 4574 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4575 {
4576 // They can't be teleported home for some reason
4577 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4578 if (regionInfo != null)
4579 {
4580 World.RequestTeleportLocation(
4581 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4582 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4583 }
4584 }
4199 } 4585 }
4200 } 4586 }
4201 } 4587 }
@@ -4302,7 +4688,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4302 UUID av = new UUID(); 4688 UUID av = new UUID();
4303 if (!UUID.TryParse(agent,out av)) 4689 if (!UUID.TryParse(agent,out av))
4304 { 4690 {
4305 LSLError("First parameter to llDialog needs to be a key"); 4691 //LSLError("First parameter to llDialog needs to be a key");
4306 return; 4692 return;
4307 } 4693 }
4308 4694
@@ -4334,7 +4720,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4334 public void llCollisionSound(string impact_sound, double impact_volume) 4720 public void llCollisionSound(string impact_sound, double impact_volume)
4335 { 4721 {
4336 m_host.AddScriptLPS(1); 4722 m_host.AddScriptLPS(1);
4337 4723
4724 if(impact_sound == "")
4725 {
4726 m_host.CollisionSoundVolume = (float)impact_volume;
4727 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4728 m_host.CollisionSoundType = 0;
4729 return;
4730 }
4338 // TODO: Parameter check logic required. 4731 // TODO: Parameter check logic required.
4339 UUID soundId = UUID.Zero; 4732 UUID soundId = UUID.Zero;
4340 if (!UUID.TryParse(impact_sound, out soundId)) 4733 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4347,6 +4740,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4347 4740
4348 m_host.CollisionSound = soundId; 4741 m_host.CollisionSound = soundId;
4349 m_host.CollisionSoundVolume = (float)impact_volume; 4742 m_host.CollisionSoundVolume = (float)impact_volume;
4743 m_host.CollisionSoundType = 1;
4350 } 4744 }
4351 4745
4352 public LSL_String llGetAnimation(string id) 4746 public LSL_String llGetAnimation(string id)
@@ -4360,14 +4754,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4360 4754
4361 if (m_host.RegionHandle == presence.RegionHandle) 4755 if (m_host.RegionHandle == presence.RegionHandle)
4362 { 4756 {
4363 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4364
4365 if (presence != null) 4757 if (presence != null)
4366 { 4758 {
4367 AnimationSet currentAnims = presence.Animator.Animations; 4759 if (presence.SitGround)
4368 string currentAnimationState = String.Empty; 4760 return "Sitting on Ground";
4369 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4761 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4370 return currentAnimationState; 4762 return "Sitting";
4763
4764 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4765 string lslMovementAnimation;
4766
4767 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4768 return lslMovementAnimation;
4371 } 4769 }
4372 } 4770 }
4373 4771
@@ -4514,7 +4912,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4514 { 4912 {
4515 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4913 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4516 float distance_term = distance * distance * distance; // Script Energy 4914 float distance_term = distance * distance * distance; // Script Energy
4517 float pusher_mass = m_host.GetMass(); 4915 // use total object mass and not part
4916 float pusher_mass = m_host.ParentGroup.GetMass();
4518 4917
4519 float PUSH_ATTENUATION_DISTANCE = 17f; 4918 float PUSH_ATTENUATION_DISTANCE = 17f;
4520 float PUSH_ATTENUATION_SCALE = 5f; 4919 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4764,6 +5163,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4764 { 5163 {
4765 return item.AssetID.ToString(); 5164 return item.AssetID.ToString();
4766 } 5165 }
5166 m_host.TaskInventory.LockItemsForRead(false);
4767 5167
4768 return UUID.Zero.ToString(); 5168 return UUID.Zero.ToString();
4769 } 5169 }
@@ -4897,7 +5297,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4897 public LSL_Vector llGetCenterOfMass() 5297 public LSL_Vector llGetCenterOfMass()
4898 { 5298 {
4899 m_host.AddScriptLPS(1); 5299 m_host.AddScriptLPS(1);
4900 Vector3 center = m_host.GetGeometricCenter(); 5300 Vector3 center = m_host.GetCenterOfMass();
4901 return new LSL_Vector(center.X,center.Y,center.Z); 5301 return new LSL_Vector(center.X,center.Y,center.Z);
4902 } 5302 }
4903 5303
@@ -4916,14 +5316,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4916 { 5316 {
4917 m_host.AddScriptLPS(1); 5317 m_host.AddScriptLPS(1);
4918 5318
4919 if (src == null) 5319 return src.Length;
4920 {
4921 return 0;
4922 }
4923 else
4924 {
4925 return src.Length;
4926 }
4927 } 5320 }
4928 5321
4929 public LSL_Integer llList2Integer(LSL_List src, int index) 5322 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4994,7 +5387,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4994 else if (src.Data[index] is LSL_Float) 5387 else if (src.Data[index] is LSL_Float)
4995 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5388 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4996 else if (src.Data[index] is LSL_String) 5389 else if (src.Data[index] is LSL_String)
4997 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5390 {
5391 string str = ((LSL_String) src.Data[index]).m_string;
5392 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5393 if (m != Match.Empty)
5394 {
5395 str = m.Value;
5396 double d = 0.0;
5397 if (!Double.TryParse(str, out d))
5398 return 0.0;
5399
5400 return d;
5401 }
5402 return 0.0;
5403 }
4998 return Convert.ToDouble(src.Data[index]); 5404 return Convert.ToDouble(src.Data[index]);
4999 } 5405 }
5000 catch (FormatException) 5406 catch (FormatException)
@@ -5036,7 +5442,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5036 // for completion and should LSL_Key ever be implemented 5442 // for completion and should LSL_Key ever be implemented
5037 // as it's own struct 5443 // as it's own struct
5038 else if (!(src.Data[index] is LSL_String || 5444 else if (!(src.Data[index] is LSL_String ||
5039 src.Data[index] is LSL_Key)) 5445 src.Data[index] is LSL_Key ||
5446 src.Data[index] is String))
5040 { 5447 {
5041 return ""; 5448 return "";
5042 } 5449 }
@@ -5294,7 +5701,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5294 } 5701 }
5295 } 5702 }
5296 } 5703 }
5297 else { 5704 else
5705 {
5298 object[] array = new object[src.Length]; 5706 object[] array = new object[src.Length];
5299 Array.Copy(src.Data, 0, array, 0, src.Length); 5707 Array.Copy(src.Data, 0, array, 0, src.Length);
5300 result = new LSL_List(array); 5708 result = new LSL_List(array);
@@ -5401,7 +5809,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5401 public LSL_Integer llGetRegionAgentCount() 5809 public LSL_Integer llGetRegionAgentCount()
5402 { 5810 {
5403 m_host.AddScriptLPS(1); 5811 m_host.AddScriptLPS(1);
5404 return new LSL_Integer(World.GetRootAgentCount()); 5812
5813 int count = 0;
5814 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5815 count++;
5816 });
5817
5818 return new LSL_Integer(count);
5405 } 5819 }
5406 5820
5407 public LSL_Vector llGetRegionCorner() 5821 public LSL_Vector llGetRegionCorner()
@@ -5634,6 +6048,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5634 flags |= ScriptBaseClass.AGENT_AWAY; 6048 flags |= ScriptBaseClass.AGENT_AWAY;
5635 } 6049 }
5636 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
5637 // 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???
5638 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6059 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5639 { 6060 {
@@ -5681,6 +6102,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5681 flags |= ScriptBaseClass.AGENT_SITTING; 6102 flags |= ScriptBaseClass.AGENT_SITTING;
5682 } 6103 }
5683 6104
6105 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6106 {
6107 flags |= ScriptBaseClass.AGENT_MALE;
6108 }
6109
5684 return flags; 6110 return flags;
5685 } 6111 }
5686 6112
@@ -5828,9 +6254,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5828 6254
5829 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6255 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5830 6256
5831 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
5832 { 6265 {
5833 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5834 } 6266 }
5835 } 6267 }
5836 6268
@@ -5882,13 +6314,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5882 6314
5883 if (m_host.OwnerID == land.LandData.OwnerID) 6315 if (m_host.OwnerID == land.LandData.OwnerID)
5884 { 6316 {
5885 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");
5886 } 6320 }
5887 } 6321 }
5888 } 6322 }
5889 ScriptSleep(5000); 6323 ScriptSleep(5000);
5890 } 6324 }
5891 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
5892 public LSL_Integer llOverMyLand(string id) 6331 public LSL_Integer llOverMyLand(string id)
5893 { 6332 {
5894 m_host.AddScriptLPS(1); 6333 m_host.AddScriptLPS(1);
@@ -5947,20 +6386,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5947 return agentSize; 6386 return agentSize;
5948 } 6387 }
5949 6388
5950 public LSL_Integer llSameGroup(string agent) 6389 public LSL_Integer llSameGroup(string id)
5951 { 6390 {
5952 m_host.AddScriptLPS(1); 6391 m_host.AddScriptLPS(1);
5953 UUID agentId = new UUID(); 6392 UUID uuid = new UUID();
5954 if (!UUID.TryParse(agent, out agentId)) 6393 if (!UUID.TryParse(id, out uuid))
5955 return new LSL_Integer(0);
5956 ScenePresence presence = World.GetScenePresence(agentId);
5957 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5958 return new LSL_Integer(0); 6394 return new LSL_Integer(0);
5959 IClientAPI client = presence.ControllingClient; 6395
5960 if (m_host.GroupID == client.ActiveGroupId) 6396 // Check if it's a group key
6397 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5961 return new LSL_Integer(1); 6398 return new LSL_Integer(1);
5962 else 6399
6400 // We got passed a UUID.Zero
6401 if (uuid == UUID.Zero)
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
5963 return new LSL_Integer(0); 6427 return new LSL_Integer(0);
6428 }
6429
6430 return new LSL_Integer(0);
5964 } 6431 }
5965 6432
5966 public void llUnSit(string id) 6433 public void llUnSit(string id)
@@ -6085,7 +6552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6085 return m_host.ParentGroup.AttachmentPoint; 6552 return m_host.ParentGroup.AttachmentPoint;
6086 } 6553 }
6087 6554
6088 public LSL_Integer llGetFreeMemory() 6555 public virtual LSL_Integer llGetFreeMemory()
6089 { 6556 {
6090 m_host.AddScriptLPS(1); 6557 m_host.AddScriptLPS(1);
6091 // Make scripts designed for LSO happy 6558 // Make scripts designed for LSO happy
@@ -6202,7 +6669,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6202 SetParticleSystem(m_host, rules); 6669 SetParticleSystem(m_host, rules);
6203 } 6670 }
6204 6671
6205 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6672 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6673 {
6206 6674
6207 6675
6208 if (rules.Length == 0) 6676 if (rules.Length == 0)
@@ -6516,6 +6984,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6516 6984
6517 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6985 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6518 { 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
6519 part.SitTargetPosition = offset; 6991 part.SitTargetPosition = offset;
6520 part.SitTargetOrientation = rot; 6992 part.SitTargetOrientation = rot;
6521 part.ParentGroup.HasGroupChanged = true; 6993 part.ParentGroup.HasGroupChanged = true;
@@ -6671,13 +7143,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6671 UUID av = new UUID(); 7143 UUID av = new UUID();
6672 if (!UUID.TryParse(avatar,out av)) 7144 if (!UUID.TryParse(avatar,out av))
6673 { 7145 {
6674 LSLError("First parameter to llDialog needs to be a key"); 7146 //LSLError("First parameter to llDialog needs to be a key");
6675 return; 7147 return;
6676 } 7148 }
6677 if (buttons.Length < 1) 7149 if (buttons.Length < 1)
6678 { 7150 {
6679 LSLError("No less than 1 button can be shown"); 7151 buttons.Add("OK");
6680 return;
6681 } 7152 }
6682 if (buttons.Length > 12) 7153 if (buttons.Length > 12)
6683 { 7154 {
@@ -6694,7 +7165,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6694 } 7165 }
6695 if (buttons.Data[i].ToString().Length > 24) 7166 if (buttons.Data[i].ToString().Length > 24)
6696 { 7167 {
6697 LSLError("button label cannot be longer than 24 characters"); 7168 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6698 return; 7169 return;
6699 } 7170 }
6700 buts[i] = buttons.Data[i].ToString(); 7171 buts[i] = buttons.Data[i].ToString();
@@ -6761,9 +7232,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6761 return; 7232 return;
6762 } 7233 }
6763 7234
6764 // the rest of the permission checks are done in RezScript, so check the pin there as well 7235 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6765 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);
6766 7242
7243 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7244 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7245 }
7246 }
6767 // 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
6768 ScriptSleep(3000); 7248 ScriptSleep(3000);
6769 } 7249 }
@@ -6826,19 +7306,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6826 public LSL_String llMD5String(string src, int nonce) 7306 public LSL_String llMD5String(string src, int nonce)
6827 { 7307 {
6828 m_host.AddScriptLPS(1); 7308 m_host.AddScriptLPS(1);
6829 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7309 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6830 } 7310 }
6831 7311
6832 public LSL_String llSHA1String(string src) 7312 public LSL_String llSHA1String(string src)
6833 { 7313 {
6834 m_host.AddScriptLPS(1); 7314 m_host.AddScriptLPS(1);
6835 return Util.SHA1Hash(src).ToLower(); 7315 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6836 } 7316 }
6837 7317
6838 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)
6839 { 7319 {
6840 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.
6841 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;
6842 7324
6843 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7325 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6844 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7326 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6943,6 +7425,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6943 // Prim type box, cylinder and prism. 7425 // Prim type box, cylinder and prism.
6944 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)
6945 { 7427 {
7428 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7429 return;
7430
6946 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.
6947 ObjectShapePacket.ObjectDataBlock shapeBlock; 7432 ObjectShapePacket.ObjectDataBlock shapeBlock;
6948 7433
@@ -6996,6 +7481,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6996 // Prim type sphere. 7481 // Prim type sphere.
6997 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)
6998 { 7483 {
7484 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7485 return;
7486
6999 ObjectShapePacket.ObjectDataBlock shapeBlock; 7487 ObjectShapePacket.ObjectDataBlock shapeBlock;
7000 7488
7001 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7489 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7037,6 +7525,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7037 // Prim type torus, tube and ring. 7525 // Prim type torus, tube and ring.
7038 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)
7039 { 7527 {
7528 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7529 return;
7530
7040 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.
7041 ObjectShapePacket.ObjectDataBlock shapeBlock; 7532 ObjectShapePacket.ObjectDataBlock shapeBlock;
7042 7533
@@ -7172,6 +7663,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7172 // Prim type sculpt. 7663 // Prim type sculpt.
7173 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7664 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7174 { 7665 {
7666 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7667 return;
7668
7175 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7669 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7176 UUID sculptId; 7670 UUID sculptId;
7177 7671
@@ -7196,7 +7690,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7196 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7690 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7197 { 7691 {
7198 // default 7692 // default
7199 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7693 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7200 } 7694 }
7201 7695
7202 part.Shape.SetSculptProperties((byte)type, sculptId); 7696 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7213,48 +7707,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7213 ScriptSleep(200); 7707 ScriptSleep(200);
7214 } 7708 }
7215 7709
7216 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7710 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7217 { 7711 {
7218 m_host.AddScriptLPS(1); 7712 m_host.AddScriptLPS(1);
7219 7713
7220 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7714 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7221 7715
7222 ScriptSleep(200); 7716 ScriptSleep(200);
7223 } 7717 }
7224 7718
7225 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7719 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7226 { 7720 {
7227 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);
7228 7728
7229 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 }
7230 } 7764 }
7231 7765
7232 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)
7233 { 7769 {
7234 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;
7235 7776
7236 LSL_List remaining = null; 7777 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7237 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;
7238 7785
7239 foreach (SceneObjectPart part in parts) 7786 part.UpdateExtraPhysics(physdata);
7240 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7787 }
7241 7788
7242 while (remaining != null && remaining.Length > 2) 7789 public void llSetPhysicsMaterial(int material_bits,
7243 { 7790 float material_gravity_modifier, float material_restitution,
7244 linknumber = remaining.GetLSLIntegerItem(0); 7791 float material_friction, float material_density)
7245 rules = remaining.GetSublist(1, -1); 7792 {
7246 parts = GetLinkParts(linknumber); 7793 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7794 }
7247 7795
7248 foreach (SceneObjectPart part in parts) 7796 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7249 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;
7250 } 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);
7251 } 7824 }
7252 7825
7253 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)
7254 { 7827 {
7828 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7829 return null;
7830
7255 int idx = 0; 7831 int idx = 0;
7256 int idxStart = 0; 7832 int idxStart = 0;
7257 7833
7834 SceneObjectGroup parentgrp = part.ParentGroup;
7835
7258 bool positionChanged = false; 7836 bool positionChanged = false;
7259 LSL_Vector currentPosition = GetPartLocalPos(part); 7837 LSL_Vector currentPosition = GetPartLocalPos(part);
7260 7838
@@ -7279,8 +7857,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7279 return null; 7857 return null;
7280 7858
7281 v=rules.GetVector3Item(idx++); 7859 v=rules.GetVector3Item(idx++);
7282 positionChanged = true;
7283 currentPosition = GetSetPosTarget(part, v, currentPosition); 7860 currentPosition = GetSetPosTarget(part, v, currentPosition);
7861 positionChanged = true;
7284 7862
7285 break; 7863 break;
7286 case (int)ScriptBaseClass.PRIM_SIZE: 7864 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7296,8 +7874,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7296 return null; 7874 return null;
7297 7875
7298 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7876 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7877 SceneObjectPart rootPart = parentgrp.RootPart;
7299 // try to let this work as in SL... 7878 // try to let this work as in SL...
7300 if (part.ParentID == 0) 7879 if (rootPart == part)
7301 { 7880 {
7302 // special case: If we are root, rotate complete SOG to new rotation 7881 // special case: If we are root, rotate complete SOG to new rotation
7303 SetRot(part, q); 7882 SetRot(part, q);
@@ -7305,7 +7884,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7305 else 7884 else
7306 { 7885 {
7307 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 7886 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7308 SceneObjectPart rootPart = part.ParentGroup.RootPart; 7887 // sounds like sl bug that we need to replicate
7309 SetRot(part, rootPart.RotationOffset * (Quaternion)q); 7888 SetRot(part, rootPart.RotationOffset * (Quaternion)q);
7310 } 7889 }
7311 7890
@@ -7557,7 +8136,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7557 return null; 8136 return null;
7558 8137
7559 string ph = rules.Data[idx++].ToString(); 8138 string ph = rules.Data[idx++].ToString();
7560 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8139 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7561 8140
7562 break; 8141 break;
7563 8142
@@ -7575,12 +8154,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7575 part.ScriptSetPhysicsStatus(physics); 8154 part.ScriptSetPhysicsStatus(physics);
7576 break; 8155 break;
7577 8156
8157 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8158 if (remain < 1)
8159 return null;
8160
8161 int shape_type = rules.GetLSLIntegerItem(idx++);
8162
8163 ExtraPhysicsData physdata = new ExtraPhysicsData();
8164 physdata.Density = part.Density;
8165 physdata.Bounce = part.Bounciness;
8166 physdata.GravitationModifier = part.GravityModifier;
8167 physdata.PhysShapeType = (PhysShapeType)shape_type;
8168
8169 part.UpdateExtraPhysics(physdata);
8170
8171 break;
8172
8173 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8174 if (remain < 5)
8175 return null;
8176
8177 int material_bits = rules.GetLSLIntegerItem(idx++);
8178 float material_density = (float)rules.GetLSLFloatItem(idx++);
8179 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8180 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8181 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8182
8183 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8184
8185 break;
8186
7578 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8187 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7579 if (remain < 1) 8188 if (remain < 1)
7580 return null; 8189 return null;
7581 string temp = rules.Data[idx++].ToString(); 8190 string temp = rules.Data[idx++].ToString();
7582 8191
7583 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8192 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7584 8193
7585 break; 8194 break;
7586 8195
@@ -7654,7 +8263,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7654 if (part.ParentGroup.RootPart == part) 8263 if (part.ParentGroup.RootPart == part)
7655 { 8264 {
7656 SceneObjectGroup parent = part.ParentGroup; 8265 SceneObjectGroup parent = part.ParentGroup;
7657 parent.UpdateGroupPosition(currentPosition); 8266 Util.FireAndForget(delegate(object x) {
8267 parent.UpdateGroupPosition(currentPosition);
8268 });
7658 } 8269 }
7659 else 8270 else
7660 { 8271 {
@@ -7699,10 +8310,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7699 8310
7700 public LSL_String llXorBase64Strings(string str1, string str2) 8311 public LSL_String llXorBase64Strings(string str1, string str2)
7701 { 8312 {
7702 m_host.AddScriptLPS(1); 8313 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7703 Deprecated("llXorBase64Strings"); 8314
7704 ScriptSleep(300); 8315 ScriptSleep(300);
7705 return String.Empty; 8316 m_host.AddScriptLPS(1);
8317
8318 if (str1 == String.Empty)
8319 return String.Empty;
8320 if (str2 == String.Empty)
8321 return str1;
8322
8323 int len = str2.Length;
8324 if ((len % 4) != 0) // LL is EVIL!!!!
8325 {
8326 while (str2.EndsWith("="))
8327 str2 = str2.Substring(0, str2.Length - 1);
8328
8329 len = str2.Length;
8330 int mod = len % 4;
8331
8332 if (mod == 1)
8333 str2 = str2.Substring(0, str2.Length - 1);
8334 else if (mod == 2)
8335 str2 += "==";
8336 else if (mod == 3)
8337 str2 += "=";
8338 }
8339
8340 byte[] data1;
8341 byte[] data2;
8342 try
8343 {
8344 data1 = Convert.FromBase64String(str1);
8345 data2 = Convert.FromBase64String(str2);
8346 }
8347 catch (Exception)
8348 {
8349 return new LSL_String(String.Empty);
8350 }
8351
8352 // For cases where the decoded length of s2 is greater
8353 // than the decoded length of s1, simply perform a normal
8354 // decode and XOR
8355 //
8356 if (data2.Length >= data1.Length)
8357 {
8358 for (int pos = 0 ; pos < data1.Length ; pos++ )
8359 data1[pos] ^= data2[pos];
8360
8361 return Convert.ToBase64String(data1);
8362 }
8363
8364 // Remove padding
8365 while (str1.EndsWith("="))
8366 str1 = str1.Substring(0, str1.Length - 1);
8367 while (str2.EndsWith("="))
8368 str2 = str2.Substring(0, str2.Length - 1);
8369
8370 byte[] d1 = new byte[str1.Length];
8371 byte[] d2 = new byte[str2.Length];
8372
8373 for (int i = 0 ; i < str1.Length ; i++)
8374 {
8375 int idx = b64.IndexOf(str1.Substring(i, 1));
8376 if (idx == -1)
8377 idx = 0;
8378 d1[i] = (byte)idx;
8379 }
8380
8381 for (int i = 0 ; i < str2.Length ; i++)
8382 {
8383 int idx = b64.IndexOf(str2.Substring(i, 1));
8384 if (idx == -1)
8385 idx = 0;
8386 d2[i] = (byte)idx;
8387 }
8388
8389 string output = String.Empty;
8390
8391 for (int pos = 0 ; pos < d1.Length ; pos++)
8392 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8393
8394 while (output.Length % 3 > 0)
8395 output += "=";
8396
8397 return output;
7706 } 8398 }
7707 8399
7708 public void llRemoteDataSetRegion() 8400 public void llRemoteDataSetRegion()
@@ -7826,13 +8518,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7826 public LSL_Integer llGetNumberOfPrims() 8518 public LSL_Integer llGetNumberOfPrims()
7827 { 8519 {
7828 m_host.AddScriptLPS(1); 8520 m_host.AddScriptLPS(1);
7829 int avatarCount = 0; 8521 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7830 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8522
7831 {
7832 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7833 avatarCount++;
7834 });
7835
7836 return m_host.ParentGroup.PrimCount + avatarCount; 8523 return m_host.ParentGroup.PrimCount + avatarCount;
7837 } 8524 }
7838 8525
@@ -7848,55 +8535,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7848 m_host.AddScriptLPS(1); 8535 m_host.AddScriptLPS(1);
7849 UUID objID = UUID.Zero; 8536 UUID objID = UUID.Zero;
7850 LSL_List result = new LSL_List(); 8537 LSL_List result = new LSL_List();
8538
8539 // If the ID is not valid, return null result
7851 if (!UUID.TryParse(obj, out objID)) 8540 if (!UUID.TryParse(obj, out objID))
7852 { 8541 {
7853 result.Add(new LSL_Vector()); 8542 result.Add(new LSL_Vector());
7854 result.Add(new LSL_Vector()); 8543 result.Add(new LSL_Vector());
7855 return result; 8544 return result;
7856 } 8545 }
8546
8547 // Check if this is an attached prim. If so, replace
8548 // the UUID with the avatar UUID and report it's bounding box
8549 SceneObjectPart part = World.GetSceneObjectPart(objID);
8550 if (part != null && part.ParentGroup.IsAttachment)
8551 objID = part.ParentGroup.AttachedAvatar;
8552
8553 // Find out if this is an avatar ID. If so, return it's box
7857 ScenePresence presence = World.GetScenePresence(objID); 8554 ScenePresence presence = World.GetScenePresence(objID);
7858 if (presence != null) 8555 if (presence != null)
7859 { 8556 {
7860 if (presence.ParentID == 0) // not sat on an object 8557 // As per LSL Wiki, there is no difference between sitting
8558 // and standing avatar since server 1.36
8559 LSL_Vector lower;
8560 LSL_Vector upper;
8561 if (presence.Animator.Animations.DefaultAnimation.AnimID
8562 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7861 { 8563 {
7862 LSL_Vector lower; 8564 // This is for ground sitting avatars
7863 LSL_Vector upper; 8565 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7864 if (presence.Animator.Animations.DefaultAnimation.AnimID 8566 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7865 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8567 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7866 {
7867 // This is for ground sitting avatars
7868 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7869 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7870 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7871 }
7872 else
7873 {
7874 // This is for standing/flying avatars
7875 float height = presence.Appearance.AvatarHeight / 2.0f;
7876 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7877 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7878 }
7879 result.Add(lower);
7880 result.Add(upper);
7881 return result;
7882 } 8568 }
7883 else 8569 else
7884 { 8570 {
7885 // sitting on an object so we need the bounding box of that 8571 // This is for standing/flying avatars
7886 // which should include the avatar so set the UUID to the 8572 float height = presence.Appearance.AvatarHeight / 2.0f;
7887 // UUID of the object the avatar is sat on and allow it to fall through 8573 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7888 // to processing an object 8574 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7889 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7890 objID = p.UUID;
7891 } 8575 }
8576
8577 // Adjust to the documented error offsets (see LSL Wiki)
8578 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8579 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8580
8581 if (lower.x > upper.x)
8582 lower.x = upper.x;
8583 if (lower.y > upper.y)
8584 lower.y = upper.y;
8585 if (lower.z > upper.z)
8586 lower.z = upper.z;
8587
8588 result.Add(lower);
8589 result.Add(upper);
8590 return result;
7892 } 8591 }
7893 SceneObjectPart part = World.GetSceneObjectPart(objID); 8592
8593 part = World.GetSceneObjectPart(objID);
7894 // Currently only works for single prims without a sitting avatar 8594 // Currently only works for single prims without a sitting avatar
7895 if (part != null) 8595 if (part != null)
7896 { 8596 {
7897 Vector3 halfSize = part.Scale / 2.0f; 8597 float minX;
7898 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8598 float maxX;
7899 LSL_Vector upper = new LSL_Vector(halfSize); 8599 float minY;
8600 float maxY;
8601 float minZ;
8602 float maxZ;
8603
8604 // This BBox is in sim coordinates, with the offset being
8605 // a contained point.
8606 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8607 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8608
8609 minX -= offsets[0].X;
8610 maxX -= offsets[0].X;
8611 minY -= offsets[0].Y;
8612 maxY -= offsets[0].Y;
8613 minZ -= offsets[0].Z;
8614 maxZ -= offsets[0].Z;
8615
8616 LSL_Vector lower;
8617 LSL_Vector upper;
8618
8619 // Adjust to the documented error offsets (see LSL Wiki)
8620 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8621 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8622
8623 if (lower.x > upper.x)
8624 lower.x = upper.x;
8625 if (lower.y > upper.y)
8626 lower.y = upper.y;
8627 if (lower.z > upper.z)
8628 lower.z = upper.z;
8629
7900 result.Add(lower); 8630 result.Add(lower);
7901 result.Add(upper); 8631 result.Add(upper);
7902 return result; 8632 return result;
@@ -7910,7 +8640,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7910 8640
7911 public LSL_Vector llGetGeometricCenter() 8641 public LSL_Vector llGetGeometricCenter()
7912 { 8642 {
7913 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8643 Vector3 tmp = m_host.GetGeometricCenter();
8644 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7914 } 8645 }
7915 8646
7916 public LSL_List llGetPrimitiveParams(LSL_List rules) 8647 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7938,24 +8669,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7938 { 8669 {
7939 m_host.AddScriptLPS(1); 8670 m_host.AddScriptLPS(1);
7940 8671
7941 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8672 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8673 // keep other options as before
7942 8674
8675 List<SceneObjectPart> parts;
8676 List<ScenePresence> avatars;
8677
7943 LSL_List res = new LSL_List(); 8678 LSL_List res = new LSL_List();
7944 LSL_List remaining = null; 8679 LSL_List remaining = null;
7945 8680
7946 foreach (SceneObjectPart part in parts) 8681 while (rules.Length > 0)
7947 {
7948 remaining = GetPrimParams(part, rules, ref res);
7949 }
7950
7951 while (remaining != null && remaining.Length > 2)
7952 { 8682 {
7953 linknumber = remaining.GetLSLIntegerItem(0);
7954 rules = remaining.GetSublist(1, -1);
7955 parts = GetLinkParts(linknumber); 8683 parts = GetLinkParts(linknumber);
8684 avatars = GetLinkAvatars(linknumber);
7956 8685
8686 remaining = null;
7957 foreach (SceneObjectPart part in parts) 8687 foreach (SceneObjectPart part in parts)
8688 {
7958 remaining = GetPrimParams(part, rules, ref res); 8689 remaining = GetPrimParams(part, rules, ref res);
8690 }
8691 foreach (ScenePresence avatar in avatars)
8692 {
8693 remaining = GetPrimParams(avatar, rules, ref res);
8694 }
8695
8696 if (remaining != null && remaining.Length > 0)
8697 {
8698 linknumber = remaining.GetLSLIntegerItem(0);
8699 rules = remaining.GetSublist(1, -1);
8700 }
7959 } 8701 }
7960 8702
7961 return res; 8703 return res;
@@ -8000,13 +8742,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8000 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8742 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8001 part.AbsolutePosition.Y, 8743 part.AbsolutePosition.Y,
8002 part.AbsolutePosition.Z); 8744 part.AbsolutePosition.Z);
8003 // For some reason, the part.AbsolutePosition.* values do not change if the
8004 // linkset is rotated; they always reflect the child prim's world position
8005 // as though the linkset is unrotated. This is incompatible behavior with SL's
8006 // implementation, so will break scripts imported from there (not to mention it
8007 // makes it more difficult to determine a child prim's actual inworld position).
8008 if (part.ParentID != 0)
8009 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8010 res.Add(v); 8745 res.Add(v);
8011 break; 8746 break;
8012 8747
@@ -8178,30 +8913,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8178 if (remain < 1) 8913 if (remain < 1)
8179 return null; 8914 return null;
8180 8915
8181 face=(int)rules.GetLSLIntegerItem(idx++); 8916 face = (int)rules.GetLSLIntegerItem(idx++);
8182 8917
8183 tex = part.Shape.Textures; 8918 tex = part.Shape.Textures;
8919 int shiny;
8184 if (face == ScriptBaseClass.ALL_SIDES) 8920 if (face == ScriptBaseClass.ALL_SIDES)
8185 { 8921 {
8186 for (face = 0; face < GetNumberOfSides(part); face++) 8922 for (face = 0; face < GetNumberOfSides(part); face++)
8187 { 8923 {
8188 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8924 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8189 // Convert Shininess to PRIM_SHINY_* 8925 if (shinyness == Shininess.High)
8190 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8926 {
8191 // PRIM_BUMP_* 8927 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8192 res.Add(new LSL_Integer((int)texface.Bump)); 8928 }
8929 else if (shinyness == Shininess.Medium)
8930 {
8931 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8932 }
8933 else if (shinyness == Shininess.Low)
8934 {
8935 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8936 }
8937 else
8938 {
8939 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8940 }
8941 res.Add(new LSL_Integer(shiny));
8942 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8193 } 8943 }
8194 } 8944 }
8195 else 8945 else
8196 { 8946 {
8197 if (face >= 0 && face < GetNumberOfSides(part)) 8947 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8948 if (shinyness == Shininess.High)
8198 { 8949 {
8199 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8950 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8200 // Convert Shininess to PRIM_SHINY_* 8951 }
8201 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8952 else if (shinyness == Shininess.Medium)
8202 // PRIM_BUMP_* 8953 {
8203 res.Add(new LSL_Integer((int)texface.Bump)); 8954 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8204 } 8955 }
8956 else if (shinyness == Shininess.Low)
8957 {
8958 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8959 }
8960 else
8961 {
8962 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8963 }
8964 res.Add(new LSL_Integer(shiny));
8965 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8205 } 8966 }
8206 break; 8967 break;
8207 8968
@@ -8209,24 +8970,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8209 if (remain < 1) 8970 if (remain < 1)
8210 return null; 8971 return null;
8211 8972
8212 face=(int)rules.GetLSLIntegerItem(idx++); 8973 face = (int)rules.GetLSLIntegerItem(idx++);
8213 8974
8214 tex = part.Shape.Textures; 8975 tex = part.Shape.Textures;
8976 int fullbright;
8215 if (face == ScriptBaseClass.ALL_SIDES) 8977 if (face == ScriptBaseClass.ALL_SIDES)
8216 { 8978 {
8217 for (face = 0; face < GetNumberOfSides(part); face++) 8979 for (face = 0; face < GetNumberOfSides(part); face++)
8218 { 8980 {
8219 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8981 if (tex.GetFace((uint)face).Fullbright == true)
8220 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8982 {
8983 fullbright = ScriptBaseClass.TRUE;
8984 }
8985 else
8986 {
8987 fullbright = ScriptBaseClass.FALSE;
8988 }
8989 res.Add(new LSL_Integer(fullbright));
8221 } 8990 }
8222 } 8991 }
8223 else 8992 else
8224 { 8993 {
8225 if (face >= 0 && face < GetNumberOfSides(part)) 8994 if (tex.GetFace((uint)face).Fullbright == true)
8226 { 8995 {
8227 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8996 fullbright = ScriptBaseClass.TRUE;
8228 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8229 } 8997 }
8998 else
8999 {
9000 fullbright = ScriptBaseClass.FALSE;
9001 }
9002 res.Add(new LSL_Integer(fullbright));
8230 } 9003 }
8231 break; 9004 break;
8232 9005
@@ -8248,27 +9021,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8248 break; 9021 break;
8249 9022
8250 case (int)ScriptBaseClass.PRIM_TEXGEN: 9023 case (int)ScriptBaseClass.PRIM_TEXGEN:
9024 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8251 if (remain < 1) 9025 if (remain < 1)
8252 return null; 9026 return null;
8253 9027
8254 face=(int)rules.GetLSLIntegerItem(idx++); 9028 face = (int)rules.GetLSLIntegerItem(idx++);
8255 9029
8256 tex = part.Shape.Textures; 9030 tex = part.Shape.Textures;
8257 if (face == ScriptBaseClass.ALL_SIDES) 9031 if (face == ScriptBaseClass.ALL_SIDES)
8258 { 9032 {
8259 for (face = 0; face < GetNumberOfSides(part); face++) 9033 for (face = 0; face < GetNumberOfSides(part); face++)
8260 { 9034 {
8261 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9035 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8262 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9036 {
8263 res.Add(new LSL_Integer((uint)texgen >> 1)); 9037 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9038 }
9039 else
9040 {
9041 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9042 }
8264 } 9043 }
8265 } 9044 }
8266 else 9045 else
8267 { 9046 {
8268 if (face >= 0 && face < GetNumberOfSides(part)) 9047 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8269 { 9048 {
8270 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9049 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8271 res.Add(new LSL_Integer((uint)texgen >> 1)); 9050 }
9051 else
9052 {
9053 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8272 } 9054 }
8273 } 9055 }
8274 break; 9056 break;
@@ -8292,24 +9074,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8292 if (remain < 1) 9074 if (remain < 1)
8293 return null; 9075 return null;
8294 9076
8295 face=(int)rules.GetLSLIntegerItem(idx++); 9077 face = (int)rules.GetLSLIntegerItem(idx++);
8296 9078
8297 tex = part.Shape.Textures; 9079 tex = part.Shape.Textures;
9080 float primglow;
8298 if (face == ScriptBaseClass.ALL_SIDES) 9081 if (face == ScriptBaseClass.ALL_SIDES)
8299 { 9082 {
8300 for (face = 0; face < GetNumberOfSides(part); face++) 9083 for (face = 0; face < GetNumberOfSides(part); face++)
8301 { 9084 {
8302 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9085 primglow = tex.GetFace((uint)face).Glow;
8303 res.Add(new LSL_Float(texface.Glow)); 9086 res.Add(new LSL_Float(primglow));
8304 } 9087 }
8305 } 9088 }
8306 else 9089 else
8307 { 9090 {
8308 if (face >= 0 && face < GetNumberOfSides(part)) 9091 primglow = tex.GetFace((uint)face).Glow;
8309 { 9092 res.Add(new LSL_Float(primglow));
8310 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8311 res.Add(new LSL_Float(texface.Glow));
8312 }
8313 } 9093 }
8314 break; 9094 break;
8315 9095
@@ -8321,15 +9101,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8321 textColor.B)); 9101 textColor.B));
8322 res.Add(new LSL_Float(textColor.A)); 9102 res.Add(new LSL_Float(textColor.A));
8323 break; 9103 break;
9104
8324 case (int)ScriptBaseClass.PRIM_NAME: 9105 case (int)ScriptBaseClass.PRIM_NAME:
8325 res.Add(new LSL_String(part.Name)); 9106 res.Add(new LSL_String(part.Name));
8326 break; 9107 break;
9108
8327 case (int)ScriptBaseClass.PRIM_DESC: 9109 case (int)ScriptBaseClass.PRIM_DESC:
8328 res.Add(new LSL_String(part.Description)); 9110 res.Add(new LSL_String(part.Description));
8329 break; 9111 break;
9112
8330 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9113 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8331 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9114 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8332 break; 9115 break;
9116
8333 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9117 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8334 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9118 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8335 break; 9119 break;
@@ -8940,8 +9724,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8940 // The function returns an ordered list 9724 // The function returns an ordered list
8941 // representing the tokens found in the supplied 9725 // representing the tokens found in the supplied
8942 // sources string. If two successive tokenizers 9726 // sources string. If two successive tokenizers
8943 // are encountered, then a NULL entry is added 9727 // are encountered, then a null-string entry is
8944 // to the list. 9728 // added to the list.
8945 // 9729 //
8946 // It is a precondition that the source and 9730 // It is a precondition that the source and
8947 // toekizer lisst are non-null. If they are null, 9731 // toekizer lisst are non-null. If they are null,
@@ -8949,7 +9733,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8949 // while their lengths are being determined. 9733 // while their lengths are being determined.
8950 // 9734 //
8951 // A small amount of working memoryis required 9735 // A small amount of working memoryis required
8952 // of approximately 8*#tokenizers. 9736 // of approximately 8*#tokenizers + 8*srcstrlen.
8953 // 9737 //
8954 // There are many ways in which this function 9738 // There are many ways in which this function
8955 // can be implemented, this implementation is 9739 // can be implemented, this implementation is
@@ -8965,155 +9749,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8965 // and eliminates redundant tokenizers as soon 9749 // and eliminates redundant tokenizers as soon
8966 // as is possible. 9750 // as is possible.
8967 // 9751 //
8968 // The implementation tries to avoid any copying 9752 // The implementation tries to minimize temporary
8969 // of arrays or other objects. 9753 // garbage generation.
8970 // </remarks> 9754 // </remarks>
8971 9755
8972 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9756 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8973 { 9757 {
8974 int beginning = 0; 9758 return ParseString2List(src, separators, spacers, true);
8975 int srclen = src.Length; 9759 }
8976 int seplen = separators.Length;
8977 object[] separray = separators.Data;
8978 int spclen = spacers.Length;
8979 object[] spcarray = spacers.Data;
8980 int mlen = seplen+spclen;
8981
8982 int[] offset = new int[mlen+1];
8983 bool[] active = new bool[mlen];
8984
8985 int best;
8986 int j;
8987
8988 // Initial capacity reduces resize cost
8989 9760
8990 LSL_List tokens = new LSL_List(); 9761 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9762 {
9763 int srclen = src.Length;
9764 int seplen = separators.Length;
9765 object[] separray = separators.Data;
9766 int spclen = spacers.Length;
9767 object[] spcarray = spacers.Data;
9768 int dellen = 0;
9769 string[] delarray = new string[seplen+spclen];
8991 9770
8992 // All entries are initially valid 9771 int outlen = 0;
9772 string[] outarray = new string[srclen*2+1];
8993 9773
8994 for (int i = 0; i < mlen; i++) 9774 int i, j;
8995 active[i] = true; 9775 string d;
8996 9776
8997 offset[mlen] = srclen; 9777 m_host.AddScriptLPS(1);
8998 9778
8999 while (beginning < srclen) 9779 /*
9780 * Convert separator and spacer lists to C# strings.
9781 * Also filter out null strings so we don't hang.
9782 */
9783 for (i = 0; i < seplen; i ++)
9000 { 9784 {
9785 d = separray[i].ToString();
9786 if (d.Length > 0)
9787 {
9788 delarray[dellen++] = d;
9789 }
9790 }
9791 seplen = dellen;
9001 9792
9002 best = mlen; // as bad as it gets 9793 for (i = 0; i < spclen; i ++)
9794 {
9795 d = spcarray[i].ToString();
9796 if (d.Length > 0)
9797 {
9798 delarray[dellen++] = d;
9799 }
9800 }
9003 9801
9004 // Scan for separators 9802 /*
9803 * Scan through source string from beginning to end.
9804 */
9805 for (i = 0;;)
9806 {
9005 9807
9006 for (j = 0; j < seplen; j++) 9808 /*
9809 * Find earliest delimeter in src starting at i (if any).
9810 */
9811 int earliestDel = -1;
9812 int earliestSrc = srclen;
9813 string earliestStr = null;
9814 for (j = 0; j < dellen; j ++)
9007 { 9815 {
9008 if (separray[j].ToString() == String.Empty) 9816 d = delarray[j];
9009 active[j] = false; 9817 if (d != null)
9010
9011 if (active[j])
9012 { 9818 {
9013 // scan all of the markers 9819 int index = src.IndexOf(d, i);
9014 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9820 if (index < 0)
9015 { 9821 {
9016 // not present at all 9822 delarray[j] = null; // delim nowhere in src, don't check it anymore
9017 active[j] = false;
9018 } 9823 }
9019 else 9824 else if (index < earliestSrc)
9020 { 9825 {
9021 // present and correct 9826 earliestSrc = index; // where delimeter starts in source string
9022 if (offset[j] < offset[best]) 9827 earliestDel = j; // where delimeter is in delarray[]
9023 { 9828 earliestStr = d; // the delimeter string from delarray[]
9024 // closest so far 9829 if (index == i) break; // can't do any better than found at beg of string
9025 best = j;
9026 if (offset[best] == beginning)
9027 break;
9028 }
9029 } 9830 }
9030 } 9831 }
9031 } 9832 }
9032 9833
9033 // Scan for spacers 9834 /*
9034 9835 * Output source string starting at i through start of earliest delimeter.
9035 if (offset[best] != beginning) 9836 */
9837 if (keepNulls || (earliestSrc > i))
9036 { 9838 {
9037 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9839 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9038 {
9039 if (spcarray[j-seplen].ToString() == String.Empty)
9040 active[j] = false;
9041
9042 if (active[j])
9043 {
9044 // scan all of the markers
9045 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9046 {
9047 // not present at all
9048 active[j] = false;
9049 }
9050 else
9051 {
9052 // present and correct
9053 if (offset[j] < offset[best])
9054 {
9055 // closest so far
9056 best = j;
9057 }
9058 }
9059 }
9060 }
9061 } 9840 }
9062 9841
9063 // This is the normal exit from the scanning loop 9842 /*
9843 * If no delimeter found at or after i, we're done scanning.
9844 */
9845 if (earliestDel < 0) break;
9064 9846
9065 if (best == mlen) 9847 /*
9848 * If delimeter was a spacer, output the spacer.
9849 */
9850 if (earliestDel >= seplen)
9066 { 9851 {
9067 // no markers were found on this pass 9852 outarray[outlen++] = earliestStr;
9068 // so we're pretty much done
9069 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9070 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9071 break;
9072 } 9853 }
9073 9854
9074 // Otherwise we just add the newly delimited token 9855 /*
9075 // and recalculate where the search should continue. 9856 * Look at rest of src string following delimeter.
9076 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9857 */
9077 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9858 i = earliestSrc + earliestStr.Length;
9078
9079 if (best < seplen)
9080 {
9081 beginning = offset[best] + (separray[best].ToString()).Length;
9082 }
9083 else
9084 {
9085 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9086 string str = spcarray[best - seplen].ToString();
9087 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9088 tokens.Add(new LSL_String(str));
9089 }
9090 } 9859 }
9091 9860
9092 // This an awkward an not very intuitive boundary case. If the 9861 /*
9093 // last substring is a tokenizer, then there is an implied trailing 9862 * Make up an exact-sized output array suitable for an LSL_List object.
9094 // null list entry. Hopefully the single comparison will not be too 9863 */
9095 // arduous. Alternatively the 'break' could be replced with a return 9864 object[] outlist = new object[outlen];
9096 // but that's shabby programming. 9865 for (i = 0; i < outlen; i ++)
9097
9098 if ((beginning == srclen) && (keepNulls))
9099 { 9866 {
9100 if (srclen != 0) 9867 outlist[i] = new LSL_String(outarray[i]);
9101 tokens.Add(new LSL_String(""));
9102 } 9868 }
9103 9869 return new LSL_List(outlist);
9104 return tokens;
9105 }
9106
9107 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9108 {
9109 m_host.AddScriptLPS(1);
9110 return this.ParseString(src, separators, spacers, false);
9111 }
9112
9113 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9114 {
9115 m_host.AddScriptLPS(1);
9116 return this.ParseString(src, separators, spacers, true);
9117 } 9870 }
9118 9871
9119 public LSL_Integer llGetObjectPermMask(int mask) 9872 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9208,6 +9961,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9208 case 4: 9961 case 4:
9209 return (int)item.NextPermissions; 9962 return (int)item.NextPermissions;
9210 } 9963 }
9964 m_host.TaskInventory.LockItemsForRead(false);
9211 9965
9212 return -1; 9966 return -1;
9213 } 9967 }
@@ -9398,9 +10152,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9398 { 10152 {
9399 try 10153 try
9400 { 10154 {
10155 /*
9401 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10156 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9402 if (obj != null) 10157 if (obj != null)
9403 return (double)obj.GetMass(); 10158 return (double)obj.GetMass();
10159 */
10160 // return total object mass
10161 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10162 if (obj != null)
10163 return obj.GetMass();
10164
9404 // the object is null so the key is for an avatar 10165 // the object is null so the key is for an avatar
9405 ScenePresence avatar = World.GetScenePresence(key); 10166 ScenePresence avatar = World.GetScenePresence(key);
9406 if (avatar != null) 10167 if (avatar != null)
@@ -9420,7 +10181,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9420 } 10181 }
9421 10182
9422 /// <summary> 10183 /// <summary>
9423 /// illListReplaceList removes the sub-list defined by the inclusive indices 10184 /// llListReplaceList removes the sub-list defined by the inclusive indices
9424 /// start and end and inserts the src list in its place. The inclusive 10185 /// start and end and inserts the src list in its place. The inclusive
9425 /// nature of the indices means that at least one element must be deleted 10186 /// nature of the indices means that at least one element must be deleted
9426 /// if the indices are within the bounds of the existing list. I.e. 2,2 10187 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9477,16 +10238,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9477 // based upon end. Note that if end exceeds the upper 10238 // based upon end. Note that if end exceeds the upper
9478 // bound in this case, the entire destination list 10239 // bound in this case, the entire destination list
9479 // is removed. 10240 // is removed.
9480 else 10241 else if (start == 0)
9481 { 10242 {
9482 if (end + 1 < dest.Length) 10243 if (end + 1 < dest.Length)
9483 {
9484 return src + dest.GetSublist(end + 1, -1); 10244 return src + dest.GetSublist(end + 1, -1);
9485 }
9486 else 10245 else
9487 {
9488 return src; 10246 return src;
9489 } 10247 }
10248 else // Start < 0
10249 {
10250 if (end + 1 < dest.Length)
10251 return dest.GetSublist(end + 1, -1);
10252 else
10253 return new LSL_List();
9490 } 10254 }
9491 } 10255 }
9492 // Finally, if start > end, we strip away a prefix and 10256 // Finally, if start > end, we strip away a prefix and
@@ -9537,17 +10301,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9537 int width = 0; 10301 int width = 0;
9538 int height = 0; 10302 int height = 0;
9539 10303
9540 ParcelMediaCommandEnum? commandToSend = null; 10304 uint commandToSend = 0;
9541 float time = 0.0f; // default is from start 10305 float time = 0.0f; // default is from start
9542 10306
9543 ScenePresence presence = null; 10307 ScenePresence presence = null;
9544 10308
9545 for (int i = 0; i < commandList.Data.Length; i++) 10309 for (int i = 0; i < commandList.Data.Length; i++)
9546 { 10310 {
9547 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10311 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9548 switch (command) 10312 switch (command)
9549 { 10313 {
9550 case ParcelMediaCommandEnum.Agent: 10314 case (uint)ParcelMediaCommandEnum.Agent:
9551 // we send only to one agent 10315 // we send only to one agent
9552 if ((i + 1) < commandList.Length) 10316 if ((i + 1) < commandList.Length)
9553 { 10317 {
@@ -9564,25 +10328,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9564 } 10328 }
9565 break; 10329 break;
9566 10330
9567 case ParcelMediaCommandEnum.Loop: 10331 case (uint)ParcelMediaCommandEnum.Loop:
9568 loop = 1; 10332 loop = 1;
9569 commandToSend = command; 10333 commandToSend = command;
9570 update = true; //need to send the media update packet to set looping 10334 update = true; //need to send the media update packet to set looping
9571 break; 10335 break;
9572 10336
9573 case ParcelMediaCommandEnum.Play: 10337 case (uint)ParcelMediaCommandEnum.Play:
9574 loop = 0; 10338 loop = 0;
9575 commandToSend = command; 10339 commandToSend = command;
9576 update = true; //need to send the media update packet to make sure it doesn't loop 10340 update = true; //need to send the media update packet to make sure it doesn't loop
9577 break; 10341 break;
9578 10342
9579 case ParcelMediaCommandEnum.Pause: 10343 case (uint)ParcelMediaCommandEnum.Pause:
9580 case ParcelMediaCommandEnum.Stop: 10344 case (uint)ParcelMediaCommandEnum.Stop:
9581 case ParcelMediaCommandEnum.Unload: 10345 case (uint)ParcelMediaCommandEnum.Unload:
9582 commandToSend = command; 10346 commandToSend = command;
9583 break; 10347 break;
9584 10348
9585 case ParcelMediaCommandEnum.Url: 10349 case (uint)ParcelMediaCommandEnum.Url:
9586 if ((i + 1) < commandList.Length) 10350 if ((i + 1) < commandList.Length)
9587 { 10351 {
9588 if (commandList.Data[i + 1] is LSL_String) 10352 if (commandList.Data[i + 1] is LSL_String)
@@ -9595,7 +10359,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9595 } 10359 }
9596 break; 10360 break;
9597 10361
9598 case ParcelMediaCommandEnum.Texture: 10362 case (uint)ParcelMediaCommandEnum.Texture:
9599 if ((i + 1) < commandList.Length) 10363 if ((i + 1) < commandList.Length)
9600 { 10364 {
9601 if (commandList.Data[i + 1] is LSL_String) 10365 if (commandList.Data[i + 1] is LSL_String)
@@ -9608,7 +10372,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9608 } 10372 }
9609 break; 10373 break;
9610 10374
9611 case ParcelMediaCommandEnum.Time: 10375 case (uint)ParcelMediaCommandEnum.Time:
9612 if ((i + 1) < commandList.Length) 10376 if ((i + 1) < commandList.Length)
9613 { 10377 {
9614 if (commandList.Data[i + 1] is LSL_Float) 10378 if (commandList.Data[i + 1] is LSL_Float)
@@ -9620,7 +10384,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9620 } 10384 }
9621 break; 10385 break;
9622 10386
9623 case ParcelMediaCommandEnum.AutoAlign: 10387 case (uint)ParcelMediaCommandEnum.AutoAlign:
9624 if ((i + 1) < commandList.Length) 10388 if ((i + 1) < commandList.Length)
9625 { 10389 {
9626 if (commandList.Data[i + 1] is LSL_Integer) 10390 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9634,7 +10398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9634 } 10398 }
9635 break; 10399 break;
9636 10400
9637 case ParcelMediaCommandEnum.Type: 10401 case (uint)ParcelMediaCommandEnum.Type:
9638 if ((i + 1) < commandList.Length) 10402 if ((i + 1) < commandList.Length)
9639 { 10403 {
9640 if (commandList.Data[i + 1] is LSL_String) 10404 if (commandList.Data[i + 1] is LSL_String)
@@ -9647,7 +10411,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9647 } 10411 }
9648 break; 10412 break;
9649 10413
9650 case ParcelMediaCommandEnum.Desc: 10414 case (uint)ParcelMediaCommandEnum.Desc:
9651 if ((i + 1) < commandList.Length) 10415 if ((i + 1) < commandList.Length)
9652 { 10416 {
9653 if (commandList.Data[i + 1] is LSL_String) 10417 if (commandList.Data[i + 1] is LSL_String)
@@ -9660,7 +10424,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9660 } 10424 }
9661 break; 10425 break;
9662 10426
9663 case ParcelMediaCommandEnum.Size: 10427 case (uint)ParcelMediaCommandEnum.Size:
9664 if ((i + 2) < commandList.Length) 10428 if ((i + 2) < commandList.Length)
9665 { 10429 {
9666 if (commandList.Data[i + 1] is LSL_Integer) 10430 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9730,7 +10494,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9730 } 10494 }
9731 } 10495 }
9732 10496
9733 if (commandToSend != null) 10497 if (commandToSend != 0)
9734 { 10498 {
9735 // the commandList contained a start/stop/... command, too 10499 // the commandList contained a start/stop/... command, too
9736 if (presence == null) 10500 if (presence == null)
@@ -9767,7 +10531,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9767 10531
9768 if (aList.Data[i] != null) 10532 if (aList.Data[i] != null)
9769 { 10533 {
9770 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10534 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9771 { 10535 {
9772 case ParcelMediaCommandEnum.Url: 10536 case ParcelMediaCommandEnum.Url:
9773 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10537 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9824,15 +10588,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9824 10588
9825 if (quick_pay_buttons.Data.Length < 4) 10589 if (quick_pay_buttons.Data.Length < 4)
9826 { 10590 {
9827 LSLError("List must have at least 4 elements"); 10591 int x;
9828 return; 10592 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10593 {
10594 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10595 }
9829 } 10596 }
9830 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10597 int[] nPrice = new int[5];
9831 10598 nPrice[0] = price;
9832 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10599 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9833 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10600 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9834 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10601 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9835 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10602 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10603 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9836 m_host.ParentGroup.HasGroupChanged = true; 10604 m_host.ParentGroup.HasGroupChanged = true;
9837 } 10605 }
9838 10606
@@ -9849,7 +10617,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9849 return new LSL_Vector(); 10617 return new LSL_Vector();
9850 } 10618 }
9851 10619
9852 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10620// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10621 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9853 if (presence != null) 10622 if (presence != null)
9854 { 10623 {
9855 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10624 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9871,7 +10640,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9871 return new LSL_Rotation(); 10640 return new LSL_Rotation();
9872 } 10641 }
9873 10642
9874 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10643// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10644 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9875 if (presence != null) 10645 if (presence != null)
9876 { 10646 {
9877 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10647 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9931,14 +10701,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9931 { 10701 {
9932 m_host.AddScriptLPS(1); 10702 m_host.AddScriptLPS(1);
9933 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10703 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9934 if (detectedParams == null) return; // only works on the first detected avatar 10704 if (detectedParams == null)
9935 10705 {
10706 if (m_host.ParentGroup.IsAttachment == true)
10707 {
10708 detectedParams = new DetectParams();
10709 detectedParams.Key = m_host.OwnerID;
10710 }
10711 else
10712 {
10713 return;
10714 }
10715 }
10716
9936 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10717 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9937 if (avatar != null) 10718 if (avatar != null)
9938 { 10719 {
9939 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10720 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9940 simname, pos, lookAt); 10721 simname, pos, lookAt);
9941 } 10722 }
10723
9942 ScriptSleep(1000); 10724 ScriptSleep(1000);
9943 } 10725 }
9944 10726
@@ -10062,12 +10844,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10062 10844
10063 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10845 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10064 object[] data = rules.Data; 10846 object[] data = rules.Data;
10065 for (int i = 0; i < data.Length; ++i) { 10847 for (int i = 0; i < data.Length; ++i)
10848 {
10066 int type = Convert.ToInt32(data[i++].ToString()); 10849 int type = Convert.ToInt32(data[i++].ToString());
10067 if (i >= data.Length) break; // odd number of entries => ignore the last 10850 if (i >= data.Length) break; // odd number of entries => ignore the last
10068 10851
10069 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10852 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10070 switch (type) { 10853 switch (type)
10854 {
10071 case ScriptBaseClass.CAMERA_FOCUS: 10855 case ScriptBaseClass.CAMERA_FOCUS:
10072 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10856 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10073 case ScriptBaseClass.CAMERA_POSITION: 10857 case ScriptBaseClass.CAMERA_POSITION:
@@ -10172,19 +10956,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10172 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10956 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10173 { 10957 {
10174 m_host.AddScriptLPS(1); 10958 m_host.AddScriptLPS(1);
10175 string ret = String.Empty; 10959
10176 string src1 = llBase64ToString(str1); 10960 if (str1 == String.Empty)
10177 string src2 = llBase64ToString(str2); 10961 return String.Empty;
10178 int c = 0; 10962 if (str2 == String.Empty)
10179 for (int i = 0; i < src1.Length; i++) 10963 return str1;
10964
10965 int len = str2.Length;
10966 if ((len % 4) != 0) // LL is EVIL!!!!
10180 { 10967 {
10181 ret += (char) (src1[i] ^ src2[c]); 10968 while (str2.EndsWith("="))
10969 str2 = str2.Substring(0, str2.Length - 1);
10182 10970
10183 c++; 10971 len = str2.Length;
10184 if (c >= src2.Length) 10972 int mod = len % 4;
10185 c = 0; 10973
10974 if (mod == 1)
10975 str2 = str2.Substring(0, str2.Length - 1);
10976 else if (mod == 2)
10977 str2 += "==";
10978 else if (mod == 3)
10979 str2 += "=";
10186 } 10980 }
10187 return llStringToBase64(ret); 10981
10982 byte[] data1;
10983 byte[] data2;
10984 try
10985 {
10986 data1 = Convert.FromBase64String(str1);
10987 data2 = Convert.FromBase64String(str2);
10988 }
10989 catch (Exception)
10990 {
10991 return new LSL_String(String.Empty);
10992 }
10993
10994 byte[] d2 = new Byte[data1.Length];
10995 int pos = 0;
10996
10997 if (data1.Length <= data2.Length)
10998 {
10999 Array.Copy(data2, 0, d2, 0, data1.Length);
11000 }
11001 else
11002 {
11003 while (pos < data1.Length)
11004 {
11005 len = data1.Length - pos;
11006 if (len > data2.Length)
11007 len = data2.Length;
11008
11009 Array.Copy(data2, 0, d2, pos, len);
11010 pos += len;
11011 }
11012 }
11013
11014 for (pos = 0 ; pos < data1.Length ; pos++ )
11015 data1[pos] ^= d2[pos];
11016
11017 return Convert.ToBase64String(data1);
10188 } 11018 }
10189 11019
10190 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11020 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10237,16 +11067,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10237 if (userAgent != null) 11067 if (userAgent != null)
10238 httpHeaders["User-Agent"] = userAgent; 11068 httpHeaders["User-Agent"] = userAgent;
10239 11069
11070 // See if the URL contains any header hacks
11071 string[] urlParts = url.Split(new char[] {'\n'});
11072 if (urlParts.Length > 1)
11073 {
11074 // Iterate the passed headers and parse them
11075 for (int i = 1 ; i < urlParts.Length ; i++ )
11076 {
11077 // The rest of those would be added to the body in SL.
11078 // Let's not do that.
11079 if (urlParts[i] == String.Empty)
11080 break;
11081
11082 // See if this could be a valid header
11083 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11084 if (headerParts.Length != 2)
11085 continue;
11086
11087 string headerName = headerParts[0].Trim();
11088 string headerValue = headerParts[1].Trim();
11089
11090 // Filter out headers that could be used to abuse
11091 // another system or cloak the request
11092 if (headerName.ToLower() == "x-secondlife-shard" ||
11093 headerName.ToLower() == "x-secondlife-object-name" ||
11094 headerName.ToLower() == "x-secondlife-object-key" ||
11095 headerName.ToLower() == "x-secondlife-region" ||
11096 headerName.ToLower() == "x-secondlife-local-position" ||
11097 headerName.ToLower() == "x-secondlife-local-velocity" ||
11098 headerName.ToLower() == "x-secondlife-local-rotation" ||
11099 headerName.ToLower() == "x-secondlife-owner-name" ||
11100 headerName.ToLower() == "x-secondlife-owner-key" ||
11101 headerName.ToLower() == "connection" ||
11102 headerName.ToLower() == "content-length" ||
11103 headerName.ToLower() == "from" ||
11104 headerName.ToLower() == "host" ||
11105 headerName.ToLower() == "proxy-authorization" ||
11106 headerName.ToLower() == "referer" ||
11107 headerName.ToLower() == "trailer" ||
11108 headerName.ToLower() == "transfer-encoding" ||
11109 headerName.ToLower() == "via" ||
11110 headerName.ToLower() == "authorization")
11111 continue;
11112
11113 httpHeaders[headerName] = headerValue;
11114 }
11115
11116 // Finally, strip any protocol specifier from the URL
11117 url = urlParts[0].Trim();
11118 int idx = url.IndexOf(" HTTP/");
11119 if (idx != -1)
11120 url = url.Substring(0, idx);
11121 }
11122
10240 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11123 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10241 Regex r = new Regex(authregex); 11124 Regex r = new Regex(authregex);
10242 int[] gnums = r.GetGroupNumbers(); 11125 int[] gnums = r.GetGroupNumbers();
10243 Match m = r.Match(url); 11126 Match m = r.Match(url);
10244 if (m.Success) { 11127 if (m.Success)
10245 for (int i = 1; i < gnums.Length; i++) { 11128 {
11129 for (int i = 1; i < gnums.Length; i++)
11130 {
10246 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11131 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10247 //CaptureCollection cc = g.Captures; 11132 //CaptureCollection cc = g.Captures;
10248 } 11133 }
10249 if (m.Groups.Count == 5) { 11134 if (m.Groups.Count == 5)
11135 {
10250 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11136 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10251 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11137 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10252 } 11138 }
@@ -10449,6 +11335,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10449 11335
10450 LSL_List ret = new LSL_List(); 11336 LSL_List ret = new LSL_List();
10451 UUID key = new UUID(); 11337 UUID key = new UUID();
11338
11339
10452 if (UUID.TryParse(id, out key)) 11340 if (UUID.TryParse(id, out key))
10453 { 11341 {
10454 ScenePresence av = World.GetScenePresence(key); 11342 ScenePresence av = World.GetScenePresence(key);
@@ -10466,13 +11354,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10466 ret.Add(new LSL_String("")); 11354 ret.Add(new LSL_String(""));
10467 break; 11355 break;
10468 case ScriptBaseClass.OBJECT_POS: 11356 case ScriptBaseClass.OBJECT_POS:
10469 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11357 Vector3 avpos;
11358
11359 if (av.ParentID != 0 && av.ParentPart != null)
11360 {
11361 avpos = av.OffsetPosition;
11362
11363 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11364 avpos -= sitOffset;
11365
11366 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11367 }
11368 else
11369 avpos = av.AbsolutePosition;
11370
11371 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10470 break; 11372 break;
10471 case ScriptBaseClass.OBJECT_ROT: 11373 case ScriptBaseClass.OBJECT_ROT:
10472 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11374 Quaternion avrot = av.Rotation;
11375 if (av.ParentID != 0 && av.ParentPart != null)
11376 {
11377 avrot = av.ParentPart.GetWorldRotation() * avrot;
11378 }
11379 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10473 break; 11380 break;
10474 case ScriptBaseClass.OBJECT_VELOCITY: 11381 case ScriptBaseClass.OBJECT_VELOCITY:
10475 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11382 Vector3 avvel = av.Velocity;
11383 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10476 break; 11384 break;
10477 case ScriptBaseClass.OBJECT_OWNER: 11385 case ScriptBaseClass.OBJECT_OWNER:
10478 ret.Add(new LSL_String(id)); 11386 ret.Add(new LSL_String(id));
@@ -10528,11 +11436,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10528 case ScriptBaseClass.OBJECT_NAME: 11436 case ScriptBaseClass.OBJECT_NAME:
10529 ret.Add(new LSL_String(obj.Name)); 11437 ret.Add(new LSL_String(obj.Name));
10530 break; 11438 break;
10531 case ScriptBaseClass.OBJECT_DESC: 11439 case ScriptBaseClass.OBJECT_DESC:
10532 ret.Add(new LSL_String(obj.Description)); 11440 ret.Add(new LSL_String(obj.Description));
10533 break; 11441 break;
10534 case ScriptBaseClass.OBJECT_POS: 11442 case ScriptBaseClass.OBJECT_POS:
10535 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11443 Vector3 opos = obj.AbsolutePosition;
11444 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10536 break; 11445 break;
10537 case ScriptBaseClass.OBJECT_ROT: 11446 case ScriptBaseClass.OBJECT_ROT:
10538 { 11447 {
@@ -10582,9 +11491,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10582 // The value returned in SL for normal prims is prim count 11491 // The value returned in SL for normal prims is prim count
10583 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11492 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10584 break; 11493 break;
10585 // The following 3 costs I have intentionaly coded to return zero. They are part of 11494
10586 // "Land Impact" calculations. These calculations are probably not applicable 11495 // costs below may need to be diferent for root parts, need to check
10587 // to OpenSim and are not yet complete in SL
10588 case ScriptBaseClass.OBJECT_SERVER_COST: 11496 case ScriptBaseClass.OBJECT_SERVER_COST:
10589 // The linden calculation is here 11497 // The linden calculation is here
10590 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11498 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10592,16 +11500,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10592 ret.Add(new LSL_Float(0)); 11500 ret.Add(new LSL_Float(0));
10593 break; 11501 break;
10594 case ScriptBaseClass.OBJECT_STREAMING_COST: 11502 case ScriptBaseClass.OBJECT_STREAMING_COST:
10595 // The linden calculation is here 11503 // The value returned in SL for normal prims is prim count * 0.06
10596 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11504 ret.Add(new LSL_Float(obj.StreamingCost));
10597 // The value returned in SL for normal prims looks like the prim count * 0.06
10598 ret.Add(new LSL_Float(0));
10599 break; 11505 break;
10600 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11506 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10601 // The linden calculation is here 11507 // The value returned in SL for normal prims is prim count
10602 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11508 ret.Add(new LSL_Float(obj.PhysicsCost));
10603 // The value returned in SL for normal prims looks like the prim count
10604 ret.Add(new LSL_Float(0));
10605 break; 11509 break;
10606 default: 11510 default:
10607 // Invalid or unhandled constant. 11511 // Invalid or unhandled constant.
@@ -10812,15 +11716,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10812 return result; 11716 return result;
10813 } 11717 }
10814 11718
10815 public void print(string str) 11719 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10816 { 11720 {
10817 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11721 List<SceneObjectPart> parts = GetLinkParts(link);
10818 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11722 if (parts.Count < 1)
10819 if (ossl != null) 11723 return 0;
10820 { 11724
10821 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11725 return GetNumberOfSides(parts[0]);
10822 m_log.Info("LSL print():" + str);
10823 }
10824 } 11726 }
10825 11727
10826 private string Name2Username(string name) 11728 private string Name2Username(string name)
@@ -10865,7 +11767,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10865 11767
10866 return rq.ToString(); 11768 return rq.ToString();
10867 } 11769 }
10868 11770/*
11771 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11772 {
11773 m_SayShoutCount = 0;
11774 }
11775*/
10869 private struct Tri 11776 private struct Tri
10870 { 11777 {
10871 public Vector3 p1; 11778 public Vector3 p1;
@@ -11005,9 +11912,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11005 11912
11006 ContactResult result = new ContactResult (); 11913 ContactResult result = new ContactResult ();
11007 result.ConsumerID = group.LocalId; 11914 result.ConsumerID = group.LocalId;
11008 result.Depth = intersection.distance; 11915// result.Depth = intersection.distance;
11009 result.Normal = intersection.normal; 11916 result.Normal = intersection.normal;
11010 result.Pos = intersection.ipoint; 11917 result.Pos = intersection.ipoint;
11918 result.Depth = Vector3.Mag(rayStart - result.Pos);
11011 11919
11012 contacts.Add(result); 11920 contacts.Add(result);
11013 }); 11921 });
@@ -11140,6 +12048,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11140 12048
11141 return contacts[0]; 12049 return contacts[0];
11142 } 12050 }
12051/*
12052 // not done:
12053 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12054 {
12055 ContactResult[] contacts = null;
12056 World.ForEachSOG(delegate(SceneObjectGroup group)
12057 {
12058 if (m_host.ParentGroup == group)
12059 return;
12060
12061 if (group.IsAttachment)
12062 return;
12063
12064 if(group.RootPart.PhysActor != null)
12065 return;
12066
12067 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12068 });
12069 return contacts;
12070 }
12071*/
11143 12072
11144 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12073 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11145 { 12074 {
@@ -11181,32 +12110,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11181 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12110 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11182 12111
11183 12112
11184 if (checkTerrain) 12113 if (World.SuportsRayCastFiltered())
11185 { 12114 {
11186 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12115 if (dist == 0)
11187 if (groundContact != null) 12116 return list;
11188 results.Add((ContactResult)groundContact);
11189 }
11190 12117
11191 if (checkAgents) 12118 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11192 { 12119 if (checkTerrain)
11193 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12120 rayfilter |= RayFilterFlags.land;
11194 foreach (ContactResult r in agentHits) 12121// if (checkAgents)
11195 results.Add(r); 12122// rayfilter |= RayFilterFlags.agent;
11196 } 12123 if (checkPhysical)
12124 rayfilter |= RayFilterFlags.physical;
12125 if (checkNonPhysical)
12126 rayfilter |= RayFilterFlags.nonphysical;
12127 if (detectPhantom)
12128 rayfilter |= RayFilterFlags.LSLPhanton;
12129
12130 Vector3 direction = dir * ( 1/dist);
12131
12132 if(rayfilter == 0)
12133 {
12134 list.Add(new LSL_Integer(0));
12135 return list;
12136 }
12137
12138 // get some more contacts to sort ???
12139 int physcount = 4 * count;
12140 if (physcount > 20)
12141 physcount = 20;
12142
12143 object physresults;
12144 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12145
12146 if (physresults == null)
12147 {
12148 list.Add(new LSL_Integer(-3)); // timeout error
12149 return list;
12150 }
12151
12152 results = (List<ContactResult>)physresults;
12153
12154 // for now physics doesn't detect sitted avatars so do it outside physics
12155 if (checkAgents)
12156 {
12157 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12158 foreach (ContactResult r in agentHits)
12159 results.Add(r);
12160 }
11197 12161
11198 if (checkPhysical || checkNonPhysical || detectPhantom) 12162 // TODO: Replace this with a better solution. ObjectIntersection can only
12163 // detect nonphysical phantoms. They are detected by virtue of being
12164 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12165 // physicsl phantoms as done by the physics scene
12166 // We don't want anything else but phantoms here.
12167 if (detectPhantom)
12168 {
12169 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12170 foreach (ContactResult r in objectHits)
12171 results.Add(r);
12172 }
12173 }
12174 else
11199 { 12175 {
11200 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12176 if (checkTerrain)
11201 foreach (ContactResult r in objectHits) 12177 {
11202 results.Add(r); 12178 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12179 if (groundContact != null)
12180 results.Add((ContactResult)groundContact);
12181 }
12182
12183 if (checkAgents)
12184 {
12185 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12186 foreach (ContactResult r in agentHits)
12187 results.Add(r);
12188 }
12189
12190 if (checkPhysical || checkNonPhysical || detectPhantom)
12191 {
12192 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12193 foreach (ContactResult r in objectHits)
12194 results.Add(r);
12195 }
11203 } 12196 }
11204 12197
11205 results.Sort(delegate(ContactResult a, ContactResult b) 12198 results.Sort(delegate(ContactResult a, ContactResult b)
11206 { 12199 {
11207 return a.Depth.CompareTo(b.Depth); 12200 return a.Depth.CompareTo(b.Depth);
11208 }); 12201 });
11209 12202
11210 int values = 0; 12203 int values = 0;
11211 SceneObjectGroup thisgrp = m_host.ParentGroup; 12204 SceneObjectGroup thisgrp = m_host.ParentGroup;
11212 12205
@@ -11299,7 +12292,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11299 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12292 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11300 if (!isAccount) return 0; 12293 if (!isAccount) return 0;
11301 if (estate.HasAccess(id)) return 1; 12294 if (estate.HasAccess(id)) return 1;
11302 if (estate.IsBanned(id)) 12295 if (estate.IsBanned(id, World.GetUserFlags(id)))
11303 estate.RemoveBan(id); 12296 estate.RemoveBan(id);
11304 estate.AddEstateUser(id); 12297 estate.AddEstateUser(id);
11305 break; 12298 break;
@@ -11318,14 +12311,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11318 break; 12311 break;
11319 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12312 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11320 if (!isAccount) return 0; 12313 if (!isAccount) return 0;
11321 if (estate.IsBanned(id)) return 1; 12314 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11322 EstateBan ban = new EstateBan(); 12315 EstateBan ban = new EstateBan();
11323 ban.EstateID = estate.EstateID; 12316 ban.EstateID = estate.EstateID;
11324 ban.BannedUserID = id; 12317 ban.BannedUserID = id;
11325 estate.AddBan(ban); 12318 estate.AddBan(ban);
11326 break; 12319 break;
11327 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12320 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11328 if (!isAccount || !estate.IsBanned(id)) return 0; 12321 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11329 estate.RemoveBan(id); 12322 estate.RemoveBan(id);
11330 break; 12323 break;
11331 default: return 0; 12324 default: return 0;
@@ -11354,7 +12347,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11354 return 16384; 12347 return 16384;
11355 } 12348 }
11356 12349
11357 public LSL_Integer llGetUsedMemory() 12350 public virtual LSL_Integer llGetUsedMemory()
11358 { 12351 {
11359 m_host.AddScriptLPS(1); 12352 m_host.AddScriptLPS(1);
11360 // The value returned for LSO scripts in SL 12353 // The value returned for LSO scripts in SL
@@ -11382,22 +12375,731 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11382 public void llSetSoundQueueing(int queue) 12375 public void llSetSoundQueueing(int queue)
11383 { 12376 {
11384 m_host.AddScriptLPS(1); 12377 m_host.AddScriptLPS(1);
11385 NotImplemented("llSetSoundQueueing");
11386 } 12378 }
11387 12379
11388 public void llCollisionSprite(string impact_sprite) 12380 public void llCollisionSprite(string impact_sprite)
11389 { 12381 {
11390 m_host.AddScriptLPS(1); 12382 m_host.AddScriptLPS(1);
11391 NotImplemented("llCollisionSprite"); 12383 // Viewer 2.0 broke this and it's likely LL has no intention
12384 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11392 } 12385 }
11393 12386
11394 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12387 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11395 { 12388 {
11396 m_host.AddScriptLPS(1); 12389 m_host.AddScriptLPS(1);
11397 NotImplemented("llGodLikeRezObject"); 12390
12391 if (!World.Permissions.IsGod(m_host.OwnerID))
12392 NotImplemented("llGodLikeRezObject");
12393
12394 AssetBase rezAsset = World.AssetService.Get(inventory);
12395 if (rezAsset == null)
12396 {
12397 llSay(0, "Asset not found");
12398 return;
12399 }
12400
12401 SceneObjectGroup group = null;
12402
12403 try
12404 {
12405 string xmlData = Utils.BytesToString(rezAsset.Data);
12406 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12407 }
12408 catch
12409 {
12410 llSay(0, "Asset not found");
12411 return;
12412 }
12413
12414 if (group == null)
12415 {
12416 llSay(0, "Asset not found");
12417 return;
12418 }
12419
12420 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12421 group.RootPart.AttachOffset = group.AbsolutePosition;
12422
12423 group.ResetIDs();
12424
12425 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12426 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12427 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12428 group.ScheduleGroupForFullUpdate();
12429
12430 // objects rezzed with this method are die_at_edge by default.
12431 group.RootPart.SetDieAtEdge(true);
12432
12433 group.ResumeScripts();
12434
12435 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12436 "object_rez", new Object[] {
12437 new LSL_String(
12438 group.RootPart.UUID.ToString()) },
12439 new DetectParams[0]));
12440 }
12441
12442 public LSL_String llTransferLindenDollars(string destination, int amount)
12443 {
12444 UUID txn = UUID.Random();
12445
12446 Util.FireAndForget(delegate(object x)
12447 {
12448 int replycode = 0;
12449 string replydata = destination + "," + amount.ToString();
12450
12451 try
12452 {
12453 TaskInventoryItem item = m_item;
12454 if (item == null)
12455 {
12456 replydata = "SERVICE_ERROR";
12457 return;
12458 }
12459
12460 m_host.AddScriptLPS(1);
12461
12462 if (item.PermsGranter == UUID.Zero)
12463 {
12464 replydata = "MISSING_PERMISSION_DEBIT";
12465 return;
12466 }
12467
12468 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12469 {
12470 replydata = "MISSING_PERMISSION_DEBIT";
12471 return;
12472 }
12473
12474 UUID toID = new UUID();
12475
12476 if (!UUID.TryParse(destination, out toID))
12477 {
12478 replydata = "INVALID_AGENT";
12479 return;
12480 }
12481
12482 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12483
12484 if (money == null)
12485 {
12486 replydata = "TRANSFERS_DISABLED";
12487 return;
12488 }
12489
12490 bool result = money.ObjectGiveMoney(
12491 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12492
12493 if (result)
12494 {
12495 replycode = 1;
12496 return;
12497 }
12498
12499 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12500 }
12501 finally
12502 {
12503 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12504 "transaction_result", new Object[] {
12505 new LSL_String(txn.ToString()),
12506 new LSL_Integer(replycode),
12507 new LSL_String(replydata) },
12508 new DetectParams[0]));
12509 }
12510 });
12511
12512 return txn.ToString();
11398 } 12513 }
11399 12514
11400 #endregion 12515 #endregion
12516
12517 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12518 {
12519 SceneObjectGroup group = m_host.ParentGroup;
12520
12521 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12522 return;
12523 if (group.IsAttachment)
12524 return;
12525
12526 if (frames.Data.Length > 0) // We are getting a new motion
12527 {
12528 if (group.RootPart.KeyframeMotion != null)
12529 group.RootPart.KeyframeMotion.Delete();
12530 group.RootPart.KeyframeMotion = null;
12531
12532 int idx = 0;
12533
12534 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12535 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12536
12537 while (idx < options.Data.Length)
12538 {
12539 int option = (int)options.GetLSLIntegerItem(idx++);
12540 int remain = options.Data.Length - idx;
12541
12542 switch (option)
12543 {
12544 case ScriptBaseClass.KFM_MODE:
12545 if (remain < 1)
12546 break;
12547 int modeval = (int)options.GetLSLIntegerItem(idx++);
12548 switch(modeval)
12549 {
12550 case ScriptBaseClass.KFM_FORWARD:
12551 mode = KeyframeMotion.PlayMode.Forward;
12552 break;
12553 case ScriptBaseClass.KFM_REVERSE:
12554 mode = KeyframeMotion.PlayMode.Reverse;
12555 break;
12556 case ScriptBaseClass.KFM_LOOP:
12557 mode = KeyframeMotion.PlayMode.Loop;
12558 break;
12559 case ScriptBaseClass.KFM_PING_PONG:
12560 mode = KeyframeMotion.PlayMode.PingPong;
12561 break;
12562 }
12563 break;
12564 case ScriptBaseClass.KFM_DATA:
12565 if (remain < 1)
12566 break;
12567 int dataval = (int)options.GetLSLIntegerItem(idx++);
12568 data = (KeyframeMotion.DataFormat)dataval;
12569 break;
12570 }
12571 }
12572
12573 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12574
12575 idx = 0;
12576
12577 int elemLength = 2;
12578 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12579 elemLength = 3;
12580
12581 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12582 while (idx < frames.Data.Length)
12583 {
12584 int remain = frames.Data.Length - idx;
12585
12586 if (remain < elemLength)
12587 break;
12588
12589 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12590 frame.Position = null;
12591 frame.Rotation = null;
12592
12593 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12594 {
12595 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12596 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12597 }
12598 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12599 {
12600 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12601 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12602 }
12603
12604 float tempf = (float)frames.GetLSLFloatItem(idx++);
12605 frame.TimeMS = (int)(tempf * 1000.0f);
12606
12607 keyframes.Add(frame);
12608 }
12609
12610 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12611 group.RootPart.KeyframeMotion.Start();
12612 }
12613 else
12614 {
12615 if (group.RootPart.KeyframeMotion == null)
12616 return;
12617
12618 if (options.Data.Length == 0)
12619 {
12620 group.RootPart.KeyframeMotion.Stop();
12621 return;
12622 }
12623
12624 int code = (int)options.GetLSLIntegerItem(0);
12625
12626 int idx = 0;
12627
12628 while (idx < options.Data.Length)
12629 {
12630 int option = (int)options.GetLSLIntegerItem(idx++);
12631 int remain = options.Data.Length - idx;
12632
12633 switch (option)
12634 {
12635 case ScriptBaseClass.KFM_COMMAND:
12636 int cmd = (int)options.GetLSLIntegerItem(idx++);
12637 switch (cmd)
12638 {
12639 case ScriptBaseClass.KFM_CMD_PLAY:
12640 group.RootPart.KeyframeMotion.Start();
12641 break;
12642 case ScriptBaseClass.KFM_CMD_STOP:
12643 group.RootPart.KeyframeMotion.Stop();
12644 break;
12645 case ScriptBaseClass.KFM_CMD_PAUSE:
12646 group.RootPart.KeyframeMotion.Pause();
12647 break;
12648 }
12649 break;
12650 }
12651 }
12652 }
12653 }
12654
12655 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12656 {
12657 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12658
12659 int idx = 0;
12660 int idxStart = 0;
12661
12662 bool positionChanged = false;
12663 Vector3 finalPos = Vector3.Zero;
12664
12665 try
12666 {
12667 while (idx < rules.Length)
12668 {
12669 ++rulesParsed;
12670 int code = rules.GetLSLIntegerItem(idx++);
12671
12672 int remain = rules.Length - idx;
12673 idxStart = idx;
12674
12675 switch (code)
12676 {
12677 case (int)ScriptBaseClass.PRIM_POSITION:
12678 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12679 {
12680 if (remain < 1)
12681 return null;
12682
12683 LSL_Vector v;
12684 v = rules.GetVector3Item(idx++);
12685
12686 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12687 if (part == null)
12688 break;
12689
12690 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12691 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12692 if (part.LinkNum > 1)
12693 {
12694 localRot = GetPartLocalRot(part);
12695 localPos = GetPartLocalPos(part);
12696 }
12697
12698 v -= localPos;
12699 v /= localRot;
12700
12701 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12702
12703 v = v + 2 * sitOffset;
12704
12705 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12706 av.SendAvatarDataToAllAgents();
12707
12708 }
12709 break;
12710
12711 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12712 case (int)ScriptBaseClass.PRIM_ROTATION:
12713 {
12714 if (remain < 1)
12715 return null;
12716
12717 LSL_Rotation r;
12718 r = rules.GetQuaternionItem(idx++);
12719
12720 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12721 if (part == null)
12722 break;
12723
12724 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12725 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12726
12727 if (part.LinkNum > 1)
12728 localRot = GetPartLocalRot(part);
12729
12730 r = r * llGetRootRotation() / localRot;
12731 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12732 av.SendAvatarDataToAllAgents();
12733 }
12734 break;
12735
12736 // parse rest doing nothing but number of parameters error check
12737 case (int)ScriptBaseClass.PRIM_SIZE:
12738 case (int)ScriptBaseClass.PRIM_MATERIAL:
12739 case (int)ScriptBaseClass.PRIM_PHANTOM:
12740 case (int)ScriptBaseClass.PRIM_PHYSICS:
12741 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12742 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12743 case (int)ScriptBaseClass.PRIM_NAME:
12744 case (int)ScriptBaseClass.PRIM_DESC:
12745 if (remain < 1)
12746 return null;
12747 idx++;
12748 break;
12749
12750 case (int)ScriptBaseClass.PRIM_GLOW:
12751 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12752 case (int)ScriptBaseClass.PRIM_TEXGEN:
12753 if (remain < 2)
12754 return null;
12755 idx += 2;
12756 break;
12757
12758 case (int)ScriptBaseClass.PRIM_TYPE:
12759 if (remain < 3)
12760 return null;
12761 code = (int)rules.GetLSLIntegerItem(idx++);
12762 remain = rules.Length - idx;
12763 switch (code)
12764 {
12765 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12766 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12767 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12768 if (remain < 6)
12769 return null;
12770 idx += 6;
12771 break;
12772
12773 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12774 if (remain < 5)
12775 return null;
12776 idx += 5;
12777 break;
12778
12779 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12780 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12781 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12782 if (remain < 11)
12783 return null;
12784 idx += 11;
12785 break;
12786
12787 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12788 if (remain < 2)
12789 return null;
12790 idx += 2;
12791 break;
12792 }
12793 break;
12794
12795 case (int)ScriptBaseClass.PRIM_COLOR:
12796 case (int)ScriptBaseClass.PRIM_TEXT:
12797 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12798 case (int)ScriptBaseClass.PRIM_OMEGA:
12799 if (remain < 3)
12800 return null;
12801 idx += 3;
12802 break;
12803
12804 case (int)ScriptBaseClass.PRIM_TEXTURE:
12805 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12806 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12807 if (remain < 5)
12808 return null;
12809 idx += 5;
12810 break;
12811
12812 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12813 if (remain < 7)
12814 return null;
12815
12816 idx += 7;
12817 break;
12818
12819 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12820 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12821 return null;
12822
12823 return rules.GetSublist(idx, -1);
12824 }
12825 }
12826 }
12827 catch (InvalidCastException e)
12828 {
12829 ShoutError(string.Format(
12830 "{0} error running rule #{1}: arg #{2} ",
12831 originFunc, rulesParsed, idx - idxStart) + e.Message);
12832 }
12833 finally
12834 {
12835 if (positionChanged)
12836 {
12837 av.OffsetPosition = finalPos;
12838// av.SendAvatarDataToAllAgents();
12839 av.SendTerseUpdateToAllClients();
12840 positionChanged = false;
12841 }
12842 }
12843 return null;
12844 }
12845
12846 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12847 {
12848 // avatars case
12849 // replies as SL wiki
12850
12851// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12852 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12853
12854 int idx = 0;
12855 while (idx < rules.Length)
12856 {
12857 int code = (int)rules.GetLSLIntegerItem(idx++);
12858 int remain = rules.Length - idx;
12859
12860 switch (code)
12861 {
12862 case (int)ScriptBaseClass.PRIM_MATERIAL:
12863 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12864 break;
12865
12866 case (int)ScriptBaseClass.PRIM_PHYSICS:
12867 res.Add(new LSL_Integer(0));
12868 break;
12869
12870 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12871 res.Add(new LSL_Integer(0));
12872 break;
12873
12874 case (int)ScriptBaseClass.PRIM_PHANTOM:
12875 res.Add(new LSL_Integer(0));
12876 break;
12877
12878 case (int)ScriptBaseClass.PRIM_POSITION:
12879
12880 Vector3 pos = avatar.OffsetPosition;
12881
12882 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12883 pos -= sitOffset;
12884
12885 if( sitPart != null)
12886 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12887
12888 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12889 break;
12890
12891 case (int)ScriptBaseClass.PRIM_SIZE:
12892 // as in llGetAgentSize above
12893 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12894 break;
12895
12896 case (int)ScriptBaseClass.PRIM_ROTATION:
12897 Quaternion rot = avatar.Rotation;
12898 if (sitPart != null)
12899 {
12900 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12901 }
12902
12903 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12904 break;
12905
12906 case (int)ScriptBaseClass.PRIM_TYPE:
12907 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12908 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12909 res.Add(new LSL_Vector(0f,1.0f,0f));
12910 res.Add(new LSL_Float(0.0f));
12911 res.Add(new LSL_Vector(0, 0, 0));
12912 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12913 res.Add(new LSL_Vector(0, 0, 0));
12914 break;
12915
12916 case (int)ScriptBaseClass.PRIM_TEXTURE:
12917 if (remain < 1)
12918 return null;
12919
12920 int face = (int)rules.GetLSLIntegerItem(idx++);
12921 if (face == ScriptBaseClass.ALL_SIDES)
12922 {
12923 for (face = 0; face < 21; face++)
12924 {
12925 res.Add(new LSL_String(""));
12926 res.Add(new LSL_Vector(0,0,0));
12927 res.Add(new LSL_Vector(0,0,0));
12928 res.Add(new LSL_Float(0.0));
12929 }
12930 }
12931 else
12932 {
12933 if (face >= 0 && face < 21)
12934 {
12935 res.Add(new LSL_String(""));
12936 res.Add(new LSL_Vector(0,0,0));
12937 res.Add(new LSL_Vector(0,0,0));
12938 res.Add(new LSL_Float(0.0));
12939 }
12940 }
12941 break;
12942
12943 case (int)ScriptBaseClass.PRIM_COLOR:
12944 if (remain < 1)
12945 return null;
12946
12947 face = (int)rules.GetLSLIntegerItem(idx++);
12948
12949 if (face == ScriptBaseClass.ALL_SIDES)
12950 {
12951 for (face = 0; face < 21; face++)
12952 {
12953 res.Add(new LSL_Vector(0,0,0));
12954 res.Add(new LSL_Float(0));
12955 }
12956 }
12957 else
12958 {
12959 res.Add(new LSL_Vector(0,0,0));
12960 res.Add(new LSL_Float(0));
12961 }
12962 break;
12963
12964 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12965 if (remain < 1)
12966 return null;
12967 face = (int)rules.GetLSLIntegerItem(idx++);
12968
12969 if (face == ScriptBaseClass.ALL_SIDES)
12970 {
12971 for (face = 0; face < 21; face++)
12972 {
12973 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12974 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12975 }
12976 }
12977 else
12978 {
12979 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12980 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12981 }
12982 break;
12983
12984 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12985 if (remain < 1)
12986 return null;
12987 face = (int)rules.GetLSLIntegerItem(idx++);
12988
12989 if (face == ScriptBaseClass.ALL_SIDES)
12990 {
12991 for (face = 0; face < 21; face++)
12992 {
12993 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12994 }
12995 }
12996 else
12997 {
12998 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12999 }
13000 break;
13001
13002 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13003 res.Add(new LSL_Integer(0));
13004 res.Add(new LSL_Integer(0));// softness
13005 res.Add(new LSL_Float(0.0f)); // gravity
13006 res.Add(new LSL_Float(0.0f)); // friction
13007 res.Add(new LSL_Float(0.0f)); // wind
13008 res.Add(new LSL_Float(0.0f)); // tension
13009 res.Add(new LSL_Vector(0f,0f,0f));
13010 break;
13011
13012 case (int)ScriptBaseClass.PRIM_TEXGEN:
13013 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13014 if (remain < 1)
13015 return null;
13016 face = (int)rules.GetLSLIntegerItem(idx++);
13017
13018 if (face == ScriptBaseClass.ALL_SIDES)
13019 {
13020 for (face = 0; face < 21; face++)
13021 {
13022 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13023 }
13024 }
13025 else
13026 {
13027 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13028 }
13029 break;
13030
13031 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13032 res.Add(new LSL_Integer(0));
13033 res.Add(new LSL_Vector(0f,0f,0f));
13034 res.Add(new LSL_Float(0f)); // intensity
13035 res.Add(new LSL_Float(0f)); // radius
13036 res.Add(new LSL_Float(0f)); // falloff
13037 break;
13038
13039 case (int)ScriptBaseClass.PRIM_GLOW:
13040 if (remain < 1)
13041 return null;
13042 face = (int)rules.GetLSLIntegerItem(idx++);
13043
13044 if (face == ScriptBaseClass.ALL_SIDES)
13045 {
13046 for (face = 0; face < 21; face++)
13047 {
13048 res.Add(new LSL_Float(0f));
13049 }
13050 }
13051 else
13052 {
13053 res.Add(new LSL_Float(0f));
13054 }
13055 break;
13056
13057 case (int)ScriptBaseClass.PRIM_TEXT:
13058 res.Add(new LSL_String(""));
13059 res.Add(new LSL_Vector(0f,0f,0f));
13060 res.Add(new LSL_Float(1.0f));
13061 break;
13062
13063 case (int)ScriptBaseClass.PRIM_NAME:
13064 res.Add(new LSL_String(avatar.Name));
13065 break;
13066
13067 case (int)ScriptBaseClass.PRIM_DESC:
13068 res.Add(new LSL_String(""));
13069 break;
13070
13071 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13072 Quaternion lrot = avatar.Rotation;
13073
13074 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13075 {
13076 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13077 }
13078 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13079 break;
13080
13081 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13082 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13083 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13084 lpos -= lsitOffset;
13085
13086 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13087 {
13088 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13089 }
13090 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13091 break;
13092
13093 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13094 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13095 return null;
13096
13097 return rules.GetSublist(idx, -1);
13098 }
13099 }
13100
13101 return null;
13102 }
11401 } 13103 }
11402 13104
11403 public class NotecardCache 13105 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 e245684..7aacfd4 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);
@@ -1803,6 +1812,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1803 1812
1804 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1813 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1805 { 1814 {
1815 m_host.TaskInventory.LockItemsForRead(true);
1806 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1816 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1807 { 1817 {
1808 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1818 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1810,6 +1820,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1810 assetID = item.AssetID; 1820 assetID = item.AssetID;
1811 } 1821 }
1812 } 1822 }
1823 m_host.TaskInventory.LockItemsForRead(false);
1813 } 1824 }
1814 1825
1815 if (assetID == UUID.Zero) 1826 if (assetID == UUID.Zero)
@@ -2295,7 +2306,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2295 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2306 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2296 m_host.AddScriptLPS(1); 2307 m_host.AddScriptLPS(1);
2297 2308
2298 return NpcCreate(firstname, lastname, position, notecard, false, false); 2309 return NpcCreate(firstname, lastname, position, notecard, true, false);
2299 } 2310 }
2300 2311
2301 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2312 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2306,24 +2317,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2306 return NpcCreate( 2317 return NpcCreate(
2307 firstname, lastname, position, notecard, 2318 firstname, lastname, position, notecard,
2308 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2319 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2309 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2320 false);
2321// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2310 } 2322 }
2311 2323
2312 private LSL_Key NpcCreate( 2324 private LSL_Key NpcCreate(
2313 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2325 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2314 { 2326 {
2327 if (!owned)
2328 OSSLError("Unowned NPCs are unsupported");
2329
2330 string groupTitle = String.Empty;
2331
2332 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2333 return new LSL_Key(UUID.Zero.ToString());
2334
2335 if (firstname != String.Empty || lastname != String.Empty)
2336 {
2337 if (firstname != "Shown outfit:")
2338 groupTitle = "- NPC -";
2339 }
2340
2315 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2341 INPCModule module = World.RequestModuleInterface<INPCModule>();
2316 if (module != null) 2342 if (module != null)
2317 { 2343 {
2318 AvatarAppearance appearance = null; 2344 AvatarAppearance appearance = null;
2319 2345
2320 UUID id; 2346// UUID id;
2321 if (UUID.TryParse(notecard, out id)) 2347// if (UUID.TryParse(notecard, out id))
2322 { 2348// {
2323 ScenePresence clonePresence = World.GetScenePresence(id); 2349// ScenePresence clonePresence = World.GetScenePresence(id);
2324 if (clonePresence != null) 2350// if (clonePresence != null)
2325 appearance = clonePresence.Appearance; 2351// appearance = clonePresence.Appearance;
2326 } 2352// }
2327 2353
2328 if (appearance == null) 2354 if (appearance == null)
2329 { 2355 {
@@ -2351,6 +2377,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2351 World, 2377 World,
2352 appearance); 2378 appearance);
2353 2379
2380 ScenePresence sp;
2381 if (World.TryGetScenePresence(x, out sp))
2382 {
2383 sp.Grouptitle = groupTitle;
2384 sp.SendAvatarDataToAllAgents();
2385 }
2354 return new LSL_Key(x.ToString()); 2386 return new LSL_Key(x.ToString());
2355 } 2387 }
2356 2388
@@ -2650,16 +2682,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2650 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2682 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2651 m_host.AddScriptLPS(1); 2683 m_host.AddScriptLPS(1);
2652 2684
2653 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2685 ManualResetEvent ev = new ManualResetEvent(false);
2654 if (module != null)
2655 {
2656 UUID npcId = new UUID(npc.m_string);
2657 2686
2658 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2687 Util.FireAndForget(delegate(object x) {
2659 return; 2688 try
2689 {
2690 INPCModule module = World.RequestModuleInterface<INPCModule>();
2691 if (module != null)
2692 {
2693 UUID npcId = new UUID(npc.m_string);
2660 2694
2661 module.DeleteNPC(npcId, World); 2695 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2662 } 2696 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2697 {
2698 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2699 return;
2700 }
2701
2702 module.DeleteNPC(npcId, World);
2703 }
2704 }
2705 finally
2706 {
2707 ev.Set();
2708 }
2709 });
2710 ev.WaitOne();
2663 } 2711 }
2664 2712
2665 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2713 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3373,6 +3421,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3373 if (m_UrlModule != null) 3421 if (m_UrlModule != null)
3374 m_UrlModule.HttpContentType(new UUID(id),type); 3422 m_UrlModule.HttpContentType(new UUID(id),type);
3375 } 3423 }
3376 3424 }
3377 } 3425}
3378} \ 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 }