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.cs3172
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs102
-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, 2672 insertions, 786 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 6e46992..fbb91ce 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 private List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 344 private 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);
4329
4330 GridInstantMessage msg = new GridInstantMessage(World,
4331 m_host.OwnerID, m_host.Name, destId,
4332 (byte)InstantMessageDialog.TaskInventoryOffered,
4333 false, item.Name+". "+m_host.Name+" is located at "+
4334 World.RegionInfo.RegionName+" "+
4335 m_host.AbsolutePosition.ToString(),
4336 agentItem.ID, true, m_host.AbsolutePosition,
4337 bucket);
3972 4338
3973 GridInstantMessage msg = new GridInstantMessage(World, 4339 ScenePresence sp;
3974 m_host.UUID, m_host.Name + ", an object owned by " +
3975 resolveName(m_host.OwnerID) + ",", destId,
3976 (byte)InstantMessageDialog.TaskInventoryOffered,
3977 false, item.Name + "\n" + m_host.Name + " is located at " +
3978 World.RegionInfo.RegionName+" "+
3979 m_host.AbsolutePosition.ToString(),
3980 agentItem.ID, true, m_host.AbsolutePosition,
3981 bucket);
3982 4340
3983 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4341 if (World.TryGetScenePresence(destId, out sp))
4342 {
4343 sp.ControllingClient.SendInstantMessage(msg);
3984 } 4344 }
3985 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)
@@ -5294,7 +5700,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5294 } 5700 }
5295 } 5701 }
5296 } 5702 }
5297 else { 5703 else
5704 {
5298 object[] array = new object[src.Length]; 5705 object[] array = new object[src.Length];
5299 Array.Copy(src.Data, 0, array, 0, src.Length); 5706 Array.Copy(src.Data, 0, array, 0, src.Length);
5300 result = new LSL_List(array); 5707 result = new LSL_List(array);
@@ -5401,7 +5808,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5401 public LSL_Integer llGetRegionAgentCount() 5808 public LSL_Integer llGetRegionAgentCount()
5402 { 5809 {
5403 m_host.AddScriptLPS(1); 5810 m_host.AddScriptLPS(1);
5404 return new LSL_Integer(World.GetRootAgentCount()); 5811
5812 int count = 0;
5813 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5814 count++;
5815 });
5816
5817 return new LSL_Integer(count);
5405 } 5818 }
5406 5819
5407 public LSL_Vector llGetRegionCorner() 5820 public LSL_Vector llGetRegionCorner()
@@ -5634,6 +6047,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5634 flags |= ScriptBaseClass.AGENT_AWAY; 6047 flags |= ScriptBaseClass.AGENT_AWAY;
5635 } 6048 }
5636 6049
6050 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6051 UUID[] anims = agent.Animator.GetAnimationArray();
6052 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6053 {
6054 flags |= ScriptBaseClass.AGENT_BUSY;
6055 }
6056
5637 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6057 // 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) 6058 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5639 { 6059 {
@@ -5681,6 +6101,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5681 flags |= ScriptBaseClass.AGENT_SITTING; 6101 flags |= ScriptBaseClass.AGENT_SITTING;
5682 } 6102 }
5683 6103
6104 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6105 {
6106 flags |= ScriptBaseClass.AGENT_MALE;
6107 }
6108
5684 return flags; 6109 return flags;
5685 } 6110 }
5686 6111
@@ -5828,9 +6253,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5828 6253
5829 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6254 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5830 6255
5831 foreach (SceneObjectPart part in parts) 6256 try
6257 {
6258 foreach (SceneObjectPart part in parts)
6259 {
6260 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6261 }
6262 }
6263 finally
5832 { 6264 {
5833 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5834 } 6265 }
5835 } 6266 }
5836 6267
@@ -5882,13 +6313,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5882 6313
5883 if (m_host.OwnerID == land.LandData.OwnerID) 6314 if (m_host.OwnerID == land.LandData.OwnerID)
5884 { 6315 {
5885 World.TeleportClientHome(agentID, presence.ControllingClient); 6316 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6317 presence.TeleportWithMomentum(pos, null);
6318 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5886 } 6319 }
5887 } 6320 }
5888 } 6321 }
5889 ScriptSleep(5000); 6322 ScriptSleep(5000);
5890 } 6323 }
5891 6324
6325 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6326 {
6327 return ParseString2List(str, separators, in_spacers, false);
6328 }
6329
5892 public LSL_Integer llOverMyLand(string id) 6330 public LSL_Integer llOverMyLand(string id)
5893 { 6331 {
5894 m_host.AddScriptLPS(1); 6332 m_host.AddScriptLPS(1);
@@ -5947,20 +6385,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5947 return agentSize; 6385 return agentSize;
5948 } 6386 }
5949 6387
5950 public LSL_Integer llSameGroup(string agent) 6388 public LSL_Integer llSameGroup(string id)
5951 { 6389 {
5952 m_host.AddScriptLPS(1); 6390 m_host.AddScriptLPS(1);
5953 UUID agentId = new UUID(); 6391 UUID uuid = new UUID();
5954 if (!UUID.TryParse(agent, out agentId)) 6392 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); 6393 return new LSL_Integer(0);
5959 IClientAPI client = presence.ControllingClient; 6394
5960 if (m_host.GroupID == client.ActiveGroupId) 6395 // Check if it's a group key
6396 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5961 return new LSL_Integer(1); 6397 return new LSL_Integer(1);
5962 else 6398
6399 // We got passed a UUID.Zero
6400 if (uuid == UUID.Zero)
5963 return new LSL_Integer(0); 6401 return new LSL_Integer(0);
6402
6403 // Handle the case where id names an avatar
6404 ScenePresence presence = World.GetScenePresence(uuid);
6405 if (presence != null)
6406 {
6407 if (presence.IsChildAgent)
6408 return new LSL_Integer(0);
6409
6410 IClientAPI client = presence.ControllingClient;
6411 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6412 return new LSL_Integer(1);
6413
6414 return new LSL_Integer(0);
6415 }
6416
6417 // Handle object case
6418 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6419 if (part != null)
6420 {
6421 // This will handle both deed and non-deed and also the no
6422 // group case
6423 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6424 return new LSL_Integer(1);
6425
6426 return new LSL_Integer(0);
6427 }
6428
6429 return new LSL_Integer(0);
5964 } 6430 }
5965 6431
5966 public void llUnSit(string id) 6432 public void llUnSit(string id)
@@ -6085,7 +6551,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6085 return m_host.ParentGroup.AttachmentPoint; 6551 return m_host.ParentGroup.AttachmentPoint;
6086 } 6552 }
6087 6553
6088 public LSL_Integer llGetFreeMemory() 6554 public virtual LSL_Integer llGetFreeMemory()
6089 { 6555 {
6090 m_host.AddScriptLPS(1); 6556 m_host.AddScriptLPS(1);
6091 // Make scripts designed for LSO happy 6557 // Make scripts designed for LSO happy
@@ -6202,7 +6668,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6202 SetParticleSystem(m_host, rules); 6668 SetParticleSystem(m_host, rules);
6203 } 6669 }
6204 6670
6205 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6671 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6672 {
6206 6673
6207 6674
6208 if (rules.Length == 0) 6675 if (rules.Length == 0)
@@ -6516,6 +6983,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6516 6983
6517 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6984 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6518 { 6985 {
6986 // LSL quaternions can normalize to 0, normal Quaternions can't.
6987 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6988 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6989
6519 part.SitTargetPosition = offset; 6990 part.SitTargetPosition = offset;
6520 part.SitTargetOrientation = rot; 6991 part.SitTargetOrientation = rot;
6521 part.ParentGroup.HasGroupChanged = true; 6992 part.ParentGroup.HasGroupChanged = true;
@@ -6671,13 +7142,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6671 UUID av = new UUID(); 7142 UUID av = new UUID();
6672 if (!UUID.TryParse(avatar,out av)) 7143 if (!UUID.TryParse(avatar,out av))
6673 { 7144 {
6674 LSLError("First parameter to llDialog needs to be a key"); 7145 //LSLError("First parameter to llDialog needs to be a key");
6675 return; 7146 return;
6676 } 7147 }
6677 if (buttons.Length < 1) 7148 if (buttons.Length < 1)
6678 { 7149 {
6679 LSLError("No less than 1 button can be shown"); 7150 buttons.Add("OK");
6680 return;
6681 } 7151 }
6682 if (buttons.Length > 12) 7152 if (buttons.Length > 12)
6683 { 7153 {
@@ -6694,7 +7164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6694 } 7164 }
6695 if (buttons.Data[i].ToString().Length > 24) 7165 if (buttons.Data[i].ToString().Length > 24)
6696 { 7166 {
6697 LSLError("button label cannot be longer than 24 characters"); 7167 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6698 return; 7168 return;
6699 } 7169 }
6700 buts[i] = buttons.Data[i].ToString(); 7170 buts[i] = buttons.Data[i].ToString();
@@ -6761,9 +7231,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6761 return; 7231 return;
6762 } 7232 }
6763 7233
6764 // the rest of the permission checks are done in RezScript, so check the pin there as well 7234 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6765 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7235 if (dest != null)
7236 {
7237 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7238 {
7239 // the rest of the permission checks are done in RezScript, so check the pin there as well
7240 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6766 7241
7242 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7243 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7244 }
7245 }
6767 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7246 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6768 ScriptSleep(3000); 7247 ScriptSleep(3000);
6769 } 7248 }
@@ -6826,19 +7305,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6826 public LSL_String llMD5String(string src, int nonce) 7305 public LSL_String llMD5String(string src, int nonce)
6827 { 7306 {
6828 m_host.AddScriptLPS(1); 7307 m_host.AddScriptLPS(1);
6829 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7308 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6830 } 7309 }
6831 7310
6832 public LSL_String llSHA1String(string src) 7311 public LSL_String llSHA1String(string src)
6833 { 7312 {
6834 m_host.AddScriptLPS(1); 7313 m_host.AddScriptLPS(1);
6835 return Util.SHA1Hash(src).ToLower(); 7314 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6836 } 7315 }
6837 7316
6838 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7317 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6839 { 7318 {
6840 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7319 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6841 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7320 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7321 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7322 return shapeBlock;
6842 7323
6843 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7324 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6844 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7325 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6943,6 +7424,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6943 // Prim type box, cylinder and prism. 7424 // 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) 7425 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 { 7426 {
7427 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7428 return;
7429
6946 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7430 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6947 ObjectShapePacket.ObjectDataBlock shapeBlock; 7431 ObjectShapePacket.ObjectDataBlock shapeBlock;
6948 7432
@@ -6996,6 +7480,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6996 // Prim type sphere. 7480 // 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) 7481 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6998 { 7482 {
7483 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7484 return;
7485
6999 ObjectShapePacket.ObjectDataBlock shapeBlock; 7486 ObjectShapePacket.ObjectDataBlock shapeBlock;
7000 7487
7001 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7488 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7037,6 +7524,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7037 // Prim type torus, tube and ring. 7524 // 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) 7525 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 { 7526 {
7527 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7528 return;
7529
7040 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7530 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7041 ObjectShapePacket.ObjectDataBlock shapeBlock; 7531 ObjectShapePacket.ObjectDataBlock shapeBlock;
7042 7532
@@ -7172,6 +7662,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7172 // Prim type sculpt. 7662 // Prim type sculpt.
7173 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7663 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7174 { 7664 {
7665 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7666 return;
7667
7175 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7668 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7176 UUID sculptId; 7669 UUID sculptId;
7177 7670
@@ -7196,7 +7689,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7196 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7689 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7197 { 7690 {
7198 // default 7691 // default
7199 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7692 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7200 } 7693 }
7201 7694
7202 part.Shape.SetSculptProperties((byte)type, sculptId); 7695 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7213,46 +7706,126 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7213 ScriptSleep(200); 7706 ScriptSleep(200);
7214 } 7707 }
7215 7708
7216 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7709 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7217 { 7710 {
7218 m_host.AddScriptLPS(1); 7711 m_host.AddScriptLPS(1);
7219 7712
7220 setLinkPrimParams(linknumber, rules); 7713 setLinkPrimParams(linknumber, rules);
7714 }
7221 7715
7222 ScriptSleep(200); 7716 private void setLinkPrimParams(int linknumber, LSL_List rules)
7717 {
7718 List<object> parts = new List<object>();
7719 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7720 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7721 foreach (SceneObjectPart p in prims)
7722 parts.Add(p);
7723 foreach (ScenePresence p in avatars)
7724 parts.Add(p);
7725
7726 LSL_List remaining = null;
7727
7728 if (parts.Count > 0)
7729 {
7730 foreach (object part in parts)
7731 {
7732 if (part is SceneObjectPart)
7733 remaining = SetPrimParams((SceneObjectPart)part, rules);
7734 else
7735 remaining = SetPrimParams((ScenePresence)part, rules);
7736 }
7737
7738 while((object)remaining != null && remaining.Length > 2)
7739 {
7740 linknumber = remaining.GetLSLIntegerItem(0);
7741 rules = remaining.GetSublist(1,-1);
7742 parts.Clear();
7743 prims = GetLinkParts(linknumber);
7744 avatars = GetLinkAvatars(linknumber);
7745 foreach (SceneObjectPart p in prims)
7746 parts.Add(p);
7747 foreach (ScenePresence p in avatars)
7748 parts.Add(p);
7749
7750 foreach (object part in parts)
7751 {
7752 if (part is SceneObjectPart)
7753 remaining = SetPrimParams((SceneObjectPart)part, rules);
7754 else
7755 remaining = SetPrimParams((ScenePresence)part, rules);
7756 }
7757 }
7758 }
7223 } 7759 }
7224 7760
7225 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7761 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7762 float material_density, float material_friction,
7763 float material_restitution, float material_gravity_modifier)
7226 { 7764 {
7227 m_host.AddScriptLPS(1); 7765 ExtraPhysicsData physdata = new ExtraPhysicsData();
7766 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7767 physdata.Density = part.Density;
7768 physdata.Friction = part.Friction;
7769 physdata.Bounce = part.Bounciness;
7770 physdata.GravitationModifier = part.GravityModifier;
7228 7771
7229 setLinkPrimParams(linknumber, rules); 7772 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7773 physdata.Density = material_density;
7774 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7775 physdata.Friction = material_friction;
7776 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7777 physdata.Bounce = material_restitution;
7778 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7779 physdata.GravitationModifier = material_gravity_modifier;
7780
7781 part.UpdateExtraPhysics(physdata);
7230 } 7782 }
7231 7783
7232 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7784 public void llSetPhysicsMaterial(int material_bits,
7785 float material_gravity_modifier, float material_restitution,
7786 float material_friction, float material_density)
7233 { 7787 {
7234 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7788 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7789 }
7235 7790
7236 LSL_List remaining = null; 7791 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7792 {
7793 llSetLinkPrimitiveParamsFast(linknumber, rules);
7794 ScriptSleep(200);
7795 }
7237 7796
7238 foreach (SceneObjectPart part in parts) 7797 // vector up using libomv (c&p from sop )
7239 remaining = SetPrimParams(part, rules); 7798 // vector up rotated by r
7799 private Vector3 Zrot(Quaternion r)
7800 {
7801 double x, y, z, m;
7240 7802
7241 while(remaining != null && remaining.Length > 2) 7803 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7804 if (Math.Abs(1.0 - m) > 0.000001)
7242 { 7805 {
7243 linknumber = remaining.GetLSLIntegerItem(0); 7806 m = 1.0 / Math.Sqrt(m);
7244 rules = remaining.GetSublist(1,-1); 7807 r.X *= (float)m;
7245 parts = GetLinkParts(linknumber); 7808 r.Y *= (float)m;
7246 7809 r.Z *= (float)m;
7247 foreach (SceneObjectPart part in parts) 7810 r.W *= (float)m;
7248 remaining = SetPrimParams(part, rules);
7249 } 7811 }
7812
7813 x = 2 * (r.X * r.Z + r.Y * r.W);
7814 y = 2 * (-r.X * r.W + r.Y * r.Z);
7815 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7816
7817 return new Vector3((float)x, (float)y, (float)z);
7250 } 7818 }
7251 7819
7252 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules) 7820 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules)
7253 { 7821 {
7822 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7823 return null;
7824
7254 int idx = 0; 7825 int idx = 0;
7255 7826
7827 SceneObjectGroup parentgrp = part.ParentGroup;
7828
7256 bool positionChanged = false; 7829 bool positionChanged = false;
7257 LSL_Vector currentPosition = GetPartLocalPos(part); 7830 LSL_Vector currentPosition = GetPartLocalPos(part);
7258 7831
@@ -7275,8 +7848,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7275 return null; 7848 return null;
7276 7849
7277 v=rules.GetVector3Item(idx++); 7850 v=rules.GetVector3Item(idx++);
7278 positionChanged = true;
7279 currentPosition = GetSetPosTarget(part, v, currentPosition); 7851 currentPosition = GetSetPosTarget(part, v, currentPosition);
7852 positionChanged = true;
7280 7853
7281 break; 7854 break;
7282 case (int)ScriptBaseClass.PRIM_SIZE: 7855 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7292,8 +7865,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7292 return null; 7865 return null;
7293 7866
7294 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7867 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7868 SceneObjectPart rootPart = parentgrp.RootPart;
7295 // try to let this work as in SL... 7869 // try to let this work as in SL...
7296 if (part.ParentID == 0) 7870 if (rootPart == part)
7297 { 7871 {
7298 // special case: If we are root, rotate complete SOG to new rotation 7872 // special case: If we are root, rotate complete SOG to new rotation
7299 SetRot(part, q); 7873 SetRot(part, q);
@@ -7301,7 +7875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7301 else 7875 else
7302 { 7876 {
7303 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 7877 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7304 SceneObjectPart rootPart = part.ParentGroup.RootPart; 7878 // sounds like sl bug that we need to replicate
7305 SetRot(part, rootPart.RotationOffset * (Quaternion)q); 7879 SetRot(part, rootPart.RotationOffset * (Quaternion)q);
7306 } 7880 }
7307 7881
@@ -7553,7 +8127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7553 return null; 8127 return null;
7554 8128
7555 string ph = rules.Data[idx++].ToString(); 8129 string ph = rules.Data[idx++].ToString();
7556 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8130 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7557 8131
7558 break; 8132 break;
7559 8133
@@ -7571,12 +8145,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7571 part.ScriptSetPhysicsStatus(physics); 8145 part.ScriptSetPhysicsStatus(physics);
7572 break; 8146 break;
7573 8147
8148 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8149 if (remain < 1)
8150 return null;
8151
8152 int shape_type = rules.GetLSLIntegerItem(idx++);
8153
8154 ExtraPhysicsData physdata = new ExtraPhysicsData();
8155 physdata.Density = part.Density;
8156 physdata.Bounce = part.Bounciness;
8157 physdata.GravitationModifier = part.GravityModifier;
8158 physdata.PhysShapeType = (PhysShapeType)shape_type;
8159
8160 part.UpdateExtraPhysics(physdata);
8161
8162 break;
8163
8164 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8165 if (remain < 5)
8166 return null;
8167
8168 int material_bits = rules.GetLSLIntegerItem(idx++);
8169 float material_density = (float)rules.GetLSLFloatItem(idx++);
8170 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8171 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8172 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8173
8174 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8175
8176 break;
8177
7574 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8178 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7575 if (remain < 1) 8179 if (remain < 1)
7576 return null; 8180 return null;
7577 string temp = rules.Data[idx++].ToString(); 8181 string temp = rules.Data[idx++].ToString();
7578 8182
7579 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8183 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7580 8184
7581 break; 8185 break;
7582 8186
@@ -7648,7 +8252,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7648 if (part.ParentGroup.RootPart == part) 8252 if (part.ParentGroup.RootPart == part)
7649 { 8253 {
7650 SceneObjectGroup parent = part.ParentGroup; 8254 SceneObjectGroup parent = part.ParentGroup;
7651 parent.UpdateGroupPosition(currentPosition); 8255 Util.FireAndForget(delegate(object x) {
8256 parent.UpdateGroupPosition(currentPosition);
8257 });
7652 } 8258 }
7653 else 8259 else
7654 { 8260 {
@@ -7693,10 +8299,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7693 8299
7694 public LSL_String llXorBase64Strings(string str1, string str2) 8300 public LSL_String llXorBase64Strings(string str1, string str2)
7695 { 8301 {
7696 m_host.AddScriptLPS(1); 8302 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7697 Deprecated("llXorBase64Strings"); 8303
7698 ScriptSleep(300); 8304 ScriptSleep(300);
7699 return String.Empty; 8305 m_host.AddScriptLPS(1);
8306
8307 if (str1 == String.Empty)
8308 return String.Empty;
8309 if (str2 == String.Empty)
8310 return str1;
8311
8312 int len = str2.Length;
8313 if ((len % 4) != 0) // LL is EVIL!!!!
8314 {
8315 while (str2.EndsWith("="))
8316 str2 = str2.Substring(0, str2.Length - 1);
8317
8318 len = str2.Length;
8319 int mod = len % 4;
8320
8321 if (mod == 1)
8322 str2 = str2.Substring(0, str2.Length - 1);
8323 else if (mod == 2)
8324 str2 += "==";
8325 else if (mod == 3)
8326 str2 += "=";
8327 }
8328
8329 byte[] data1;
8330 byte[] data2;
8331 try
8332 {
8333 data1 = Convert.FromBase64String(str1);
8334 data2 = Convert.FromBase64String(str2);
8335 }
8336 catch (Exception)
8337 {
8338 return new LSL_String(String.Empty);
8339 }
8340
8341 // For cases where the decoded length of s2 is greater
8342 // than the decoded length of s1, simply perform a normal
8343 // decode and XOR
8344 //
8345 if (data2.Length >= data1.Length)
8346 {
8347 for (int pos = 0 ; pos < data1.Length ; pos++ )
8348 data1[pos] ^= data2[pos];
8349
8350 return Convert.ToBase64String(data1);
8351 }
8352
8353 // Remove padding
8354 while (str1.EndsWith("="))
8355 str1 = str1.Substring(0, str1.Length - 1);
8356 while (str2.EndsWith("="))
8357 str2 = str2.Substring(0, str2.Length - 1);
8358
8359 byte[] d1 = new byte[str1.Length];
8360 byte[] d2 = new byte[str2.Length];
8361
8362 for (int i = 0 ; i < str1.Length ; i++)
8363 {
8364 int idx = b64.IndexOf(str1.Substring(i, 1));
8365 if (idx == -1)
8366 idx = 0;
8367 d1[i] = (byte)idx;
8368 }
8369
8370 for (int i = 0 ; i < str2.Length ; i++)
8371 {
8372 int idx = b64.IndexOf(str2.Substring(i, 1));
8373 if (idx == -1)
8374 idx = 0;
8375 d2[i] = (byte)idx;
8376 }
8377
8378 string output = String.Empty;
8379
8380 for (int pos = 0 ; pos < d1.Length ; pos++)
8381 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8382
8383 while (output.Length % 3 > 0)
8384 output += "=";
8385
8386 return output;
7700 } 8387 }
7701 8388
7702 public void llRemoteDataSetRegion() 8389 public void llRemoteDataSetRegion()
@@ -7820,13 +8507,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7820 public LSL_Integer llGetNumberOfPrims() 8507 public LSL_Integer llGetNumberOfPrims()
7821 { 8508 {
7822 m_host.AddScriptLPS(1); 8509 m_host.AddScriptLPS(1);
7823 int avatarCount = 0; 8510 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7824 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8511
7825 {
7826 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7827 avatarCount++;
7828 });
7829
7830 return m_host.ParentGroup.PrimCount + avatarCount; 8512 return m_host.ParentGroup.PrimCount + avatarCount;
7831 } 8513 }
7832 8514
@@ -7842,55 +8524,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7842 m_host.AddScriptLPS(1); 8524 m_host.AddScriptLPS(1);
7843 UUID objID = UUID.Zero; 8525 UUID objID = UUID.Zero;
7844 LSL_List result = new LSL_List(); 8526 LSL_List result = new LSL_List();
8527
8528 // If the ID is not valid, return null result
7845 if (!UUID.TryParse(obj, out objID)) 8529 if (!UUID.TryParse(obj, out objID))
7846 { 8530 {
7847 result.Add(new LSL_Vector()); 8531 result.Add(new LSL_Vector());
7848 result.Add(new LSL_Vector()); 8532 result.Add(new LSL_Vector());
7849 return result; 8533 return result;
7850 } 8534 }
8535
8536 // Check if this is an attached prim. If so, replace
8537 // the UUID with the avatar UUID and report it's bounding box
8538 SceneObjectPart part = World.GetSceneObjectPart(objID);
8539 if (part != null && part.ParentGroup.IsAttachment)
8540 objID = part.ParentGroup.AttachedAvatar;
8541
8542 // Find out if this is an avatar ID. If so, return it's box
7851 ScenePresence presence = World.GetScenePresence(objID); 8543 ScenePresence presence = World.GetScenePresence(objID);
7852 if (presence != null) 8544 if (presence != null)
7853 { 8545 {
7854 if (presence.ParentID == 0) // not sat on an object 8546 // As per LSL Wiki, there is no difference between sitting
8547 // and standing avatar since server 1.36
8548 LSL_Vector lower;
8549 LSL_Vector upper;
8550 if (presence.Animator.Animations.DefaultAnimation.AnimID
8551 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7855 { 8552 {
7856 LSL_Vector lower; 8553 // This is for ground sitting avatars
7857 LSL_Vector upper; 8554 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7858 if (presence.Animator.Animations.DefaultAnimation.AnimID 8555 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7859 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8556 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7860 {
7861 // This is for ground sitting avatars
7862 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7863 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7864 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7865 }
7866 else
7867 {
7868 // This is for standing/flying avatars
7869 float height = presence.Appearance.AvatarHeight / 2.0f;
7870 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7871 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7872 }
7873 result.Add(lower);
7874 result.Add(upper);
7875 return result;
7876 } 8557 }
7877 else 8558 else
7878 { 8559 {
7879 // sitting on an object so we need the bounding box of that 8560 // This is for standing/flying avatars
7880 // which should include the avatar so set the UUID to the 8561 float height = presence.Appearance.AvatarHeight / 2.0f;
7881 // UUID of the object the avatar is sat on and allow it to fall through 8562 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7882 // to processing an object 8563 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7883 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7884 objID = p.UUID;
7885 } 8564 }
8565
8566 // Adjust to the documented error offsets (see LSL Wiki)
8567 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8568 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8569
8570 if (lower.x > upper.x)
8571 lower.x = upper.x;
8572 if (lower.y > upper.y)
8573 lower.y = upper.y;
8574 if (lower.z > upper.z)
8575 lower.z = upper.z;
8576
8577 result.Add(lower);
8578 result.Add(upper);
8579 return result;
7886 } 8580 }
7887 SceneObjectPart part = World.GetSceneObjectPart(objID); 8581
8582 part = World.GetSceneObjectPart(objID);
7888 // Currently only works for single prims without a sitting avatar 8583 // Currently only works for single prims without a sitting avatar
7889 if (part != null) 8584 if (part != null)
7890 { 8585 {
7891 Vector3 halfSize = part.Scale / 2.0f; 8586 float minX;
7892 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8587 float maxX;
7893 LSL_Vector upper = new LSL_Vector(halfSize); 8588 float minY;
8589 float maxY;
8590 float minZ;
8591 float maxZ;
8592
8593 // This BBox is in sim coordinates, with the offset being
8594 // a contained point.
8595 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8596 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8597
8598 minX -= offsets[0].X;
8599 maxX -= offsets[0].X;
8600 minY -= offsets[0].Y;
8601 maxY -= offsets[0].Y;
8602 minZ -= offsets[0].Z;
8603 maxZ -= offsets[0].Z;
8604
8605 LSL_Vector lower;
8606 LSL_Vector upper;
8607
8608 // Adjust to the documented error offsets (see LSL Wiki)
8609 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8610 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8611
8612 if (lower.x > upper.x)
8613 lower.x = upper.x;
8614 if (lower.y > upper.y)
8615 lower.y = upper.y;
8616 if (lower.z > upper.z)
8617 lower.z = upper.z;
8618
7894 result.Add(lower); 8619 result.Add(lower);
7895 result.Add(upper); 8620 result.Add(upper);
7896 return result; 8621 return result;
@@ -7904,7 +8629,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7904 8629
7905 public LSL_Vector llGetGeometricCenter() 8630 public LSL_Vector llGetGeometricCenter()
7906 { 8631 {
7907 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8632 Vector3 tmp = m_host.GetGeometricCenter();
8633 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7908 } 8634 }
7909 8635
7910 public LSL_List llGetPrimitiveParams(LSL_List rules) 8636 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7922,15 +8648,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7922 { 8648 {
7923 m_host.AddScriptLPS(1); 8649 m_host.AddScriptLPS(1);
7924 8650
8651 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8652 // keep other options as before
8653
7925 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8654 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8655 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7926 8656
7927 LSL_List res = new LSL_List(); 8657 LSL_List res = new LSL_List();
7928 8658
7929 foreach (SceneObjectPart part in parts) 8659 if (parts.Count > 0)
7930 { 8660 {
7931 GetPrimParams(part, rules, ref res); 8661 foreach (var part in parts)
8662 {
8663 GetPrimParams(part, rules, ref res);
8664 }
8665 }
8666 if (avatars.Count > 0)
8667 {
8668 foreach (ScenePresence avatar in avatars)
8669 {
8670 GetPrimParams(avatar, rules, ref res);
8671 }
8672 // TODO: FINISH MERGE
7932 } 8673 }
7933
7934 return res; 8674 return res;
7935 } 8675 }
7936 8676
@@ -7973,13 +8713,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7973 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8713 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7974 part.AbsolutePosition.Y, 8714 part.AbsolutePosition.Y,
7975 part.AbsolutePosition.Z); 8715 part.AbsolutePosition.Z);
7976 // For some reason, the part.AbsolutePosition.* values do not change if the
7977 // linkset is rotated; they always reflect the child prim's world position
7978 // as though the linkset is unrotated. This is incompatible behavior with SL's
7979 // implementation, so will break scripts imported from there (not to mention it
7980 // makes it more difficult to determine a child prim's actual inworld position).
7981 if (part.ParentID != 0)
7982 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7983 res.Add(v); 8716 res.Add(v);
7984 break; 8717 break;
7985 8718
@@ -8150,56 +8883,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8150 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8883 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8151 if (remain < 1) 8884 if (remain < 1)
8152 return; 8885 return;
8153 8886 face = (int)rules.GetLSLIntegerItem(idx++);
8154 face=(int)rules.GetLSLIntegerItem(idx++);
8155 8887
8156 tex = part.Shape.Textures; 8888 tex = part.Shape.Textures;
8889 int shiny;
8157 if (face == ScriptBaseClass.ALL_SIDES) 8890 if (face == ScriptBaseClass.ALL_SIDES)
8158 { 8891 {
8159 for (face = 0; face < GetNumberOfSides(part); face++) 8892 for (face = 0; face < GetNumberOfSides(part); face++)
8160 { 8893 {
8161 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8894 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8162 // Convert Shininess to PRIM_SHINY_* 8895 if (shinyness == Shininess.High)
8163 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8896 {
8164 // PRIM_BUMP_* 8897 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8165 res.Add(new LSL_Integer((int)texface.Bump)); 8898 }
8899 else if (shinyness == Shininess.Medium)
8900 {
8901 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8902 }
8903 else if (shinyness == Shininess.Low)
8904 {
8905 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8906 }
8907 else
8908 {
8909 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8910 }
8911 res.Add(new LSL_Integer(shiny));
8912 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8166 } 8913 }
8167 } 8914 }
8168 else 8915 else
8169 { 8916 {
8170 if (face >= 0 && face < GetNumberOfSides(part)) 8917 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8918 if (shinyness == Shininess.High)
8171 { 8919 {
8172 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8920 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8173 // Convert Shininess to PRIM_SHINY_*
8174 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8175 // PRIM_BUMP_*
8176 res.Add(new LSL_Integer((int)texface.Bump));
8177 } 8921 }
8922 else if (shinyness == Shininess.Medium)
8923 {
8924 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8925 }
8926 else if (shinyness == Shininess.Low)
8927 {
8928 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8929 }
8930 else
8931 {
8932 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8933 }
8934 res.Add(new LSL_Integer(shiny));
8935 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8178 } 8936 }
8179 break; 8937 break;
8180 8938
8181 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8939 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8182 if (remain < 1) 8940 if (remain < 1)
8183 return; 8941 return;
8184 8942 face = (int)rules.GetLSLIntegerItem(idx++);
8185 face=(int)rules.GetLSLIntegerItem(idx++);
8186 8943
8187 tex = part.Shape.Textures; 8944 tex = part.Shape.Textures;
8945 int fullbright;
8188 if (face == ScriptBaseClass.ALL_SIDES) 8946 if (face == ScriptBaseClass.ALL_SIDES)
8189 { 8947 {
8190 for (face = 0; face < GetNumberOfSides(part); face++) 8948 for (face = 0; face < GetNumberOfSides(part); face++)
8191 { 8949 {
8192 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8950 if (tex.GetFace((uint)face).Fullbright == true)
8193 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8951 {
8952 fullbright = ScriptBaseClass.TRUE;
8953 }
8954 else
8955 {
8956 fullbright = ScriptBaseClass.FALSE;
8957 }
8958 res.Add(new LSL_Integer(fullbright));
8194 } 8959 }
8195 } 8960 }
8196 else 8961 else
8197 { 8962 {
8198 if (face >= 0 && face < GetNumberOfSides(part)) 8963 if (tex.GetFace((uint)face).Fullbright == true)
8199 { 8964 {
8200 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8965 fullbright = ScriptBaseClass.TRUE;
8201 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8966 }
8967 else
8968 {
8969 fullbright = ScriptBaseClass.FALSE;
8202 } 8970 }
8971 res.Add(new LSL_Integer(fullbright));
8203 } 8972 }
8204 break; 8973 break;
8205 8974
@@ -8221,27 +8990,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8221 break; 8990 break;
8222 8991
8223 case (int)ScriptBaseClass.PRIM_TEXGEN: 8992 case (int)ScriptBaseClass.PRIM_TEXGEN:
8993 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8224 if (remain < 1) 8994 if (remain < 1)
8225 return; 8995 return;
8226 8996 face = (int)rules.GetLSLIntegerItem(idx++);
8227 face=(int)rules.GetLSLIntegerItem(idx++);
8228 8997
8229 tex = part.Shape.Textures; 8998 tex = part.Shape.Textures;
8230 if (face == ScriptBaseClass.ALL_SIDES) 8999 if (face == ScriptBaseClass.ALL_SIDES)
8231 { 9000 {
8232 for (face = 0; face < GetNumberOfSides(part); face++) 9001 for (face = 0; face < GetNumberOfSides(part); face++)
8233 { 9002 {
8234 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9003 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8235 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9004 {
8236 res.Add(new LSL_Integer((uint)texgen >> 1)); 9005 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9006 }
9007 else
9008 {
9009 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9010 }
8237 } 9011 }
8238 } 9012 }
8239 else 9013 else
8240 { 9014 {
8241 if (face >= 0 && face < GetNumberOfSides(part)) 9015 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9016 {
9017 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9018 }
9019 else
8242 { 9020 {
8243 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9021 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8244 res.Add(new LSL_Integer((uint)texgen >> 1));
8245 } 9022 }
8246 } 9023 }
8247 break; 9024 break;
@@ -8264,25 +9041,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8264 case (int)ScriptBaseClass.PRIM_GLOW: 9041 case (int)ScriptBaseClass.PRIM_GLOW:
8265 if (remain < 1) 9042 if (remain < 1)
8266 return; 9043 return;
8267 9044 face = (int)rules.GetLSLIntegerItem(idx++);
8268 face=(int)rules.GetLSLIntegerItem(idx++);
8269 9045
8270 tex = part.Shape.Textures; 9046 tex = part.Shape.Textures;
9047 float primglow;
8271 if (face == ScriptBaseClass.ALL_SIDES) 9048 if (face == ScriptBaseClass.ALL_SIDES)
8272 { 9049 {
8273 for (face = 0; face < GetNumberOfSides(part); face++) 9050 for (face = 0; face < GetNumberOfSides(part); face++)
8274 { 9051 {
8275 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9052 primglow = tex.GetFace((uint)face).Glow;
8276 res.Add(new LSL_Float(texface.Glow)); 9053 res.Add(new LSL_Float(primglow));
8277 } 9054 }
8278 } 9055 }
8279 else 9056 else
8280 { 9057 {
8281 if (face >= 0 && face < GetNumberOfSides(part)) 9058 primglow = tex.GetFace((uint)face).Glow;
8282 { 9059 res.Add(new LSL_Float(primglow));
8283 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8284 res.Add(new LSL_Float(texface.Glow));
8285 }
8286 } 9060 }
8287 break; 9061 break;
8288 9062
@@ -8294,18 +9068,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8294 textColor.B)); 9068 textColor.B));
8295 res.Add(new LSL_Float(textColor.A)); 9069 res.Add(new LSL_Float(textColor.A));
8296 break; 9070 break;
9071
8297 case (int)ScriptBaseClass.PRIM_NAME: 9072 case (int)ScriptBaseClass.PRIM_NAME:
8298 res.Add(new LSL_String(part.Name)); 9073 res.Add(new LSL_String(part.Name));
8299 break; 9074 break;
9075
8300 case (int)ScriptBaseClass.PRIM_DESC: 9076 case (int)ScriptBaseClass.PRIM_DESC:
8301 res.Add(new LSL_String(part.Description)); 9077 res.Add(new LSL_String(part.Description));
8302 break; 9078 break;
9079
8303 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9080 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8304 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9081 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8305 break; 9082 break;
9083
8306 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9084 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8307 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9085 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8308 break; 9086 break;
9087 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9088 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9089 return;
9090 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9091 LSL_List new_rules = rules.GetSublist(idx, -1);
9092 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9093 res += tres;
9094 return;
8309 case (int)ScriptBaseClass.PRIM_SLICE: 9095 case (int)ScriptBaseClass.PRIM_SLICE:
8310 PrimType prim_type = part.GetPrimType(); 9096 PrimType prim_type = part.GetPrimType();
8311 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING); 9097 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING);
@@ -8906,8 +9692,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8906 // The function returns an ordered list 9692 // The function returns an ordered list
8907 // representing the tokens found in the supplied 9693 // representing the tokens found in the supplied
8908 // sources string. If two successive tokenizers 9694 // sources string. If two successive tokenizers
8909 // are encountered, then a NULL entry is added 9695 // are encountered, then a null-string entry is
8910 // to the list. 9696 // added to the list.
8911 // 9697 //
8912 // It is a precondition that the source and 9698 // It is a precondition that the source and
8913 // toekizer lisst are non-null. If they are null, 9699 // toekizer lisst are non-null. If they are null,
@@ -8915,7 +9701,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8915 // while their lengths are being determined. 9701 // while their lengths are being determined.
8916 // 9702 //
8917 // A small amount of working memoryis required 9703 // A small amount of working memoryis required
8918 // of approximately 8*#tokenizers. 9704 // of approximately 8*#tokenizers + 8*srcstrlen.
8919 // 9705 //
8920 // There are many ways in which this function 9706 // There are many ways in which this function
8921 // can be implemented, this implementation is 9707 // can be implemented, this implementation is
@@ -8931,155 +9717,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8931 // and eliminates redundant tokenizers as soon 9717 // and eliminates redundant tokenizers as soon
8932 // as is possible. 9718 // as is possible.
8933 // 9719 //
8934 // The implementation tries to avoid any copying 9720 // The implementation tries to minimize temporary
8935 // of arrays or other objects. 9721 // garbage generation.
8936 // </remarks> 9722 // </remarks>
8937 9723
8938 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9724 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8939 { 9725 {
8940 int beginning = 0; 9726 return ParseString2List(src, separators, spacers, true);
8941 int srclen = src.Length; 9727 }
8942 int seplen = separators.Length;
8943 object[] separray = separators.Data;
8944 int spclen = spacers.Length;
8945 object[] spcarray = spacers.Data;
8946 int mlen = seplen+spclen;
8947
8948 int[] offset = new int[mlen+1];
8949 bool[] active = new bool[mlen];
8950
8951 int best;
8952 int j;
8953
8954 // Initial capacity reduces resize cost
8955 9728
8956 LSL_List tokens = new LSL_List(); 9729 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9730 {
9731 int srclen = src.Length;
9732 int seplen = separators.Length;
9733 object[] separray = separators.Data;
9734 int spclen = spacers.Length;
9735 object[] spcarray = spacers.Data;
9736 int dellen = 0;
9737 string[] delarray = new string[seplen+spclen];
8957 9738
8958 // All entries are initially valid 9739 int outlen = 0;
9740 string[] outarray = new string[srclen*2+1];
8959 9741
8960 for (int i = 0; i < mlen; i++) 9742 int i, j;
8961 active[i] = true; 9743 string d;
8962 9744
8963 offset[mlen] = srclen; 9745 m_host.AddScriptLPS(1);
8964 9746
8965 while (beginning < srclen) 9747 /*
9748 * Convert separator and spacer lists to C# strings.
9749 * Also filter out null strings so we don't hang.
9750 */
9751 for (i = 0; i < seplen; i ++)
8966 { 9752 {
9753 d = separray[i].ToString();
9754 if (d.Length > 0)
9755 {
9756 delarray[dellen++] = d;
9757 }
9758 }
9759 seplen = dellen;
8967 9760
8968 best = mlen; // as bad as it gets 9761 for (i = 0; i < spclen; i ++)
9762 {
9763 d = spcarray[i].ToString();
9764 if (d.Length > 0)
9765 {
9766 delarray[dellen++] = d;
9767 }
9768 }
8969 9769
8970 // Scan for separators 9770 /*
9771 * Scan through source string from beginning to end.
9772 */
9773 for (i = 0;;)
9774 {
8971 9775
8972 for (j = 0; j < seplen; j++) 9776 /*
9777 * Find earliest delimeter in src starting at i (if any).
9778 */
9779 int earliestDel = -1;
9780 int earliestSrc = srclen;
9781 string earliestStr = null;
9782 for (j = 0; j < dellen; j ++)
8973 { 9783 {
8974 if (separray[j].ToString() == String.Empty) 9784 d = delarray[j];
8975 active[j] = false; 9785 if (d != null)
8976
8977 if (active[j])
8978 { 9786 {
8979 // scan all of the markers 9787 int index = src.IndexOf(d, i);
8980 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9788 if (index < 0)
8981 { 9789 {
8982 // not present at all 9790 delarray[j] = null; // delim nowhere in src, don't check it anymore
8983 active[j] = false;
8984 } 9791 }
8985 else 9792 else if (index < earliestSrc)
8986 { 9793 {
8987 // present and correct 9794 earliestSrc = index; // where delimeter starts in source string
8988 if (offset[j] < offset[best]) 9795 earliestDel = j; // where delimeter is in delarray[]
8989 { 9796 earliestStr = d; // the delimeter string from delarray[]
8990 // closest so far 9797 if (index == i) break; // can't do any better than found at beg of string
8991 best = j;
8992 if (offset[best] == beginning)
8993 break;
8994 }
8995 } 9798 }
8996 } 9799 }
8997 } 9800 }
8998 9801
8999 // Scan for spacers 9802 /*
9000 9803 * Output source string starting at i through start of earliest delimeter.
9001 if (offset[best] != beginning) 9804 */
9805 if (keepNulls || (earliestSrc > i))
9002 { 9806 {
9003 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9807 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9004 {
9005 if (spcarray[j-seplen].ToString() == String.Empty)
9006 active[j] = false;
9007
9008 if (active[j])
9009 {
9010 // scan all of the markers
9011 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9012 {
9013 // not present at all
9014 active[j] = false;
9015 }
9016 else
9017 {
9018 // present and correct
9019 if (offset[j] < offset[best])
9020 {
9021 // closest so far
9022 best = j;
9023 }
9024 }
9025 }
9026 }
9027 } 9808 }
9028 9809
9029 // This is the normal exit from the scanning loop 9810 /*
9811 * If no delimeter found at or after i, we're done scanning.
9812 */
9813 if (earliestDel < 0) break;
9030 9814
9031 if (best == mlen) 9815 /*
9816 * If delimeter was a spacer, output the spacer.
9817 */
9818 if (earliestDel >= seplen)
9032 { 9819 {
9033 // no markers were found on this pass 9820 outarray[outlen++] = earliestStr;
9034 // so we're pretty much done
9035 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9036 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9037 break;
9038 } 9821 }
9039 9822
9040 // Otherwise we just add the newly delimited token 9823 /*
9041 // and recalculate where the search should continue. 9824 * Look at rest of src string following delimeter.
9042 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9825 */
9043 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9826 i = earliestSrc + earliestStr.Length;
9044
9045 if (best < seplen)
9046 {
9047 beginning = offset[best] + (separray[best].ToString()).Length;
9048 }
9049 else
9050 {
9051 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9052 string str = spcarray[best - seplen].ToString();
9053 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9054 tokens.Add(new LSL_String(str));
9055 }
9056 } 9827 }
9057 9828
9058 // This an awkward an not very intuitive boundary case. If the 9829 /*
9059 // last substring is a tokenizer, then there is an implied trailing 9830 * Make up an exact-sized output array suitable for an LSL_List object.
9060 // null list entry. Hopefully the single comparison will not be too 9831 */
9061 // arduous. Alternatively the 'break' could be replced with a return 9832 object[] outlist = new object[outlen];
9062 // but that's shabby programming. 9833 for (i = 0; i < outlen; i ++)
9063
9064 if ((beginning == srclen) && (keepNulls))
9065 { 9834 {
9066 if (srclen != 0) 9835 outlist[i] = new LSL_String(outarray[i]);
9067 tokens.Add(new LSL_String(""));
9068 } 9836 }
9069 9837 return new LSL_List(outlist);
9070 return tokens;
9071 }
9072
9073 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9074 {
9075 m_host.AddScriptLPS(1);
9076 return this.ParseString(src, separators, spacers, false);
9077 }
9078
9079 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9080 {
9081 m_host.AddScriptLPS(1);
9082 return this.ParseString(src, separators, spacers, true);
9083 } 9838 }
9084 9839
9085 public LSL_Integer llGetObjectPermMask(int mask) 9840 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9174,6 +9929,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9174 case 4: 9929 case 4:
9175 return (int)item.NextPermissions; 9930 return (int)item.NextPermissions;
9176 } 9931 }
9932 m_host.TaskInventory.LockItemsForRead(false);
9177 9933
9178 return -1; 9934 return -1;
9179 } 9935 }
@@ -9364,9 +10120,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9364 { 10120 {
9365 try 10121 try
9366 { 10122 {
10123 /*
9367 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10124 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9368 if (obj != null) 10125 if (obj != null)
9369 return (double)obj.GetMass(); 10126 return (double)obj.GetMass();
10127 */
10128 // return total object mass
10129 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10130 if (obj != null)
10131 return obj.GetMass();
10132
9370 // the object is null so the key is for an avatar 10133 // the object is null so the key is for an avatar
9371 ScenePresence avatar = World.GetScenePresence(key); 10134 ScenePresence avatar = World.GetScenePresence(key);
9372 if (avatar != null) 10135 if (avatar != null)
@@ -9386,7 +10149,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9386 } 10149 }
9387 10150
9388 /// <summary> 10151 /// <summary>
9389 /// illListReplaceList removes the sub-list defined by the inclusive indices 10152 /// llListReplaceList removes the sub-list defined by the inclusive indices
9390 /// start and end and inserts the src list in its place. The inclusive 10153 /// start and end and inserts the src list in its place. The inclusive
9391 /// nature of the indices means that at least one element must be deleted 10154 /// nature of the indices means that at least one element must be deleted
9392 /// if the indices are within the bounds of the existing list. I.e. 2,2 10155 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9443,16 +10206,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9443 // based upon end. Note that if end exceeds the upper 10206 // based upon end. Note that if end exceeds the upper
9444 // bound in this case, the entire destination list 10207 // bound in this case, the entire destination list
9445 // is removed. 10208 // is removed.
9446 else 10209 else if (start == 0)
9447 { 10210 {
9448 if (end + 1 < dest.Length) 10211 if (end + 1 < dest.Length)
9449 {
9450 return src + dest.GetSublist(end + 1, -1); 10212 return src + dest.GetSublist(end + 1, -1);
9451 }
9452 else 10213 else
9453 {
9454 return src; 10214 return src;
9455 } 10215 }
10216 else // Start < 0
10217 {
10218 if (end + 1 < dest.Length)
10219 return dest.GetSublist(end + 1, -1);
10220 else
10221 return new LSL_List();
9456 } 10222 }
9457 } 10223 }
9458 // Finally, if start > end, we strip away a prefix and 10224 // Finally, if start > end, we strip away a prefix and
@@ -9503,17 +10269,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9503 int width = 0; 10269 int width = 0;
9504 int height = 0; 10270 int height = 0;
9505 10271
9506 ParcelMediaCommandEnum? commandToSend = null; 10272 uint commandToSend = 0;
9507 float time = 0.0f; // default is from start 10273 float time = 0.0f; // default is from start
9508 10274
9509 ScenePresence presence = null; 10275 ScenePresence presence = null;
9510 10276
9511 for (int i = 0; i < commandList.Data.Length; i++) 10277 for (int i = 0; i < commandList.Data.Length; i++)
9512 { 10278 {
9513 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10279 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9514 switch (command) 10280 switch (command)
9515 { 10281 {
9516 case ParcelMediaCommandEnum.Agent: 10282 case (uint)ParcelMediaCommandEnum.Agent:
9517 // we send only to one agent 10283 // we send only to one agent
9518 if ((i + 1) < commandList.Length) 10284 if ((i + 1) < commandList.Length)
9519 { 10285 {
@@ -9530,25 +10296,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9530 } 10296 }
9531 break; 10297 break;
9532 10298
9533 case ParcelMediaCommandEnum.Loop: 10299 case (uint)ParcelMediaCommandEnum.Loop:
9534 loop = 1; 10300 loop = 1;
9535 commandToSend = command; 10301 commandToSend = command;
9536 update = true; //need to send the media update packet to set looping 10302 update = true; //need to send the media update packet to set looping
9537 break; 10303 break;
9538 10304
9539 case ParcelMediaCommandEnum.Play: 10305 case (uint)ParcelMediaCommandEnum.Play:
9540 loop = 0; 10306 loop = 0;
9541 commandToSend = command; 10307 commandToSend = command;
9542 update = true; //need to send the media update packet to make sure it doesn't loop 10308 update = true; //need to send the media update packet to make sure it doesn't loop
9543 break; 10309 break;
9544 10310
9545 case ParcelMediaCommandEnum.Pause: 10311 case (uint)ParcelMediaCommandEnum.Pause:
9546 case ParcelMediaCommandEnum.Stop: 10312 case (uint)ParcelMediaCommandEnum.Stop:
9547 case ParcelMediaCommandEnum.Unload: 10313 case (uint)ParcelMediaCommandEnum.Unload:
9548 commandToSend = command; 10314 commandToSend = command;
9549 break; 10315 break;
9550 10316
9551 case ParcelMediaCommandEnum.Url: 10317 case (uint)ParcelMediaCommandEnum.Url:
9552 if ((i + 1) < commandList.Length) 10318 if ((i + 1) < commandList.Length)
9553 { 10319 {
9554 if (commandList.Data[i + 1] is LSL_String) 10320 if (commandList.Data[i + 1] is LSL_String)
@@ -9561,7 +10327,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9561 } 10327 }
9562 break; 10328 break;
9563 10329
9564 case ParcelMediaCommandEnum.Texture: 10330 case (uint)ParcelMediaCommandEnum.Texture:
9565 if ((i + 1) < commandList.Length) 10331 if ((i + 1) < commandList.Length)
9566 { 10332 {
9567 if (commandList.Data[i + 1] is LSL_String) 10333 if (commandList.Data[i + 1] is LSL_String)
@@ -9574,7 +10340,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9574 } 10340 }
9575 break; 10341 break;
9576 10342
9577 case ParcelMediaCommandEnum.Time: 10343 case (uint)ParcelMediaCommandEnum.Time:
9578 if ((i + 1) < commandList.Length) 10344 if ((i + 1) < commandList.Length)
9579 { 10345 {
9580 if (commandList.Data[i + 1] is LSL_Float) 10346 if (commandList.Data[i + 1] is LSL_Float)
@@ -9586,7 +10352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9586 } 10352 }
9587 break; 10353 break;
9588 10354
9589 case ParcelMediaCommandEnum.AutoAlign: 10355 case (uint)ParcelMediaCommandEnum.AutoAlign:
9590 if ((i + 1) < commandList.Length) 10356 if ((i + 1) < commandList.Length)
9591 { 10357 {
9592 if (commandList.Data[i + 1] is LSL_Integer) 10358 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9600,7 +10366,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9600 } 10366 }
9601 break; 10367 break;
9602 10368
9603 case ParcelMediaCommandEnum.Type: 10369 case (uint)ParcelMediaCommandEnum.Type:
9604 if ((i + 1) < commandList.Length) 10370 if ((i + 1) < commandList.Length)
9605 { 10371 {
9606 if (commandList.Data[i + 1] is LSL_String) 10372 if (commandList.Data[i + 1] is LSL_String)
@@ -9613,7 +10379,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9613 } 10379 }
9614 break; 10380 break;
9615 10381
9616 case ParcelMediaCommandEnum.Desc: 10382 case (uint)ParcelMediaCommandEnum.Desc:
9617 if ((i + 1) < commandList.Length) 10383 if ((i + 1) < commandList.Length)
9618 { 10384 {
9619 if (commandList.Data[i + 1] is LSL_String) 10385 if (commandList.Data[i + 1] is LSL_String)
@@ -9626,7 +10392,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9626 } 10392 }
9627 break; 10393 break;
9628 10394
9629 case ParcelMediaCommandEnum.Size: 10395 case (uint)ParcelMediaCommandEnum.Size:
9630 if ((i + 2) < commandList.Length) 10396 if ((i + 2) < commandList.Length)
9631 { 10397 {
9632 if (commandList.Data[i + 1] is LSL_Integer) 10398 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9696,7 +10462,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9696 } 10462 }
9697 } 10463 }
9698 10464
9699 if (commandToSend != null) 10465 if (commandToSend != 0)
9700 { 10466 {
9701 // the commandList contained a start/stop/... command, too 10467 // the commandList contained a start/stop/... command, too
9702 if (presence == null) 10468 if (presence == null)
@@ -9733,7 +10499,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9733 10499
9734 if (aList.Data[i] != null) 10500 if (aList.Data[i] != null)
9735 { 10501 {
9736 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10502 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9737 { 10503 {
9738 case ParcelMediaCommandEnum.Url: 10504 case ParcelMediaCommandEnum.Url:
9739 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10505 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9790,15 +10556,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9790 10556
9791 if (quick_pay_buttons.Data.Length < 4) 10557 if (quick_pay_buttons.Data.Length < 4)
9792 { 10558 {
9793 LSLError("List must have at least 4 elements"); 10559 int x;
9794 return; 10560 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10561 {
10562 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10563 }
9795 } 10564 }
9796 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10565 int[] nPrice = new int[5];
9797 10566 nPrice[0] = price;
9798 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10567 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9799 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10568 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9800 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10569 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9801 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10570 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10571 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9802 m_host.ParentGroup.HasGroupChanged = true; 10572 m_host.ParentGroup.HasGroupChanged = true;
9803 } 10573 }
9804 10574
@@ -9815,7 +10585,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9815 return new LSL_Vector(); 10585 return new LSL_Vector();
9816 } 10586 }
9817 10587
9818 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10588// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10589 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9819 if (presence != null) 10590 if (presence != null)
9820 { 10591 {
9821 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10592 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9837,7 +10608,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9837 return new LSL_Rotation(); 10608 return new LSL_Rotation();
9838 } 10609 }
9839 10610
9840 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10611// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10612 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9841 if (presence != null) 10613 if (presence != null)
9842 { 10614 {
9843 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10615 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9897,14 +10669,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9897 { 10669 {
9898 m_host.AddScriptLPS(1); 10670 m_host.AddScriptLPS(1);
9899 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10671 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9900 if (detectedParams == null) return; // only works on the first detected avatar 10672 if (detectedParams == null)
9901 10673 {
10674 if (m_host.ParentGroup.IsAttachment == true)
10675 {
10676 detectedParams = new DetectParams();
10677 detectedParams.Key = m_host.OwnerID;
10678 }
10679 else
10680 {
10681 return;
10682 }
10683 }
10684
9902 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10685 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9903 if (avatar != null) 10686 if (avatar != null)
9904 { 10687 {
9905 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10688 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9906 simname, pos, lookAt); 10689 simname, pos, lookAt);
9907 } 10690 }
10691
9908 ScriptSleep(1000); 10692 ScriptSleep(1000);
9909 } 10693 }
9910 10694
@@ -10028,12 +10812,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10028 10812
10029 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10813 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10030 object[] data = rules.Data; 10814 object[] data = rules.Data;
10031 for (int i = 0; i < data.Length; ++i) { 10815 for (int i = 0; i < data.Length; ++i)
10816 {
10032 int type = Convert.ToInt32(data[i++].ToString()); 10817 int type = Convert.ToInt32(data[i++].ToString());
10033 if (i >= data.Length) break; // odd number of entries => ignore the last 10818 if (i >= data.Length) break; // odd number of entries => ignore the last
10034 10819
10035 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10820 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10036 switch (type) { 10821 switch (type)
10822 {
10037 case ScriptBaseClass.CAMERA_FOCUS: 10823 case ScriptBaseClass.CAMERA_FOCUS:
10038 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10824 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10039 case ScriptBaseClass.CAMERA_POSITION: 10825 case ScriptBaseClass.CAMERA_POSITION:
@@ -10139,19 +10925,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10139 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10925 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10140 { 10926 {
10141 m_host.AddScriptLPS(1); 10927 m_host.AddScriptLPS(1);
10142 string ret = String.Empty; 10928
10143 string src1 = llBase64ToString(str1); 10929 if (str1 == String.Empty)
10144 string src2 = llBase64ToString(str2); 10930 return String.Empty;
10145 int c = 0; 10931 if (str2 == String.Empty)
10146 for (int i = 0; i < src1.Length; i++) 10932 return str1;
10933
10934 int len = str2.Length;
10935 if ((len % 4) != 0) // LL is EVIL!!!!
10147 { 10936 {
10148 ret += (char) (src1[i] ^ src2[c]); 10937 while (str2.EndsWith("="))
10938 str2 = str2.Substring(0, str2.Length - 1);
10939
10940 len = str2.Length;
10941 int mod = len % 4;
10942
10943 if (mod == 1)
10944 str2 = str2.Substring(0, str2.Length - 1);
10945 else if (mod == 2)
10946 str2 += "==";
10947 else if (mod == 3)
10948 str2 += "=";
10949 }
10149 10950
10150 c++; 10951 byte[] data1;
10151 if (c >= src2.Length) 10952 byte[] data2;
10152 c = 0; 10953 try
10954 {
10955 data1 = Convert.FromBase64String(str1);
10956 data2 = Convert.FromBase64String(str2);
10153 } 10957 }
10154 return llStringToBase64(ret); 10958 catch (Exception)
10959 {
10960 return new LSL_String(String.Empty);
10961 }
10962
10963 byte[] d2 = new Byte[data1.Length];
10964 int pos = 0;
10965
10966 if (data1.Length <= data2.Length)
10967 {
10968 Array.Copy(data2, 0, d2, 0, data1.Length);
10969 }
10970 else
10971 {
10972 while (pos < data1.Length)
10973 {
10974 len = data1.Length - pos;
10975 if (len > data2.Length)
10976 len = data2.Length;
10977
10978 Array.Copy(data2, 0, d2, pos, len);
10979 pos += len;
10980 }
10981 }
10982
10983 for (pos = 0 ; pos < data1.Length ; pos++ )
10984 data1[pos] ^= d2[pos];
10985
10986 return Convert.ToBase64String(data1);
10155 } 10987 }
10156 10988
10157 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10989 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10204,16 +11036,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10204 if (userAgent != null) 11036 if (userAgent != null)
10205 httpHeaders["User-Agent"] = userAgent; 11037 httpHeaders["User-Agent"] = userAgent;
10206 11038
11039 // See if the URL contains any header hacks
11040 string[] urlParts = url.Split(new char[] {'\n'});
11041 if (urlParts.Length > 1)
11042 {
11043 // Iterate the passed headers and parse them
11044 for (int i = 1 ; i < urlParts.Length ; i++ )
11045 {
11046 // The rest of those would be added to the body in SL.
11047 // Let's not do that.
11048 if (urlParts[i] == String.Empty)
11049 break;
11050
11051 // See if this could be a valid header
11052 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11053 if (headerParts.Length != 2)
11054 continue;
11055
11056 string headerName = headerParts[0].Trim();
11057 string headerValue = headerParts[1].Trim();
11058
11059 // Filter out headers that could be used to abuse
11060 // another system or cloak the request
11061 if (headerName.ToLower() == "x-secondlife-shard" ||
11062 headerName.ToLower() == "x-secondlife-object-name" ||
11063 headerName.ToLower() == "x-secondlife-object-key" ||
11064 headerName.ToLower() == "x-secondlife-region" ||
11065 headerName.ToLower() == "x-secondlife-local-position" ||
11066 headerName.ToLower() == "x-secondlife-local-velocity" ||
11067 headerName.ToLower() == "x-secondlife-local-rotation" ||
11068 headerName.ToLower() == "x-secondlife-owner-name" ||
11069 headerName.ToLower() == "x-secondlife-owner-key" ||
11070 headerName.ToLower() == "connection" ||
11071 headerName.ToLower() == "content-length" ||
11072 headerName.ToLower() == "from" ||
11073 headerName.ToLower() == "host" ||
11074 headerName.ToLower() == "proxy-authorization" ||
11075 headerName.ToLower() == "referer" ||
11076 headerName.ToLower() == "trailer" ||
11077 headerName.ToLower() == "transfer-encoding" ||
11078 headerName.ToLower() == "via" ||
11079 headerName.ToLower() == "authorization")
11080 continue;
11081
11082 httpHeaders[headerName] = headerValue;
11083 }
11084
11085 // Finally, strip any protocol specifier from the URL
11086 url = urlParts[0].Trim();
11087 int idx = url.IndexOf(" HTTP/");
11088 if (idx != -1)
11089 url = url.Substring(0, idx);
11090 }
11091
10207 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11092 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10208 Regex r = new Regex(authregex); 11093 Regex r = new Regex(authregex);
10209 int[] gnums = r.GetGroupNumbers(); 11094 int[] gnums = r.GetGroupNumbers();
10210 Match m = r.Match(url); 11095 Match m = r.Match(url);
10211 if (m.Success) { 11096 if (m.Success)
10212 for (int i = 1; i < gnums.Length; i++) { 11097 {
11098 for (int i = 1; i < gnums.Length; i++)
11099 {
10213 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11100 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10214 //CaptureCollection cc = g.Captures; 11101 //CaptureCollection cc = g.Captures;
10215 } 11102 }
10216 if (m.Groups.Count == 5) { 11103 if (m.Groups.Count == 5)
11104 {
10217 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11105 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10218 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11106 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10219 } 11107 }
@@ -10416,6 +11304,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10416 11304
10417 LSL_List ret = new LSL_List(); 11305 LSL_List ret = new LSL_List();
10418 UUID key = new UUID(); 11306 UUID key = new UUID();
11307
11308
10419 if (UUID.TryParse(id, out key)) 11309 if (UUID.TryParse(id, out key))
10420 { 11310 {
10421 ScenePresence av = World.GetScenePresence(key); 11311 ScenePresence av = World.GetScenePresence(key);
@@ -10433,13 +11323,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10433 ret.Add(new LSL_String("")); 11323 ret.Add(new LSL_String(""));
10434 break; 11324 break;
10435 case ScriptBaseClass.OBJECT_POS: 11325 case ScriptBaseClass.OBJECT_POS:
10436 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11326 Vector3 avpos;
11327
11328 if (av.ParentID != 0 && av.ParentPart != null)
11329 {
11330 avpos = av.OffsetPosition;
11331
11332 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11333 avpos -= sitOffset;
11334
11335 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11336 }
11337 else
11338 avpos = av.AbsolutePosition;
11339
11340 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10437 break; 11341 break;
10438 case ScriptBaseClass.OBJECT_ROT: 11342 case ScriptBaseClass.OBJECT_ROT:
10439 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11343 Quaternion avrot = av.Rotation;
11344 if (av.ParentID != 0 && av.ParentPart != null)
11345 {
11346 avrot = av.ParentPart.GetWorldRotation() * avrot;
11347 }
11348 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10440 break; 11349 break;
10441 case ScriptBaseClass.OBJECT_VELOCITY: 11350 case ScriptBaseClass.OBJECT_VELOCITY:
10442 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11351 Vector3 avvel = av.Velocity;
11352 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10443 break; 11353 break;
10444 case ScriptBaseClass.OBJECT_OWNER: 11354 case ScriptBaseClass.OBJECT_OWNER:
10445 ret.Add(new LSL_String(id)); 11355 ret.Add(new LSL_String(id));
@@ -10495,11 +11405,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10495 case ScriptBaseClass.OBJECT_NAME: 11405 case ScriptBaseClass.OBJECT_NAME:
10496 ret.Add(new LSL_String(obj.Name)); 11406 ret.Add(new LSL_String(obj.Name));
10497 break; 11407 break;
10498 case ScriptBaseClass.OBJECT_DESC: 11408 case ScriptBaseClass.OBJECT_DESC:
10499 ret.Add(new LSL_String(obj.Description)); 11409 ret.Add(new LSL_String(obj.Description));
10500 break; 11410 break;
10501 case ScriptBaseClass.OBJECT_POS: 11411 case ScriptBaseClass.OBJECT_POS:
10502 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11412 Vector3 opos = obj.AbsolutePosition;
11413 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10503 break; 11414 break;
10504 case ScriptBaseClass.OBJECT_ROT: 11415 case ScriptBaseClass.OBJECT_ROT:
10505 { 11416 {
@@ -10549,9 +11460,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10549 // The value returned in SL for normal prims is prim count 11460 // The value returned in SL for normal prims is prim count
10550 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11461 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10551 break; 11462 break;
10552 // The following 3 costs I have intentionaly coded to return zero. They are part of 11463
10553 // "Land Impact" calculations. These calculations are probably not applicable 11464 // costs below may need to be diferent for root parts, need to check
10554 // to OpenSim and are not yet complete in SL
10555 case ScriptBaseClass.OBJECT_SERVER_COST: 11465 case ScriptBaseClass.OBJECT_SERVER_COST:
10556 // The linden calculation is here 11466 // The linden calculation is here
10557 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11467 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10559,16 +11469,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10559 ret.Add(new LSL_Float(0)); 11469 ret.Add(new LSL_Float(0));
10560 break; 11470 break;
10561 case ScriptBaseClass.OBJECT_STREAMING_COST: 11471 case ScriptBaseClass.OBJECT_STREAMING_COST:
10562 // The linden calculation is here 11472 // The value returned in SL for normal prims is prim count * 0.06
10563 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11473 ret.Add(new LSL_Float(obj.StreamingCost));
10564 // The value returned in SL for normal prims looks like the prim count * 0.06
10565 ret.Add(new LSL_Float(0));
10566 break; 11474 break;
10567 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11475 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10568 // The linden calculation is here 11476 // The value returned in SL for normal prims is prim count
10569 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11477 ret.Add(new LSL_Float(obj.PhysicsCost));
10570 // The value returned in SL for normal prims looks like the prim count
10571 ret.Add(new LSL_Float(0));
10572 break; 11478 break;
10573 default: 11479 default:
10574 // Invalid or unhandled constant. 11480 // Invalid or unhandled constant.
@@ -10768,15 +11674,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10768 return result; 11674 return result;
10769 } 11675 }
10770 11676
10771 public void print(string str) 11677 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10772 { 11678 {
10773 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11679 List<SceneObjectPart> parts = GetLinkParts(link);
10774 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11680 if (parts.Count < 1)
10775 if (ossl != null) 11681 return 0;
10776 { 11682
10777 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11683 return GetNumberOfSides(parts[0]);
10778 m_log.Info("LSL print():" + str);
10779 }
10780 } 11684 }
10781 11685
10782 private string Name2Username(string name) 11686 private string Name2Username(string name)
@@ -10821,7 +11725,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10821 11725
10822 return rq.ToString(); 11726 return rq.ToString();
10823 } 11727 }
10824 11728/*
11729 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11730 {
11731 m_SayShoutCount = 0;
11732 }
11733*/
10825 private struct Tri 11734 private struct Tri
10826 { 11735 {
10827 public Vector3 p1; 11736 public Vector3 p1;
@@ -10961,9 +11870,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10961 11870
10962 ContactResult result = new ContactResult (); 11871 ContactResult result = new ContactResult ();
10963 result.ConsumerID = group.LocalId; 11872 result.ConsumerID = group.LocalId;
10964 result.Depth = intersection.distance; 11873// result.Depth = intersection.distance;
10965 result.Normal = intersection.normal; 11874 result.Normal = intersection.normal;
10966 result.Pos = intersection.ipoint; 11875 result.Pos = intersection.ipoint;
11876 result.Depth = Vector3.Mag(rayStart - result.Pos);
10967 11877
10968 contacts.Add(result); 11878 contacts.Add(result);
10969 }); 11879 });
@@ -11096,6 +12006,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11096 12006
11097 return contacts[0]; 12007 return contacts[0];
11098 } 12008 }
12009/*
12010 // not done:
12011 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12012 {
12013 ContactResult[] contacts = null;
12014 World.ForEachSOG(delegate(SceneObjectGroup group)
12015 {
12016 if (m_host.ParentGroup == group)
12017 return;
12018
12019 if (group.IsAttachment)
12020 return;
12021
12022 if(group.RootPart.PhysActor != null)
12023 return;
12024
12025 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12026 });
12027 return contacts;
12028 }
12029*/
11099 12030
11100 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12031 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11101 { 12032 {
@@ -11137,32 +12068,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11137 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12068 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11138 12069
11139 12070
11140 if (checkTerrain) 12071 if (World.SuportsRayCastFiltered())
11141 { 12072 {
11142 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12073 if (dist == 0)
11143 if (groundContact != null) 12074 return list;
11144 results.Add((ContactResult)groundContact);
11145 }
11146 12075
11147 if (checkAgents) 12076 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11148 { 12077 if (checkTerrain)
11149 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12078 rayfilter |= RayFilterFlags.land;
11150 foreach (ContactResult r in agentHits) 12079// if (checkAgents)
11151 results.Add(r); 12080// rayfilter |= RayFilterFlags.agent;
11152 } 12081 if (checkPhysical)
12082 rayfilter |= RayFilterFlags.physical;
12083 if (checkNonPhysical)
12084 rayfilter |= RayFilterFlags.nonphysical;
12085 if (detectPhantom)
12086 rayfilter |= RayFilterFlags.LSLPhanton;
12087
12088 Vector3 direction = dir * ( 1/dist);
12089
12090 if(rayfilter == 0)
12091 {
12092 list.Add(new LSL_Integer(0));
12093 return list;
12094 }
11153 12095
11154 if (checkPhysical || checkNonPhysical || detectPhantom) 12096 // get some more contacts to sort ???
12097 int physcount = 4 * count;
12098 if (physcount > 20)
12099 physcount = 20;
12100
12101 object physresults;
12102 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12103
12104 if (physresults == null)
12105 {
12106 list.Add(new LSL_Integer(-3)); // timeout error
12107 return list;
12108 }
12109
12110 results = (List<ContactResult>)physresults;
12111
12112 // for now physics doesn't detect sitted avatars so do it outside physics
12113 if (checkAgents)
12114 {
12115 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12116 foreach (ContactResult r in agentHits)
12117 results.Add(r);
12118 }
12119
12120 // TODO: Replace this with a better solution. ObjectIntersection can only
12121 // detect nonphysical phantoms. They are detected by virtue of being
12122 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12123 // physicsl phantoms as done by the physics scene
12124 // We don't want anything else but phantoms here.
12125 if (detectPhantom)
12126 {
12127 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12128 foreach (ContactResult r in objectHits)
12129 results.Add(r);
12130 }
12131 }
12132 else
11155 { 12133 {
11156 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12134 if (checkTerrain)
11157 foreach (ContactResult r in objectHits) 12135 {
11158 results.Add(r); 12136 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12137 if (groundContact != null)
12138 results.Add((ContactResult)groundContact);
12139 }
12140
12141 if (checkAgents)
12142 {
12143 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12144 foreach (ContactResult r in agentHits)
12145 results.Add(r);
12146 }
12147
12148 if (checkPhysical || checkNonPhysical || detectPhantom)
12149 {
12150 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12151 foreach (ContactResult r in objectHits)
12152 results.Add(r);
12153 }
11159 } 12154 }
11160 12155
11161 results.Sort(delegate(ContactResult a, ContactResult b) 12156 results.Sort(delegate(ContactResult a, ContactResult b)
11162 { 12157 {
11163 return a.Depth.CompareTo(b.Depth); 12158 return a.Depth.CompareTo(b.Depth);
11164 }); 12159 });
11165 12160
11166 int values = 0; 12161 int values = 0;
11167 SceneObjectGroup thisgrp = m_host.ParentGroup; 12162 SceneObjectGroup thisgrp = m_host.ParentGroup;
11168 12163
@@ -11255,7 +12250,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11255 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12250 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11256 if (!isAccount) return 0; 12251 if (!isAccount) return 0;
11257 if (estate.HasAccess(id)) return 1; 12252 if (estate.HasAccess(id)) return 1;
11258 if (estate.IsBanned(id)) 12253 if (estate.IsBanned(id, World.GetUserFlags(id)))
11259 estate.RemoveBan(id); 12254 estate.RemoveBan(id);
11260 estate.AddEstateUser(id); 12255 estate.AddEstateUser(id);
11261 break; 12256 break;
@@ -11274,14 +12269,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11274 break; 12269 break;
11275 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12270 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11276 if (!isAccount) return 0; 12271 if (!isAccount) return 0;
11277 if (estate.IsBanned(id)) return 1; 12272 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11278 EstateBan ban = new EstateBan(); 12273 EstateBan ban = new EstateBan();
11279 ban.EstateID = estate.EstateID; 12274 ban.EstateID = estate.EstateID;
11280 ban.BannedUserID = id; 12275 ban.BannedUserID = id;
11281 estate.AddBan(ban); 12276 estate.AddBan(ban);
11282 break; 12277 break;
11283 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12278 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11284 if (!isAccount || !estate.IsBanned(id)) return 0; 12279 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11285 estate.RemoveBan(id); 12280 estate.RemoveBan(id);
11286 break; 12281 break;
11287 default: return 0; 12282 default: return 0;
@@ -11310,7 +12305,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11310 return 16384; 12305 return 16384;
11311 } 12306 }
11312 12307
11313 public LSL_Integer llGetUsedMemory() 12308 public virtual LSL_Integer llGetUsedMemory()
11314 { 12309 {
11315 m_host.AddScriptLPS(1); 12310 m_host.AddScriptLPS(1);
11316 // The value returned for LSO scripts in SL 12311 // The value returned for LSO scripts in SL
@@ -11338,7 +12333,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11338 public void llSetSoundQueueing(int queue) 12333 public void llSetSoundQueueing(int queue)
11339 { 12334 {
11340 m_host.AddScriptLPS(1); 12335 m_host.AddScriptLPS(1);
11341 NotImplemented("llSetSoundQueueing");
11342 } 12336 }
11343 12337
11344 public void llCollisionSprite(string impact_sprite) 12338 public void llCollisionSprite(string impact_sprite)
@@ -11350,10 +12344,712 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11350 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12344 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11351 { 12345 {
11352 m_host.AddScriptLPS(1); 12346 m_host.AddScriptLPS(1);
11353 NotImplemented("llGodLikeRezObject"); 12347
12348 if (!World.Permissions.IsGod(m_host.OwnerID))
12349 NotImplemented("llGodLikeRezObject");
12350
12351 AssetBase rezAsset = World.AssetService.Get(inventory);
12352 if (rezAsset == null)
12353 {
12354 llSay(0, "Asset not found");
12355 return;
12356 }
12357
12358 SceneObjectGroup group = null;
12359
12360 try
12361 {
12362 string xmlData = Utils.BytesToString(rezAsset.Data);
12363 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12364 }
12365 catch
12366 {
12367 llSay(0, "Asset not found");
12368 return;
12369 }
12370
12371 if (group == null)
12372 {
12373 llSay(0, "Asset not found");
12374 return;
12375 }
12376
12377 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12378 group.RootPart.AttachOffset = group.AbsolutePosition;
12379
12380 group.ResetIDs();
12381
12382 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12383 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12384 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12385 group.ScheduleGroupForFullUpdate();
12386
12387 // objects rezzed with this method are die_at_edge by default.
12388 group.RootPart.SetDieAtEdge(true);
12389
12390 group.ResumeScripts();
12391
12392 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12393 "object_rez", new Object[] {
12394 new LSL_String(
12395 group.RootPart.UUID.ToString()) },
12396 new DetectParams[0]));
12397 }
12398
12399 public LSL_String llTransferLindenDollars(string destination, int amount)
12400 {
12401 UUID txn = UUID.Random();
12402
12403 Util.FireAndForget(delegate(object x)
12404 {
12405 int replycode = 0;
12406 string replydata = destination + "," + amount.ToString();
12407
12408 try
12409 {
12410 TaskInventoryItem item = m_item;
12411 if (item == null)
12412 {
12413 replydata = "SERVICE_ERROR";
12414 return;
12415 }
12416
12417 m_host.AddScriptLPS(1);
12418
12419 if (item.PermsGranter == UUID.Zero)
12420 {
12421 replydata = "MISSING_PERMISSION_DEBIT";
12422 return;
12423 }
12424
12425 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12426 {
12427 replydata = "MISSING_PERMISSION_DEBIT";
12428 return;
12429 }
12430
12431 UUID toID = new UUID();
12432
12433 if (!UUID.TryParse(destination, out toID))
12434 {
12435 replydata = "INVALID_AGENT";
12436 return;
12437 }
12438
12439 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12440
12441 if (money == null)
12442 {
12443 replydata = "TRANSFERS_DISABLED";
12444 return;
12445 }
12446
12447 bool result = money.ObjectGiveMoney(
12448 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12449
12450 if (result)
12451 {
12452 replycode = 1;
12453 return;
12454 }
12455
12456 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12457 }
12458 finally
12459 {
12460 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12461 "transaction_result", new Object[] {
12462 new LSL_String(txn.ToString()),
12463 new LSL_Integer(replycode),
12464 new LSL_String(replydata) },
12465 new DetectParams[0]));
12466 }
12467 });
12468
12469 return txn.ToString();
11354 } 12470 }
11355 12471
11356 #endregion 12472 #endregion
12473
12474 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12475 {
12476 SceneObjectGroup group = m_host.ParentGroup;
12477
12478 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12479 return;
12480 if (group.IsAttachment)
12481 return;
12482
12483 if (frames.Data.Length > 0) // We are getting a new motion
12484 {
12485 if (group.RootPart.KeyframeMotion != null)
12486 group.RootPart.KeyframeMotion.Stop();
12487 group.RootPart.KeyframeMotion = null;
12488
12489 int idx = 0;
12490
12491 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12492 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12493
12494 while (idx < options.Data.Length)
12495 {
12496 int option = (int)options.GetLSLIntegerItem(idx++);
12497 int remain = options.Data.Length - idx;
12498
12499 switch (option)
12500 {
12501 case ScriptBaseClass.KFM_MODE:
12502 if (remain < 1)
12503 break;
12504 int modeval = (int)options.GetLSLIntegerItem(idx++);
12505 switch(modeval)
12506 {
12507 case ScriptBaseClass.KFM_FORWARD:
12508 mode = KeyframeMotion.PlayMode.Forward;
12509 break;
12510 case ScriptBaseClass.KFM_REVERSE:
12511 mode = KeyframeMotion.PlayMode.Reverse;
12512 break;
12513 case ScriptBaseClass.KFM_LOOP:
12514 mode = KeyframeMotion.PlayMode.Loop;
12515 break;
12516 case ScriptBaseClass.KFM_PING_PONG:
12517 mode = KeyframeMotion.PlayMode.PingPong;
12518 break;
12519 }
12520 break;
12521 case ScriptBaseClass.KFM_DATA:
12522 if (remain < 1)
12523 break;
12524 int dataval = (int)options.GetLSLIntegerItem(idx++);
12525 data = (KeyframeMotion.DataFormat)dataval;
12526 break;
12527 }
12528 }
12529
12530 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12531
12532 idx = 0;
12533
12534 int elemLength = 2;
12535 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12536 elemLength = 3;
12537
12538 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12539 while (idx < frames.Data.Length)
12540 {
12541 int remain = frames.Data.Length - idx;
12542
12543 if (remain < elemLength)
12544 break;
12545
12546 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12547 frame.Position = null;
12548 frame.Rotation = null;
12549
12550 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12551 {
12552 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12553 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12554 }
12555 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12556 {
12557 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12558 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12559 }
12560
12561 float tempf = (float)frames.GetLSLFloatItem(idx++);
12562 frame.TimeMS = (int)(tempf * 1000.0f);
12563
12564 keyframes.Add(frame);
12565 }
12566
12567 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12568 group.RootPart.KeyframeMotion.Start();
12569 }
12570 else
12571 {
12572 if (group.RootPart.KeyframeMotion == null)
12573 return;
12574
12575 if (options.Data.Length == 0)
12576 {
12577 group.RootPart.KeyframeMotion.Stop();
12578 return;
12579 }
12580
12581 int code = (int)options.GetLSLIntegerItem(0);
12582
12583 int idx = 0;
12584
12585 while (idx < options.Data.Length)
12586 {
12587 int option = (int)options.GetLSLIntegerItem(idx++);
12588 int remain = options.Data.Length - idx;
12589
12590 switch (option)
12591 {
12592 case ScriptBaseClass.KFM_COMMAND:
12593 int cmd = (int)options.GetLSLIntegerItem(idx++);
12594 switch (cmd)
12595 {
12596 case ScriptBaseClass.KFM_CMD_PLAY:
12597 group.RootPart.KeyframeMotion.Start();
12598 break;
12599 case ScriptBaseClass.KFM_CMD_STOP:
12600 group.RootPart.KeyframeMotion.Stop();
12601 break;
12602 case ScriptBaseClass.KFM_CMD_PAUSE:
12603 group.RootPart.KeyframeMotion.Pause();
12604 break;
12605 }
12606 break;
12607 }
12608 }
12609 }
12610 }
12611
12612 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules)
12613 {
12614 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12615
12616 int idx = 0;
12617
12618 bool positionChanged = false;
12619 Vector3 finalPos = Vector3.Zero;
12620
12621 try
12622 {
12623 while (idx < rules.Length)
12624 {
12625 int code = rules.GetLSLIntegerItem(idx++);
12626
12627 int remain = rules.Length - idx;
12628
12629 switch (code)
12630 {
12631 case (int)ScriptBaseClass.PRIM_POSITION:
12632 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12633 {
12634 if (remain < 1)
12635 return null;
12636
12637 LSL_Vector v;
12638 v = rules.GetVector3Item(idx++);
12639
12640 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12641 if (part == null)
12642 break;
12643
12644 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12645 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12646 if (part.LinkNum > 1)
12647 {
12648 localRot = GetPartLocalRot(part);
12649 localPos = GetPartLocalPos(part);
12650 }
12651
12652 v -= localPos;
12653 v /= localRot;
12654
12655 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12656
12657 v = v + 2 * sitOffset;
12658
12659 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12660 av.SendAvatarDataToAllAgents();
12661
12662 }
12663 break;
12664
12665 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12666 case (int)ScriptBaseClass.PRIM_ROTATION:
12667 {
12668 if (remain < 1)
12669 return null;
12670
12671 LSL_Rotation r;
12672 r = rules.GetQuaternionItem(idx++);
12673
12674 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12675 if (part == null)
12676 break;
12677
12678 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12679 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12680
12681 if (part.LinkNum > 1)
12682 localRot = GetPartLocalRot(part);
12683
12684 r = r * llGetRootRotation() / localRot;
12685 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12686 av.SendAvatarDataToAllAgents();
12687 }
12688 break;
12689
12690 // parse rest doing nothing but number of parameters error check
12691 case (int)ScriptBaseClass.PRIM_SIZE:
12692 case (int)ScriptBaseClass.PRIM_MATERIAL:
12693 case (int)ScriptBaseClass.PRIM_PHANTOM:
12694 case (int)ScriptBaseClass.PRIM_PHYSICS:
12695 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12696 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12697 case (int)ScriptBaseClass.PRIM_NAME:
12698 case (int)ScriptBaseClass.PRIM_DESC:
12699 if (remain < 1)
12700 return null;
12701 idx++;
12702 break;
12703
12704 case (int)ScriptBaseClass.PRIM_GLOW:
12705 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12706 case (int)ScriptBaseClass.PRIM_TEXGEN:
12707 if (remain < 2)
12708 return null;
12709 idx += 2;
12710 break;
12711
12712 case (int)ScriptBaseClass.PRIM_TYPE:
12713 if (remain < 3)
12714 return null;
12715 code = (int)rules.GetLSLIntegerItem(idx++);
12716 remain = rules.Length - idx;
12717 switch (code)
12718 {
12719 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12720 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12721 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12722 if (remain < 6)
12723 return null;
12724 idx += 6;
12725 break;
12726
12727 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12728 if (remain < 5)
12729 return null;
12730 idx += 5;
12731 break;
12732
12733 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12734 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12735 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12736 if (remain < 11)
12737 return null;
12738 idx += 11;
12739 break;
12740
12741 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12742 if (remain < 2)
12743 return null;
12744 idx += 2;
12745 break;
12746 }
12747 break;
12748
12749 case (int)ScriptBaseClass.PRIM_COLOR:
12750 case (int)ScriptBaseClass.PRIM_TEXT:
12751 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12752 case (int)ScriptBaseClass.PRIM_OMEGA:
12753 if (remain < 3)
12754 return null;
12755 idx += 3;
12756 break;
12757
12758 case (int)ScriptBaseClass.PRIM_TEXTURE:
12759 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12760 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12761 if (remain < 5)
12762 return null;
12763 idx += 5;
12764 break;
12765
12766 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12767 if (remain < 7)
12768 return null;
12769
12770 idx += 7;
12771 break;
12772
12773 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12774 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12775 return null;
12776
12777 return rules.GetSublist(idx, -1);
12778 }
12779 }
12780 }
12781
12782 finally
12783 {
12784 if (positionChanged)
12785 {
12786 av.OffsetPosition = finalPos;
12787// av.SendAvatarDataToAllAgents();
12788 av.SendTerseUpdateToAllClients();
12789 positionChanged = false;
12790 }
12791 }
12792 return null;
12793 }
12794
12795 public void GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12796 {
12797 // avatars case
12798 // replies as SL wiki
12799
12800// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12801 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12802
12803 int idx = 0;
12804 while (idx < rules.Length)
12805 {
12806 int code = (int)rules.GetLSLIntegerItem(idx++);
12807 int remain = rules.Length - idx;
12808
12809 switch (code)
12810 {
12811 case (int)ScriptBaseClass.PRIM_MATERIAL:
12812 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12813 break;
12814
12815 case (int)ScriptBaseClass.PRIM_PHYSICS:
12816 res.Add(new LSL_Integer(0));
12817 break;
12818
12819 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12820 res.Add(new LSL_Integer(0));
12821 break;
12822
12823 case (int)ScriptBaseClass.PRIM_PHANTOM:
12824 res.Add(new LSL_Integer(0));
12825 break;
12826
12827 case (int)ScriptBaseClass.PRIM_POSITION:
12828
12829 Vector3 pos = avatar.OffsetPosition;
12830
12831 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12832 pos -= sitOffset;
12833
12834 if( sitPart != null)
12835 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12836
12837 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12838 break;
12839
12840 case (int)ScriptBaseClass.PRIM_SIZE:
12841 // as in llGetAgentSize above
12842 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12843 break;
12844
12845 case (int)ScriptBaseClass.PRIM_ROTATION:
12846 Quaternion rot = avatar.Rotation;
12847 if (sitPart != null)
12848 {
12849 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12850 }
12851
12852 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12853 break;
12854
12855 case (int)ScriptBaseClass.PRIM_TYPE:
12856 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12857 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12858 res.Add(new LSL_Vector(0f,1.0f,0f));
12859 res.Add(new LSL_Float(0.0f));
12860 res.Add(new LSL_Vector(0, 0, 0));
12861 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12862 res.Add(new LSL_Vector(0, 0, 0));
12863 break;
12864
12865 case (int)ScriptBaseClass.PRIM_TEXTURE:
12866 if (remain < 1)
12867 return;
12868
12869 int face = (int)rules.GetLSLIntegerItem(idx++);
12870 if (face == ScriptBaseClass.ALL_SIDES)
12871 {
12872 for (face = 0; face < 21; face++)
12873 {
12874 res.Add(new LSL_String(""));
12875 res.Add(new LSL_Vector(0,0,0));
12876 res.Add(new LSL_Vector(0,0,0));
12877 res.Add(new LSL_Float(0.0));
12878 }
12879 }
12880 else
12881 {
12882 if (face >= 0 && face < 21)
12883 {
12884 res.Add(new LSL_String(""));
12885 res.Add(new LSL_Vector(0,0,0));
12886 res.Add(new LSL_Vector(0,0,0));
12887 res.Add(new LSL_Float(0.0));
12888 }
12889 }
12890 break;
12891
12892 case (int)ScriptBaseClass.PRIM_COLOR:
12893 if (remain < 1)
12894 return;
12895
12896 face = (int)rules.GetLSLIntegerItem(idx++);
12897
12898 if (face == ScriptBaseClass.ALL_SIDES)
12899 {
12900 for (face = 0; face < 21; face++)
12901 {
12902 res.Add(new LSL_Vector(0,0,0));
12903 res.Add(new LSL_Float(0));
12904 }
12905 }
12906 else
12907 {
12908 res.Add(new LSL_Vector(0,0,0));
12909 res.Add(new LSL_Float(0));
12910 }
12911 break;
12912
12913 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12914 if (remain < 1)
12915 return;
12916 face = (int)rules.GetLSLIntegerItem(idx++);
12917
12918 if (face == ScriptBaseClass.ALL_SIDES)
12919 {
12920 for (face = 0; face < 21; face++)
12921 {
12922 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12923 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12924 }
12925 }
12926 else
12927 {
12928 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12929 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12930 }
12931 break;
12932
12933 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12934 if (remain < 1)
12935 return;
12936 face = (int)rules.GetLSLIntegerItem(idx++);
12937
12938 if (face == ScriptBaseClass.ALL_SIDES)
12939 {
12940 for (face = 0; face < 21; face++)
12941 {
12942 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12943 }
12944 }
12945 else
12946 {
12947 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12948 }
12949 break;
12950
12951 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12952 res.Add(new LSL_Integer(0));
12953 res.Add(new LSL_Integer(0));// softness
12954 res.Add(new LSL_Float(0.0f)); // gravity
12955 res.Add(new LSL_Float(0.0f)); // friction
12956 res.Add(new LSL_Float(0.0f)); // wind
12957 res.Add(new LSL_Float(0.0f)); // tension
12958 res.Add(new LSL_Vector(0f,0f,0f));
12959 break;
12960
12961 case (int)ScriptBaseClass.PRIM_TEXGEN:
12962 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
12963 if (remain < 1)
12964 return;
12965 face = (int)rules.GetLSLIntegerItem(idx++);
12966
12967 if (face == ScriptBaseClass.ALL_SIDES)
12968 {
12969 for (face = 0; face < 21; face++)
12970 {
12971 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
12972 }
12973 }
12974 else
12975 {
12976 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
12977 }
12978 break;
12979
12980 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12981 res.Add(new LSL_Integer(0));
12982 res.Add(new LSL_Vector(0f,0f,0f));
12983 res.Add(new LSL_Float(0f)); // intensity
12984 res.Add(new LSL_Float(0f)); // radius
12985 res.Add(new LSL_Float(0f)); // falloff
12986 break;
12987
12988 case (int)ScriptBaseClass.PRIM_GLOW:
12989 if (remain < 1)
12990 return;
12991 face = (int)rules.GetLSLIntegerItem(idx++);
12992
12993 if (face == ScriptBaseClass.ALL_SIDES)
12994 {
12995 for (face = 0; face < 21; face++)
12996 {
12997 res.Add(new LSL_Float(0f));
12998 }
12999 }
13000 else
13001 {
13002 res.Add(new LSL_Float(0f));
13003 }
13004 break;
13005
13006 case (int)ScriptBaseClass.PRIM_TEXT:
13007 res.Add(new LSL_String(""));
13008 res.Add(new LSL_Vector(0f,0f,0f));
13009 res.Add(new LSL_Float(1.0f));
13010 break;
13011
13012 case (int)ScriptBaseClass.PRIM_NAME:
13013 res.Add(new LSL_String(avatar.Name));
13014 break;
13015
13016 case (int)ScriptBaseClass.PRIM_DESC:
13017 res.Add(new LSL_String(""));
13018 break;
13019
13020 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13021 Quaternion lrot = avatar.Rotation;
13022
13023 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13024 {
13025 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13026 }
13027 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13028 break;
13029
13030 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13031 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13032 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13033 lpos -= lsitOffset;
13034
13035 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13036 {
13037 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13038 }
13039 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13040 break;
13041
13042 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13043 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13044 return;
13045 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
13046 LSL_List new_rules = rules.GetSublist(idx, -1);
13047
13048 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
13049 return;
13050 }
13051 }
13052 }
11357 } 13053 }
11358 13054
11359 public class NotecardCache 13055 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 927f37c..43cfea2 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 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_ScriptEngine = ScriptEngine; 146 m_ScriptEngine = ScriptEngine;
146 m_host = host; 147 m_host = host;
147 m_item = item; 148 m_item = item;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -206,7 +208,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
206 208
207 internal void OSSLError(string msg) 209 internal void OSSLError(string msg)
208 { 210 {
209 throw new Exception("OSSL Runtime Error: " + msg); 211 if (m_debuggerSafe)
212 {
213 OSSLShoutError(msg);
214 }
215 else
216 {
217 throw new Exception("OSSL Runtime Error: " + msg);
218 }
210 } 219 }
211 220
212 /// <summary> 221 /// <summary>
@@ -914,18 +923,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
914 if (target != null) 923 if (target != null)
915 { 924 {
916 UUID animID=UUID.Zero; 925 UUID animID=UUID.Zero;
917 lock (m_host.TaskInventory) 926 m_host.TaskInventory.LockItemsForRead(true);
927 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
918 { 928 {
919 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 929 if (inv.Value.Name == animation)
920 { 930 {
921 if (inv.Value.Name == animation) 931 if (inv.Value.Type == (int)AssetType.Animation)
922 { 932 animID = inv.Value.AssetID;
923 if (inv.Value.Type == (int)AssetType.Animation) 933 continue;
924 animID = inv.Value.AssetID;
925 continue;
926 }
927 } 934 }
928 } 935 }
936 m_host.TaskInventory.LockItemsForRead(false);
929 if (animID == UUID.Zero) 937 if (animID == UUID.Zero)
930 target.Animator.AddAnimation(animation, m_host.UUID); 938 target.Animator.AddAnimation(animation, m_host.UUID);
931 else 939 else
@@ -966,6 +974,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
966 else 974 else
967 animID = UUID.Zero; 975 animID = UUID.Zero;
968 } 976 }
977 m_host.TaskInventory.LockItemsForRead(false);
969 978
970 if (animID == UUID.Zero) 979 if (animID == UUID.Zero)
971 target.Animator.RemoveAnimation(animation); 980 target.Animator.RemoveAnimation(animation);
@@ -1799,6 +1808,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1799 1808
1800 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1809 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1801 { 1810 {
1811 m_host.TaskInventory.LockItemsForRead(true);
1802 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1812 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1803 { 1813 {
1804 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1814 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1806,6 +1816,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1806 assetID = item.AssetID; 1816 assetID = item.AssetID;
1807 } 1817 }
1808 } 1818 }
1819 m_host.TaskInventory.LockItemsForRead(false);
1809 } 1820 }
1810 1821
1811 if (assetID == UUID.Zero) 1822 if (assetID == UUID.Zero)
@@ -2280,7 +2291,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2280 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2291 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2281 m_host.AddScriptLPS(1); 2292 m_host.AddScriptLPS(1);
2282 2293
2283 return NpcCreate(firstname, lastname, position, notecard, false, false); 2294 return NpcCreate(firstname, lastname, position, notecard, true, false);
2284 } 2295 }
2285 2296
2286 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2297 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2291,24 +2302,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2291 return NpcCreate( 2302 return NpcCreate(
2292 firstname, lastname, position, notecard, 2303 firstname, lastname, position, notecard,
2293 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2304 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2294 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2305 false);
2306// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2295 } 2307 }
2296 2308
2297 private LSL_Key NpcCreate( 2309 private LSL_Key NpcCreate(
2298 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2310 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2299 { 2311 {
2312 if (!owned)
2313 OSSLError("Unowned NPCs are unsupported");
2314
2315 string groupTitle = String.Empty;
2316
2317 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2318 return new LSL_Key(UUID.Zero.ToString());
2319
2320 if (firstname != String.Empty || lastname != String.Empty)
2321 {
2322 if (firstname != "Shown outfit:")
2323 groupTitle = "- NPC -";
2324 }
2325
2300 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2326 INPCModule module = World.RequestModuleInterface<INPCModule>();
2301 if (module != null) 2327 if (module != null)
2302 { 2328 {
2303 AvatarAppearance appearance = null; 2329 AvatarAppearance appearance = null;
2304 2330
2305 UUID id; 2331// UUID id;
2306 if (UUID.TryParse(notecard, out id)) 2332// if (UUID.TryParse(notecard, out id))
2307 { 2333// {
2308 ScenePresence clonePresence = World.GetScenePresence(id); 2334// ScenePresence clonePresence = World.GetScenePresence(id);
2309 if (clonePresence != null) 2335// if (clonePresence != null)
2310 appearance = clonePresence.Appearance; 2336// appearance = clonePresence.Appearance;
2311 } 2337// }
2312 2338
2313 if (appearance == null) 2339 if (appearance == null)
2314 { 2340 {
@@ -2336,6 +2362,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2336 World, 2362 World,
2337 appearance); 2363 appearance);
2338 2364
2365 ScenePresence sp;
2366 if (World.TryGetScenePresence(x, out sp))
2367 {
2368 sp.Grouptitle = groupTitle;
2369 sp.SendAvatarDataToAllAgents();
2370 }
2339 return new LSL_Key(x.ToString()); 2371 return new LSL_Key(x.ToString());
2340 } 2372 }
2341 2373
@@ -2635,16 +2667,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2635 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2667 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2636 m_host.AddScriptLPS(1); 2668 m_host.AddScriptLPS(1);
2637 2669
2638 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2670 ManualResetEvent ev = new ManualResetEvent(false);
2639 if (module != null)
2640 {
2641 UUID npcId = new UUID(npc.m_string);
2642 2671
2643 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2672 Util.FireAndForget(delegate(object x) {
2644 return; 2673 try
2674 {
2675 INPCModule module = World.RequestModuleInterface<INPCModule>();
2676 if (module != null)
2677 {
2678 UUID npcId = new UUID(npc.m_string);
2645 2679
2646 module.DeleteNPC(npcId, World); 2680 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2647 } 2681 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2682 {
2683 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2684 return;
2685 }
2686
2687 module.DeleteNPC(npcId, World);
2688 }
2689 }
2690 finally
2691 {
2692 ev.Set();
2693 }
2694 });
2695 ev.WaitOne();
2648 } 2696 }
2649 2697
2650 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2698 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3348,4 +3396,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3348 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString()); 3396 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString());
3349 } 3397 }
3350 } 3398 }
3351} \ No newline at end of file 3399}
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 }