aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api')
-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.cs3174
-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
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs29
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs56
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
15 files changed, 2893 insertions, 808 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 fceae02..0ed1ccb 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)
@@ -448,31 +544,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
448 544
449 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 545 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
450 546
451 /// <summary> 547 // Utility function for llRot2Euler
452 /// Convert an LSL rotation to a Euler vector. 548
453 /// </summary> 549 // normalize an angle between -PI and PI (-180 to +180 degrees)
454 /// <remarks> 550 protected double NormalizeAngle(double angle)
455 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
456 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
457 /// </remarks>
458 /// <param name="r"></param>
459 /// <returns></returns>
460 public LSL_Vector llRot2Euler(LSL_Rotation r)
461 { 551 {
462 m_host.AddScriptLPS(1); 552 if (angle > -Math.PI && angle < Math.PI)
553 return angle;
463 554
464 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 555 int numPis = (int)(Math.PI / angle);
465 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 556 double remainder = angle - Math.PI * numPis;
466 if (m == 0.0) return new LSL_Vector(); 557 if (numPis % 2 == 1)
467 double x = Math.Atan2(-v.y, v.z); 558 return Math.PI - angle;
468 double sin = v.x / m; 559 return remainder;
469 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 560 }
470 double y = Math.Asin(sin);
471 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
472 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)));
473 double z = Math.Atan2(v.y, v.x);
474 561
475 return new LSL_Vector(x, y, z); 562 public LSL_Vector llRot2Euler(LSL_Rotation q1)
563 {
564 m_host.AddScriptLPS(1);
565 LSL_Vector eul = new LSL_Vector();
566
567 double sqw = q1.s*q1.s;
568 double sqx = q1.x*q1.x;
569 double sqy = q1.z*q1.z;
570 double sqz = q1.y*q1.y;
571 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
572 double test = q1.x*q1.z + q1.y*q1.s;
573 if (test > 0.4999*unit) { // singularity at north pole
574 eul.z = 2 * Math.Atan2(q1.x,q1.s);
575 eul.y = Math.PI/2;
576 eul.x = 0;
577 return eul;
578 }
579 if (test < -0.4999*unit) { // singularity at south pole
580 eul.z = -2 * Math.Atan2(q1.x,q1.s);
581 eul.y = -Math.PI/2;
582 eul.x = 0;
583 return eul;
584 }
585 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
586 eul.y = Math.Asin(2*test/unit);
587 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
588 return eul;
476 } 589 }
477 590
478 /* From wiki: 591 /* From wiki:
@@ -525,18 +638,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
525 m_host.AddScriptLPS(1); 638 m_host.AddScriptLPS(1);
526 639
527 double x,y,z,s; 640 double x,y,z,s;
528 641 v.x *= 0.5;
529 double c1 = Math.Cos(v.x * 0.5); 642 v.y *= 0.5;
530 double c2 = Math.Cos(v.y * 0.5); 643 v.z *= 0.5;
531 double c3 = Math.Cos(v.z * 0.5); 644 double c1 = Math.Cos(v.x);
532 double s1 = Math.Sin(v.x * 0.5); 645 double c2 = Math.Cos(v.y);
533 double s2 = Math.Sin(v.y * 0.5); 646 double c1c2 = c1 * c2;
534 double s3 = Math.Sin(v.z * 0.5); 647 double s1 = Math.Sin(v.x);
535 648 double s2 = Math.Sin(v.y);
536 x = s1 * c2 * c3 + c1 * s2 * s3; 649 double s1s2 = s1 * s2;
537 y = c1 * s2 * c3 - s1 * c2 * s3; 650 double c1s2 = c1 * s2;
538 z = s1 * s2 * c3 + c1 * c2 * s3; 651 double s1c2 = s1 * c2;
539 s = c1 * c2 * c3 - s1 * s2 * s3; 652 double c3 = Math.Cos(v.z);
653 double s3 = Math.Sin(v.z);
654
655 x = s1c2 * c3 + c1s2 * s3;
656 y = c1s2 * c3 - s1c2 * s3;
657 z = s1s2 * c3 + c1c2 * s3;
658 s = c1c2 * c3 - s1s2 * s3;
540 659
541 return new LSL_Rotation(x, y, z, s); 660 return new LSL_Rotation(x, y, z, s);
542 } 661 }
@@ -674,77 +793,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
674 { 793 {
675 //A and B should both be normalized 794 //A and B should both be normalized
676 m_host.AddScriptLPS(1); 795 m_host.AddScriptLPS(1);
677 LSL_Rotation rotBetween; 796 /* This method is more accurate than the SL one, and thus causes problems
678 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 797 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
679 // continue calculation. 798
680 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 799 double dotProduct = LSL_Vector.Dot(a, b);
800 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
801 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
802 double angle = Math.Acos(dotProduct / magProduct);
803 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
804 double s = Math.Sin(angle / 2);
805
806 double x = axis.x * s;
807 double y = axis.y * s;
808 double z = axis.z * s;
809 double w = Math.Cos(angle / 2);
810
811 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
812 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
813
814 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
815 */
816
817 // This method mimics the 180 errors found in SL
818 // See www.euclideanspace.com... angleBetween
819 LSL_Vector vec_a = a;
820 LSL_Vector vec_b = b;
821
822 // Eliminate zero length
823 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
824 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
825 if (vec_a_mag < 0.00001 ||
826 vec_b_mag < 0.00001)
681 { 827 {
682 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 828 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
683 } 829 }
684 else 830
831 // Normalize
832 vec_a = llVecNorm(vec_a);
833 vec_b = llVecNorm(vec_b);
834
835 // Calculate axis and rotation angle
836 LSL_Vector axis = vec_a % vec_b;
837 LSL_Float cos_theta = vec_a * vec_b;
838
839 // Check if parallel
840 if (cos_theta > 0.99999)
685 { 841 {
686 a = LSL_Vector.Norm(a); 842 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
687 b = LSL_Vector.Norm(b); 843 }
688 double dotProduct = LSL_Vector.Dot(a, b); 844
689 // There are two degenerate cases possible. These are for vectors 180 or 845 // Check if anti-parallel
690 // 0 degrees apart. These have to be detected and handled individually. 846 else if (cos_theta < -0.99999)
691 // 847 {
692 // Check for vectors 180 degrees apart. 848 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
693 // A dot product of -1 would mean the angle between vectors is 180 degrees. 849 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
694 if (dotProduct < -0.9999999f) 850 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
695 { 851 }
696 // First assume X axis is orthogonal to the vectors. 852 else // other rotation
697 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 853 {
698 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 854 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
699 // Check for near zero vector. A very small non-zero number here will create 855 axis = llVecNorm(axis);
700 // a rotation in an undesired direction. 856 double x, y, z, s, t;
701 if (LSL_Vector.Mag(orthoVector) > 0.0001) 857 s = Math.Cos(theta);
702 { 858 t = Math.Sin(theta);
703 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 859 x = axis.x * t;
704 } 860 y = axis.y * t;
705 // If the magnitude of the vector was near zero, then assume the X axis is not 861 z = axis.z * t;
706 // orthogonal and use the Z axis instead. 862 return new LSL_Rotation(x,y,z,s);
707 else
708 {
709 // Set 180 z rotation.
710 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
711 }
712 }
713 // Check for parallel vectors.
714 // A dot product of 1 would mean the angle between vectors is 0 degrees.
715 else if (dotProduct > 0.9999999f)
716 {
717 // Set zero rotation.
718 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
719 }
720 else
721 {
722 // All special checks have been performed so get the axis of rotation.
723 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
724 // Quarternion s value is the length of the unit vector + dot product.
725 double qs = 1.0 + dotProduct;
726 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
727 // Normalize the rotation.
728 double mag = LSL_Rotation.Mag(rotBetween);
729 // We shouldn't have to worry about a divide by zero here. The qs value will be
730 // non-zero because we already know if we're here, then the dotProduct is not -1 so
731 // qs will not be zero. Also, we've already handled the input vectors being zero so the
732 // crossProduct vector should also not be zero.
733 rotBetween.x = rotBetween.x / mag;
734 rotBetween.y = rotBetween.y / mag;
735 rotBetween.z = rotBetween.z / mag;
736 rotBetween.s = rotBetween.s / mag;
737 // Check for undefined values and set zero rotation if any found. This code might not actually be required
738 // any longer since zero vectors are checked for at the top.
739 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
740 {
741 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
742 }
743 }
744 } 863 }
745 return rotBetween;
746 } 864 }
747 865
748 public void llWhisper(int channelID, string text) 866 public void llWhisper(int channelID, string text)
749 { 867 {
750 m_host.AddScriptLPS(1); 868 m_host.AddScriptLPS(1);
@@ -760,10 +878,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
760 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 878 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
761 } 879 }
762 880
881 private void CheckSayShoutTime()
882 {
883 DateTime now = DateTime.UtcNow;
884 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
885 {
886 m_lastSayShoutCheck = now;
887 m_SayShoutCount = 0;
888 }
889 else
890 m_SayShoutCount++;
891 }
892
763 public void llSay(int channelID, string text) 893 public void llSay(int channelID, string text)
764 { 894 {
765 m_host.AddScriptLPS(1); 895 m_host.AddScriptLPS(1);
766 896
897 if (channelID == 0)
898// m_SayShoutCount++;
899 CheckSayShoutTime();
900
901 if (m_SayShoutCount >= 11)
902 ScriptSleep(2000);
903
767 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 904 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
768 { 905 {
769 Console.WriteLine(text); 906 Console.WriteLine(text);
@@ -786,6 +923,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
786 { 923 {
787 m_host.AddScriptLPS(1); 924 m_host.AddScriptLPS(1);
788 925
926 if (channelID == 0)
927// m_SayShoutCount++;
928 CheckSayShoutTime();
929
930 if (m_SayShoutCount >= 11)
931 ScriptSleep(2000);
932
789 if (text.Length > 1023) 933 if (text.Length > 1023)
790 text = text.Substring(0, 1023); 934 text = text.Substring(0, 1023);
791 935
@@ -817,22 +961,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
817 961
818 public void llRegionSayTo(string target, int channel, string msg) 962 public void llRegionSayTo(string target, int channel, string msg)
819 { 963 {
964 string error = String.Empty;
965
820 if (msg.Length > 1023) 966 if (msg.Length > 1023)
821 msg = msg.Substring(0, 1023); 967 msg = msg.Substring(0, 1023);
822 968
823 m_host.AddScriptLPS(1); 969 m_host.AddScriptLPS(1);
824 970
825 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
826 {
827 return;
828 }
829
830 UUID TargetID; 971 UUID TargetID;
831 UUID.TryParse(target, out TargetID); 972 UUID.TryParse(target, out TargetID);
832 973
833 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 974 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
834 if (wComm != null) 975 if (wComm != null)
835 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 976 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
977 LSLError(error);
836 } 978 }
837 979
838 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 980 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1088,10 +1230,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1088 return detectedParams.TouchUV; 1230 return detectedParams.TouchUV;
1089 } 1231 }
1090 1232
1233 [DebuggerNonUserCode]
1091 public virtual void llDie() 1234 public virtual void llDie()
1092 { 1235 {
1093 m_host.AddScriptLPS(1); 1236 m_host.AddScriptLPS(1);
1094 throw new SelfDeleteException(); 1237 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1095 } 1238 }
1096 1239
1097 public LSL_Float llGround(LSL_Vector offset) 1240 public LSL_Float llGround(LSL_Vector offset)
@@ -1164,6 +1307,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1164 1307
1165 public void llSetStatus(int status, int value) 1308 public void llSetStatus(int status, int value)
1166 { 1309 {
1310 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1311 return;
1167 m_host.AddScriptLPS(1); 1312 m_host.AddScriptLPS(1);
1168 1313
1169 int statusrotationaxis = 0; 1314 int statusrotationaxis = 0;
@@ -1187,6 +1332,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1187 if (!allow) 1332 if (!allow)
1188 return; 1333 return;
1189 1334
1335 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1336 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1337 return;
1338
1190 m_host.ScriptSetPhysicsStatus(true); 1339 m_host.ScriptSetPhysicsStatus(true);
1191 } 1340 }
1192 else 1341 else
@@ -1384,6 +1533,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1384 { 1533 {
1385 m_host.AddScriptLPS(1); 1534 m_host.AddScriptLPS(1);
1386 1535
1536 SetColor(m_host, color, face);
1537 }
1538
1539 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1540 {
1541 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1542 return;
1543
1544 Primitive.TextureEntry tex = part.Shape.Textures;
1545 Color4 texcolor;
1546 if (face >= 0 && face < GetNumberOfSides(part))
1547 {
1548 texcolor = tex.CreateFace((uint)face).RGBA;
1549 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1550 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1551 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1552 tex.FaceTextures[face].RGBA = texcolor;
1553 part.UpdateTextureEntry(tex.GetBytes());
1554 return;
1555 }
1556 else if (face == ScriptBaseClass.ALL_SIDES)
1557 {
1558 for (uint i = 0; i < GetNumberOfSides(part); i++)
1559 {
1560 if (tex.FaceTextures[i] != null)
1561 {
1562 texcolor = tex.FaceTextures[i].RGBA;
1563 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1564 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1565 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1566 tex.FaceTextures[i].RGBA = texcolor;
1567 }
1568 texcolor = tex.DefaultTexture.RGBA;
1569 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1570 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1571 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1572 tex.DefaultTexture.RGBA = texcolor;
1573 }
1574 part.UpdateTextureEntry(tex.GetBytes());
1575 return;
1576 }
1577
1387 if (face == ScriptBaseClass.ALL_SIDES) 1578 if (face == ScriptBaseClass.ALL_SIDES)
1388 face = SceneObjectPart.ALL_SIDES; 1579 face = SceneObjectPart.ALL_SIDES;
1389 1580
@@ -1392,6 +1583,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1392 1583
1393 public void SetTexGen(SceneObjectPart part, int face,int style) 1584 public void SetTexGen(SceneObjectPart part, int face,int style)
1394 { 1585 {
1586 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1587 return;
1588
1395 Primitive.TextureEntry tex = part.Shape.Textures; 1589 Primitive.TextureEntry tex = part.Shape.Textures;
1396 MappingType textype; 1590 MappingType textype;
1397 textype = MappingType.Default; 1591 textype = MappingType.Default;
@@ -1422,6 +1616,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1422 1616
1423 public void SetGlow(SceneObjectPart part, int face, float glow) 1617 public void SetGlow(SceneObjectPart part, int face, float glow)
1424 { 1618 {
1619 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1620 return;
1621
1425 Primitive.TextureEntry tex = part.Shape.Textures; 1622 Primitive.TextureEntry tex = part.Shape.Textures;
1426 if (face >= 0 && face < GetNumberOfSides(part)) 1623 if (face >= 0 && face < GetNumberOfSides(part))
1427 { 1624 {
@@ -1447,6 +1644,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1447 1644
1448 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1645 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1449 { 1646 {
1647 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1648 return;
1450 1649
1451 Shininess sval = new Shininess(); 1650 Shininess sval = new Shininess();
1452 1651
@@ -1497,6 +1696,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1497 1696
1498 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1697 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1499 { 1698 {
1699 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1700 return;
1701
1500 Primitive.TextureEntry tex = part.Shape.Textures; 1702 Primitive.TextureEntry tex = part.Shape.Textures;
1501 if (face >= 0 && face < GetNumberOfSides(part)) 1703 if (face >= 0 && face < GetNumberOfSides(part))
1502 { 1704 {
@@ -1557,13 +1759,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1557 m_host.AddScriptLPS(1); 1759 m_host.AddScriptLPS(1);
1558 1760
1559 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1761 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1560 1762 if (parts.Count > 0)
1561 foreach (SceneObjectPart part in parts) 1763 {
1562 SetAlpha(part, alpha, face); 1764 try
1765 {
1766 foreach (SceneObjectPart part in parts)
1767 SetAlpha(part, alpha, face);
1768 }
1769 finally
1770 {
1771 }
1772 }
1563 } 1773 }
1564 1774
1565 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1775 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1566 { 1776 {
1777 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1778 return;
1779
1567 Primitive.TextureEntry tex = part.Shape.Textures; 1780 Primitive.TextureEntry tex = part.Shape.Textures;
1568 Color4 texcolor; 1781 Color4 texcolor;
1569 if (face >= 0 && face < GetNumberOfSides(part)) 1782 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1616,7 +1829,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1616 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1829 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1617 float wind, float tension, LSL_Vector Force) 1830 float wind, float tension, LSL_Vector Force)
1618 { 1831 {
1619 if (part == null) 1832 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1620 return; 1833 return;
1621 1834
1622 if (flexi) 1835 if (flexi)
@@ -1650,7 +1863,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1650 /// <param name="falloff"></param> 1863 /// <param name="falloff"></param>
1651 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1864 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1652 { 1865 {
1653 if (part == null) 1866 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1654 return; 1867 return;
1655 1868
1656 if (light) 1869 if (light)
@@ -1683,11 +1896,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1683 Primitive.TextureEntry tex = part.Shape.Textures; 1896 Primitive.TextureEntry tex = part.Shape.Textures;
1684 Color4 texcolor; 1897 Color4 texcolor;
1685 LSL_Vector rgb = new LSL_Vector(); 1898 LSL_Vector rgb = new LSL_Vector();
1899 int nsides = GetNumberOfSides(part);
1900
1686 if (face == ScriptBaseClass.ALL_SIDES) 1901 if (face == ScriptBaseClass.ALL_SIDES)
1687 { 1902 {
1688 int i; 1903 int i;
1689 1904 for (i = 0; i < nsides; i++)
1690 for (i = 0 ; i < GetNumberOfSides(part); i++)
1691 { 1905 {
1692 texcolor = tex.GetFace((uint)i).RGBA; 1906 texcolor = tex.GetFace((uint)i).RGBA;
1693 rgb.x += texcolor.R; 1907 rgb.x += texcolor.R;
@@ -1695,14 +1909,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1695 rgb.z += texcolor.B; 1909 rgb.z += texcolor.B;
1696 } 1910 }
1697 1911
1698 rgb.x /= (float)GetNumberOfSides(part); 1912 float invnsides = 1.0f / (float)nsides;
1699 rgb.y /= (float)GetNumberOfSides(part); 1913
1700 rgb.z /= (float)GetNumberOfSides(part); 1914 rgb.x *= invnsides;
1915 rgb.y *= invnsides;
1916 rgb.z *= invnsides;
1701 1917
1702 return rgb; 1918 return rgb;
1703 } 1919 }
1704 1920 if (face >= 0 && face < nsides)
1705 if (face >= 0 && face < GetNumberOfSides(part))
1706 { 1921 {
1707 texcolor = tex.GetFace((uint)face).RGBA; 1922 texcolor = tex.GetFace((uint)face).RGBA;
1708 rgb.x = texcolor.R; 1923 rgb.x = texcolor.R;
@@ -1729,15 +1944,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1729 m_host.AddScriptLPS(1); 1944 m_host.AddScriptLPS(1);
1730 1945
1731 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1946 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1732 1947 if (parts.Count > 0)
1733 foreach (SceneObjectPart part in parts) 1948 {
1734 SetTexture(part, texture, face); 1949 try
1735 1950 {
1951 foreach (SceneObjectPart part in parts)
1952 SetTexture(part, texture, face);
1953 }
1954 finally
1955 {
1956 }
1957 }
1736 ScriptSleep(200); 1958 ScriptSleep(200);
1737 } 1959 }
1738 1960
1739 protected void SetTexture(SceneObjectPart part, string texture, int face) 1961 protected void SetTexture(SceneObjectPart part, string texture, int face)
1740 { 1962 {
1963 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1964 return;
1965
1741 UUID textureID = new UUID(); 1966 UUID textureID = new UUID();
1742 1967
1743 textureID = InventoryKey(texture, (int)AssetType.Texture); 1968 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1782,6 +2007,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1782 2007
1783 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2008 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1784 { 2009 {
2010 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2011 return;
2012
1785 Primitive.TextureEntry tex = part.Shape.Textures; 2013 Primitive.TextureEntry tex = part.Shape.Textures;
1786 if (face >= 0 && face < GetNumberOfSides(part)) 2014 if (face >= 0 && face < GetNumberOfSides(part))
1787 { 2015 {
@@ -1818,6 +2046,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1818 2046
1819 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2047 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1820 { 2048 {
2049 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2050 return;
2051
1821 Primitive.TextureEntry tex = part.Shape.Textures; 2052 Primitive.TextureEntry tex = part.Shape.Textures;
1822 if (face >= 0 && face < GetNumberOfSides(part)) 2053 if (face >= 0 && face < GetNumberOfSides(part))
1823 { 2054 {
@@ -1854,6 +2085,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1854 2085
1855 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2086 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1856 { 2087 {
2088 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2089 return;
2090
1857 Primitive.TextureEntry tex = part.Shape.Textures; 2091 Primitive.TextureEntry tex = part.Shape.Textures;
1858 if (face >= 0 && face < GetNumberOfSides(part)) 2092 if (face >= 0 && face < GetNumberOfSides(part))
1859 { 2093 {
@@ -1974,7 +2208,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1974 2208
1975 bool sameParcel = here.GlobalID == there.GlobalID; 2209 bool sameParcel = here.GlobalID == there.GlobalID;
1976 2210
1977 if (!sameParcel && !World.Permissions.CanRezObject(m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))) 2211 if (!sameParcel && !World.Permissions.CanObjectEntry(m_host.UUID, false, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)))
1978 { 2212 {
1979 return 0; 2213 return 0;
1980 } 2214 }
@@ -2023,24 +2257,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2023 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2257 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2024 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2258 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2025 { 2259 {
2026 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2260 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2261 return;
2262
2027 LSL_Vector currentPos = GetPartLocalPos(part); 2263 LSL_Vector currentPos = GetPartLocalPos(part);
2264 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2028 2265
2029 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2030 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2031 2266
2032 if (part.ParentGroup.RootPart == part) 2267 if (part.ParentGroup.RootPart == part)
2033 { 2268 {
2034 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2035 targetPos.z = ground;
2036 SceneObjectGroup parent = part.ParentGroup; 2269 SceneObjectGroup parent = part.ParentGroup;
2037 LSL_Vector real_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); 2270 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2038 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2271 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2272 return;
2273 Util.FireAndForget(delegate(object x) {
2274 parent.UpdateGroupPosition(dest);
2275 });
2039 } 2276 }
2040 else 2277 else
2041 { 2278 {
2042 LSL_Vector rel_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); 2279 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2043 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2044 SceneObjectGroup parent = part.ParentGroup; 2280 SceneObjectGroup parent = part.ParentGroup;
2045 parent.HasGroupChanged = true; 2281 parent.HasGroupChanged = true;
2046 parent.ScheduleGroupForTerseUpdate(); 2282 parent.ScheduleGroupForTerseUpdate();
@@ -2073,17 +2309,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2073 else 2309 else
2074 { 2310 {
2075 if (part.ParentGroup.IsAttachment) 2311 if (part.ParentGroup.IsAttachment)
2076 {
2077 pos = part.AttachedPos; 2312 pos = part.AttachedPos;
2078 }
2079 else 2313 else
2080 {
2081 pos = part.AbsolutePosition; 2314 pos = part.AbsolutePosition;
2082 }
2083 } 2315 }
2084 2316
2085// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2086
2087 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2317 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2088 } 2318 }
2089 2319
@@ -2092,18 +2322,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2092 m_host.AddScriptLPS(1); 2322 m_host.AddScriptLPS(1);
2093 2323
2094 // try to let this work as in SL... 2324 // try to let this work as in SL...
2095 if (m_host.ParentID == 0) 2325 if (m_host.LinkNum < 2)
2096 { 2326 {
2097 // special case: If we are root, rotate complete SOG to new rotation 2327 // Special case: If we are root, rotate complete SOG to new
2328 // rotation.
2329 // We are root if the link number is 0 (single prim) or 1
2330 // (root prim). ParentID may be nonzero in attachments and
2331 // using it would cause attachments and HUDs to rotate
2332 // to the wrong positions.
2333
2098 SetRot(m_host, Rot2Quaternion(rot)); 2334 SetRot(m_host, Rot2Quaternion(rot));
2099 } 2335 }
2100 else 2336 else
2101 { 2337 {
2102 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2338 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2103 SceneObjectPart rootPart = m_host.ParentGroup.RootPart; 2339 SceneObjectPart rootPart;
2104 if (rootPart != null) // better safe than sorry 2340 if (m_host.ParentGroup != null) // better safe than sorry
2105 { 2341 {
2106 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); 2342 rootPart = m_host.ParentGroup.RootPart;
2343 if (rootPart != null)
2344 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2107 } 2345 }
2108 } 2346 }
2109 2347
@@ -2113,31 +2351,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2113 public void llSetLocalRot(LSL_Rotation rot) 2351 public void llSetLocalRot(LSL_Rotation rot)
2114 { 2352 {
2115 m_host.AddScriptLPS(1); 2353 m_host.AddScriptLPS(1);
2354
2116 SetRot(m_host, Rot2Quaternion(rot)); 2355 SetRot(m_host, Rot2Quaternion(rot));
2117 ScriptSleep(200); 2356 ScriptSleep(200);
2118 } 2357 }
2119 2358
2120 protected void SetRot(SceneObjectPart part, Quaternion rot) 2359 protected void SetRot(SceneObjectPart part, Quaternion rot)
2121 { 2360 {
2122 part.UpdateRotation(rot); 2361 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2123 // Update rotation does not move the object in the physics scene if it's a linkset. 2362 return;
2124 2363
2125//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2364 bool isroot = (part == part.ParentGroup.RootPart);
2126// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2365 bool isphys;
2127 2366
2128 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2129 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2130 // It's perfectly okay when the object is not an active physical body though.
2131 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2132 // but only if the object is not physial and active. This is important for rotating doors.
2133 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2134 // scene
2135 PhysicsActor pa = part.PhysActor; 2367 PhysicsActor pa = part.PhysActor;
2136 2368
2137 if (pa != null && !pa.IsPhysical) 2369 // keep using physactor ideia of isphysical
2370 // it should be SOP ideia of that
2371 // not much of a issue with ubitODE
2372 if (pa != null && pa.IsPhysical)
2373 isphys = true;
2374 else
2375 isphys = false;
2376
2377 // SL doesn't let scripts rotate root of physical linksets
2378 if (isroot && isphys)
2379 return;
2380
2381 part.UpdateRotation(rot);
2382
2383 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2384 // so do a nasty update of parts positions if is a root part rotation
2385 if (isroot && pa != null) // with if above implies non physical root part
2138 { 2386 {
2139 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2387 part.ParentGroup.ResetChildPrimPhysicsPositions();
2140 } 2388 }
2389 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2390 {
2391 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2392 if (sittingavas.Count > 0)
2393 {
2394 foreach (ScenePresence av in sittingavas)
2395 {
2396 if (isroot || part.LocalId == av.ParentID)
2397 av.SendTerseUpdateToAllClients();
2398 }
2399 }
2400 }
2141 } 2401 }
2142 2402
2143 /// <summary> 2403 /// <summary>
@@ -2185,8 +2445,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2185 2445
2186 public LSL_Rotation llGetLocalRot() 2446 public LSL_Rotation llGetLocalRot()
2187 { 2447 {
2448 return GetPartLocalRot(m_host);
2449 }
2450
2451 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2452 {
2188 m_host.AddScriptLPS(1); 2453 m_host.AddScriptLPS(1);
2189 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2454 Quaternion rot = part.RotationOffset;
2455 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2190 } 2456 }
2191 2457
2192 public void llSetForce(LSL_Vector force, int local) 2458 public void llSetForce(LSL_Vector force, int local)
@@ -2270,16 +2536,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2270 m_host.ApplyImpulse(v, local != 0); 2536 m_host.ApplyImpulse(v, local != 0);
2271 } 2537 }
2272 2538
2539
2273 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2540 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2274 { 2541 {
2275 m_host.AddScriptLPS(1); 2542 m_host.AddScriptLPS(1);
2276 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2543 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2277 } 2544 }
2278 2545
2279 public void llSetTorque(LSL_Vector torque, int local) 2546 public void llSetTorque(LSL_Vector torque, int local)
2280 { 2547 {
2281 m_host.AddScriptLPS(1); 2548 m_host.AddScriptLPS(1);
2282 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2549 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2283 } 2550 }
2284 2551
2285 public LSL_Vector llGetTorque() 2552 public LSL_Vector llGetTorque()
@@ -2296,20 +2563,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2296 llSetTorque(torque, local); 2563 llSetTorque(torque, local);
2297 } 2564 }
2298 2565
2566 public void llSetVelocity(LSL_Vector vel, int local)
2567 {
2568 m_host.AddScriptLPS(1);
2569 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2570 }
2571
2299 public LSL_Vector llGetVel() 2572 public LSL_Vector llGetVel()
2300 { 2573 {
2301 m_host.AddScriptLPS(1); 2574 m_host.AddScriptLPS(1);
2302 2575
2303 Vector3 vel; 2576 Vector3 vel = Vector3.Zero;
2304 2577
2305 if (m_host.ParentGroup.IsAttachment) 2578 if (m_host.ParentGroup.IsAttachment)
2306 { 2579 {
2307 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2580 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2308 vel = avatar.Velocity; 2581 if (avatar != null)
2582 vel = avatar.Velocity;
2309 } 2583 }
2310 else 2584 else
2311 { 2585 {
2312 vel = m_host.Velocity; 2586 vel = m_host.ParentGroup.RootPart.Velocity;
2313 } 2587 }
2314 2588
2315 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2589 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2321,10 +2595,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2321 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2595 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2322 } 2596 }
2323 2597
2598 public void llSetAngularVelocity(LSL_Vector avel, int local)
2599 {
2600 m_host.AddScriptLPS(1);
2601 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2602 }
2603
2324 public LSL_Vector llGetOmega() 2604 public LSL_Vector llGetOmega()
2325 { 2605 {
2326 m_host.AddScriptLPS(1); 2606 m_host.AddScriptLPS(1);
2327 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2607 Vector3 avel = m_host.AngularVelocity;
2608 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2328 } 2609 }
2329 2610
2330 public LSL_Float llGetTimeOfDay() 2611 public LSL_Float llGetTimeOfDay()
@@ -2853,16 +3134,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2853 new_group.RootPart.UUID.ToString()) }, 3134 new_group.RootPart.UUID.ToString()) },
2854 new DetectParams[0])); 3135 new DetectParams[0]));
2855 3136
2856 float groupmass = new_group.GetMass(); 3137 // do recoil
3138 SceneObjectGroup hostgrp = m_host.ParentGroup;
3139 if (hostgrp == null)
3140 return;
3141
3142 if (hostgrp.IsAttachment) // don't recoil avatars
3143 return;
2857 3144
2858 PhysicsActor pa = new_group.RootPart.PhysActor; 3145 PhysicsActor pa = new_group.RootPart.PhysActor;
2859 3146
2860 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) 3147 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero)
2861 { 3148 {
2862 //Recoil. 3149 float groupmass = new_group.GetMass();
2863 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); 3150 llvel *= -groupmass;
3151 llApplyImpulse(new LSL_Vector(llvel.X, llvel.Y,llvel.Z), 0);
2864 } 3152 }
2865 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3153 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3154 return;
3155
2866 }); 3156 });
2867 3157
2868 //ScriptSleep((int)((groupmass * velmag) / 10)); 3158 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2877,35 +3167,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2877 public void llLookAt(LSL_Vector target, double strength, double damping) 3167 public void llLookAt(LSL_Vector target, double strength, double damping)
2878 { 3168 {
2879 m_host.AddScriptLPS(1); 3169 m_host.AddScriptLPS(1);
2880 // Determine where we are looking from
2881 LSL_Vector from = llGetPos();
2882 3170
2883 // Work out the normalised vector from the source to the target 3171 // Get the normalized vector to the target
2884 LSL_Vector delta = llVecNorm(target - from); 3172 LSL_Vector d1 = llVecNorm(target - llGetPos());
2885 LSL_Vector angle = new LSL_Vector(0,0,0);
2886 3173
2887 // Calculate the yaw 3174 // Get the bearing (yaw)
2888 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3175 LSL_Vector a1 = new LSL_Vector(0,0,0);
2889 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3176 a1.z = llAtan2(d1.y, d1.x);
2890 3177
2891 // Calculate pitch 3178 // Get the elevation (pitch)
2892 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3179 LSL_Vector a2 = new LSL_Vector(0,0,0);
3180 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2893 3181
2894 // we need to convert from a vector describing 3182 LSL_Rotation r1 = llEuler2Rot(a1);
2895 // the angles of rotation in radians into rotation value 3183 LSL_Rotation r2 = llEuler2Rot(a2);
2896 LSL_Rotation rot = llEuler2Rot(angle); 3184 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2897
2898 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2899 // set the rotation of the object, copy that behavior
2900 PhysicsActor pa = m_host.PhysActor;
2901 3185
2902 if (strength == 0 || pa == null || !pa.IsPhysical) 3186 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2903 { 3187 {
2904 llSetRot(rot); 3188 // Do nothing if either value is 0 (this has been checked in SL)
3189 if (strength <= 0.0 || damping <= 0.0)
3190 return;
3191
3192 llSetRot(r3 * r2 * r1);
2905 } 3193 }
2906 else 3194 else
2907 { 3195 {
2908 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3196 if (strength == 0)
3197 {
3198 llSetRot(r3 * r2 * r1);
3199 return;
3200 }
3201
3202 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2909 } 3203 }
2910 } 3204 }
2911 3205
@@ -2951,17 +3245,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2951 } 3245 }
2952 else 3246 else
2953 { 3247 {
2954 if (m_host.IsRoot) 3248 // new SL always returns object mass
2955 { 3249// if (m_host.IsRoot)
3250// {
2956 return m_host.ParentGroup.GetMass(); 3251 return m_host.ParentGroup.GetMass();
2957 } 3252// }
2958 else 3253// else
2959 { 3254// {
2960 return m_host.GetMass(); 3255// return m_host.GetMass();
2961 } 3256// }
2962 } 3257 }
2963 } 3258 }
2964 3259
3260
3261 public LSL_Float llGetMassMKS()
3262 {
3263 return 100f * llGetMass();
3264 }
3265
2965 public void llCollisionFilter(string name, string id, int accept) 3266 public void llCollisionFilter(string name, string id, int accept)
2966 { 3267 {
2967 m_host.AddScriptLPS(1); 3268 m_host.AddScriptLPS(1);
@@ -3009,8 +3310,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3009 { 3310 {
3010 // Unregister controls from Presence 3311 // Unregister controls from Presence
3011 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3312 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3012 // Remove Take Control permission.
3013 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3014 } 3313 }
3015 } 3314 }
3016 } 3315 }
@@ -3036,7 +3335,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3036 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3335 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3037 3336
3038 if (attachmentsModule != null) 3337 if (attachmentsModule != null)
3039 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3338 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3040 else 3339 else
3041 return false; 3340 return false;
3042 } 3341 }
@@ -3066,9 +3365,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3066 { 3365 {
3067 m_host.AddScriptLPS(1); 3366 m_host.AddScriptLPS(1);
3068 3367
3069// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3070// return;
3071
3072 if (m_item.PermsGranter != m_host.OwnerID) 3368 if (m_item.PermsGranter != m_host.OwnerID)
3073 return; 3369 return;
3074 3370
@@ -3111,6 +3407,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3111 3407
3112 public void llInstantMessage(string user, string message) 3408 public void llInstantMessage(string user, string message)
3113 { 3409 {
3410 UUID result;
3411 if (!UUID.TryParse(user, out result))
3412 {
3413 ShoutError("An invalid key was passed to llInstantMessage");
3414 ScriptSleep(2000);
3415 return;
3416 }
3417
3418
3114 m_host.AddScriptLPS(1); 3419 m_host.AddScriptLPS(1);
3115 3420
3116 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3421 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3125,14 +3430,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3125 UUID friendTransactionID = UUID.Random(); 3430 UUID friendTransactionID = UUID.Random();
3126 3431
3127 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3432 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3128 3433
3129 GridInstantMessage msg = new GridInstantMessage(); 3434 GridInstantMessage msg = new GridInstantMessage();
3130 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3435 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3131 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3436 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3132 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3437 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3133// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3438// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3134// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3439// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3135 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3440// DateTime dt = DateTime.UtcNow;
3441//
3442// // Ticks from UtcNow, but make it look like local. Evil, huh?
3443// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3444//
3445// try
3446// {
3447// // Convert that to the PST timezone
3448// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3449// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3450// }
3451// catch
3452// {
3453// // No logging here, as it could be VERY spammy
3454// }
3455//
3456// // And make it look local again to fool the unix time util
3457// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3458
3459 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3460
3136 //if (client != null) 3461 //if (client != null)
3137 //{ 3462 //{
3138 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3463 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3146,12 +3471,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3146 msg.message = message.Substring(0, 1024); 3471 msg.message = message.Substring(0, 1024);
3147 else 3472 else
3148 msg.message = message; 3473 msg.message = message;
3149 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3474 msg.dialog = (byte)19; // MessageFromObject
3150 msg.fromGroup = false;// fromGroup; 3475 msg.fromGroup = false;// fromGroup;
3151 msg.offline = (byte)0; //offline; 3476 msg.offline = (byte)0; //offline;
3152 msg.ParentEstateID = 0; //ParentEstateID; 3477 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3153 msg.Position = new Vector3(m_host.AbsolutePosition); 3478 msg.Position = new Vector3(m_host.AbsolutePosition);
3154 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3479 msg.RegionID = World.RegionInfo.RegionID.Guid;
3155 msg.binaryBucket 3480 msg.binaryBucket
3156 = Util.StringToBytes256( 3481 = Util.StringToBytes256(
3157 "{0}/{1}/{2}/{3}", 3482 "{0}/{1}/{2}/{3}",
@@ -3179,7 +3504,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3179 } 3504 }
3180 3505
3181 emailModule.SendEmail(m_host.UUID, address, subject, message); 3506 emailModule.SendEmail(m_host.UUID, address, subject, message);
3182 llSleep(EMAIL_PAUSE_TIME); 3507 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3183 } 3508 }
3184 3509
3185 public void llGetNextEmail(string address, string subject) 3510 public void llGetNextEmail(string address, string subject)
@@ -3425,7 +3750,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3425 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3750 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3426 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3751 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3427 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3752 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3753 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3428 ScriptBaseClass.PERMISSION_ATTACH; 3754 ScriptBaseClass.PERMISSION_ATTACH;
3755
3429 } 3756 }
3430 else 3757 else
3431 { 3758 {
@@ -3460,11 +3787,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3460 3787
3461 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3788 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3462 { 3789 {
3463 lock (m_host.TaskInventory) 3790 m_host.TaskInventory.LockItemsForWrite(true);
3464 { 3791 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3465 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3792 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3466 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3793 m_host.TaskInventory.LockItemsForWrite(false);
3467 }
3468 3794
3469 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3795 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3470 "run_time_permissions", new Object[] { 3796 "run_time_permissions", new Object[] {
@@ -3507,11 +3833,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3507 3833
3508 if (!m_waitingForScriptAnswer) 3834 if (!m_waitingForScriptAnswer)
3509 { 3835 {
3510 lock (m_host.TaskInventory) 3836 m_host.TaskInventory.LockItemsForWrite(true);
3511 { 3837 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3512 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3838 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3513 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3839 m_host.TaskInventory.LockItemsForWrite(false);
3514 }
3515 3840
3516 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3841 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3517 m_waitingForScriptAnswer=true; 3842 m_waitingForScriptAnswer=true;
@@ -3540,14 +3865,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3540 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3865 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3541 llReleaseControls(); 3866 llReleaseControls();
3542 3867
3543 lock (m_host.TaskInventory) 3868 m_host.TaskInventory.LockItemsForWrite(true);
3544 { 3869 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3545 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3870 m_host.TaskInventory.LockItemsForWrite(false);
3546 } 3871
3547 3872 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3548 m_ScriptEngine.PostScriptEvent( 3873 "run_time_permissions", new Object[] {
3549 m_item.ItemID, 3874 new LSL_Integer(answer) },
3550 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3875 new DetectParams[0]));
3551 } 3876 }
3552 3877
3553 public LSL_String llGetPermissionsKey() 3878 public LSL_String llGetPermissionsKey()
@@ -3586,14 +3911,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3586 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3911 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3587 { 3912 {
3588 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3913 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3589 3914 if (parts.Count > 0)
3590 foreach (SceneObjectPart part in parts) 3915 {
3591 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3916 try
3917 {
3918 foreach (SceneObjectPart part in parts)
3919 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3920 }
3921 finally
3922 {
3923 }
3924 }
3592 } 3925 }
3593 3926
3594 public void llCreateLink(string target, int parent) 3927 public void llCreateLink(string target, int parent)
3595 { 3928 {
3596 m_host.AddScriptLPS(1); 3929 m_host.AddScriptLPS(1);
3930
3597 UUID targetID; 3931 UUID targetID;
3598 3932
3599 if (!UUID.TryParse(target, out targetID)) 3933 if (!UUID.TryParse(target, out targetID))
@@ -3699,10 +4033,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3699 // Restructuring Multiple Prims. 4033 // Restructuring Multiple Prims.
3700 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4034 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3701 parts.Remove(parentPrim.RootPart); 4035 parts.Remove(parentPrim.RootPart);
3702 foreach (SceneObjectPart part in parts) 4036 if (parts.Count > 0)
3703 { 4037 {
3704 parentPrim.DelinkFromGroup(part.LocalId, true); 4038 try
4039 {
4040 foreach (SceneObjectPart part in parts)
4041 {
4042 parentPrim.DelinkFromGroup(part.LocalId, true);
4043 }
4044 }
4045 finally
4046 {
4047 }
3705 } 4048 }
4049
3706 parentPrim.HasGroupChanged = true; 4050 parentPrim.HasGroupChanged = true;
3707 parentPrim.ScheduleGroupForFullUpdate(); 4051 parentPrim.ScheduleGroupForFullUpdate();
3708 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4052 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3711,12 +4055,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3711 { 4055 {
3712 SceneObjectPart newRoot = parts[0]; 4056 SceneObjectPart newRoot = parts[0];
3713 parts.Remove(newRoot); 4057 parts.Remove(newRoot);
3714 foreach (SceneObjectPart part in parts) 4058
4059 try
3715 { 4060 {
3716 // Required for linking 4061 foreach (SceneObjectPart part in parts)
3717 part.ClearUpdateSchedule(); 4062 {
3718 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4063 part.ClearUpdateSchedule();
4064 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4065 }
3719 } 4066 }
4067 finally
4068 {
4069 }
4070
4071
3720 newRoot.ParentGroup.HasGroupChanged = true; 4072 newRoot.ParentGroup.HasGroupChanged = true;
3721 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4073 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3722 } 4074 }
@@ -3736,6 +4088,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3736 public void llBreakAllLinks() 4088 public void llBreakAllLinks()
3737 { 4089 {
3738 m_host.AddScriptLPS(1); 4090 m_host.AddScriptLPS(1);
4091
4092 TaskInventoryItem item = m_item;
4093
4094 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4095 && !m_automaticLinkPermission)
4096 {
4097 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4098 return;
4099 }
4100
3739 SceneObjectGroup parentPrim = m_host.ParentGroup; 4101 SceneObjectGroup parentPrim = m_host.ParentGroup;
3740 if (parentPrim.AttachmentPoint != 0) 4102 if (parentPrim.AttachmentPoint != 0)
3741 return; // Fail silently if attached 4103 return; // Fail silently if attached
@@ -3755,25 +4117,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3755 public LSL_String llGetLinkKey(int linknum) 4117 public LSL_String llGetLinkKey(int linknum)
3756 { 4118 {
3757 m_host.AddScriptLPS(1); 4119 m_host.AddScriptLPS(1);
3758 List<UUID> keytable = new List<UUID>();
3759 // parse for sitting avatare-uuids
3760 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3761 {
3762 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3763 keytable.Add(presence.UUID);
3764 });
3765
3766 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3767 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3768 {
3769 return keytable[totalprims - linknum].ToString();
3770 }
3771
3772 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3773 {
3774 return m_host.UUID.ToString();
3775 }
3776
3777 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4120 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3778 if (part != null) 4121 if (part != null)
3779 { 4122 {
@@ -3781,6 +4124,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3781 } 4124 }
3782 else 4125 else
3783 { 4126 {
4127 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4128 {
4129 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4130
4131 if (linknum < 0)
4132 return UUID.Zero.ToString();
4133
4134 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4135 if (avatars.Count > linknum)
4136 {
4137 return avatars[linknum].UUID.ToString();
4138 }
4139 }
3784 return UUID.Zero.ToString(); 4140 return UUID.Zero.ToString();
3785 } 4141 }
3786 } 4142 }
@@ -3880,17 +4236,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3880 m_host.AddScriptLPS(1); 4236 m_host.AddScriptLPS(1);
3881 int count = 0; 4237 int count = 0;
3882 4238
3883 lock (m_host.TaskInventory) 4239 m_host.TaskInventory.LockItemsForRead(true);
4240 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3884 { 4241 {
3885 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4242 if (inv.Value.Type == type || type == -1)
3886 { 4243 {
3887 if (inv.Value.Type == type || type == -1) 4244 count = count + 1;
3888 {
3889 count = count + 1;
3890 }
3891 } 4245 }
3892 } 4246 }
3893 4247
4248 m_host.TaskInventory.LockItemsForRead(false);
3894 return count; 4249 return count;
3895 } 4250 }
3896 4251
@@ -3899,16 +4254,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3899 m_host.AddScriptLPS(1); 4254 m_host.AddScriptLPS(1);
3900 ArrayList keys = new ArrayList(); 4255 ArrayList keys = new ArrayList();
3901 4256
3902 lock (m_host.TaskInventory) 4257 m_host.TaskInventory.LockItemsForRead(true);
4258 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3903 { 4259 {
3904 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4260 if (inv.Value.Type == type || type == -1)
3905 { 4261 {
3906 if (inv.Value.Type == type || type == -1) 4262 keys.Add(inv.Value.Name);
3907 {
3908 keys.Add(inv.Value.Name);
3909 }
3910 } 4263 }
3911 } 4264 }
4265 m_host.TaskInventory.LockItemsForRead(false);
3912 4266
3913 if (keys.Count == 0) 4267 if (keys.Count == 0)
3914 { 4268 {
@@ -3946,7 +4300,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3946 if (item == null) 4300 if (item == null)
3947 { 4301 {
3948 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4302 llSay(0, String.Format("Could not find object '{0}'", inventory));
3949 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4303 return;
4304// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3950 } 4305 }
3951 4306
3952 UUID objId = item.ItemID; 4307 UUID objId = item.ItemID;
@@ -3974,33 +4329,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3974 return; 4329 return;
3975 } 4330 }
3976 } 4331 }
4332
3977 // destination is an avatar 4333 // destination is an avatar
3978 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4334 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3979 4335
3980 if (agentItem == null) 4336 if (agentItem == null)
3981 return; 4337 return;
3982 4338
3983 if (m_TransferModule != null) 4339 byte[] bucket = new byte[1];
3984 { 4340 bucket[0] = (byte)item.Type;
3985 byte[] bucket = new byte[] { (byte)item.Type }; 4341 //byte[] objBytes = agentItem.ID.GetBytes();
4342 //Array.Copy(objBytes, 0, bucket, 1, 16);
3986 4343
3987 GridInstantMessage msg = new GridInstantMessage(World, 4344 GridInstantMessage msg = new GridInstantMessage(World,
3988 m_host.UUID, m_host.Name + ", an object owned by " + 4345 m_host.OwnerID, m_host.Name, destId,
3989 resolveName(m_host.OwnerID) + ",", destId, 4346 (byte)InstantMessageDialog.TaskInventoryOffered,
3990 (byte)InstantMessageDialog.TaskInventoryOffered, 4347 false, item.Name+". "+m_host.Name+" is located at "+
3991 false, item.Name + "\n" + m_host.Name + " is located at " + 4348 World.RegionInfo.RegionName+" "+
3992 World.RegionInfo.RegionName+" "+ 4349 m_host.AbsolutePosition.ToString(),
3993 m_host.AbsolutePosition.ToString(), 4350 agentItem.ID, true, m_host.AbsolutePosition,
3994 agentItem.ID, true, m_host.AbsolutePosition, 4351 bucket);
3995 bucket);
3996 4352
3997 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4353 ScenePresence sp;
3998 }
3999 4354
4355 if (World.TryGetScenePresence(destId, out sp))
4356 {
4357 sp.ControllingClient.SendInstantMessage(msg);
4358 }
4359 else
4360 {
4361 if (m_TransferModule != null)
4362 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4363 }
4364
4365 //This delay should only occur when giving inventory to avatars.
4000 ScriptSleep(3000); 4366 ScriptSleep(3000);
4001 } 4367 }
4002 } 4368 }
4003 4369
4370 [DebuggerNonUserCode]
4004 public void llRemoveInventory(string name) 4371 public void llRemoveInventory(string name)
4005 { 4372 {
4006 m_host.AddScriptLPS(1); 4373 m_host.AddScriptLPS(1);
@@ -4045,109 +4412,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4045 { 4412 {
4046 m_host.AddScriptLPS(1); 4413 m_host.AddScriptLPS(1);
4047 4414
4048 UUID uuid = (UUID)id; 4415 UUID uuid;
4049 PresenceInfo pinfo = null; 4416 if (UUID.TryParse(id, out uuid))
4050 UserAccount account;
4051
4052 UserInfoCacheEntry ce;
4053 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4054 { 4417 {
4055 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4418 PresenceInfo pinfo = null;
4056 if (account == null) 4419 UserAccount account;
4420
4421 UserInfoCacheEntry ce;
4422 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4057 { 4423 {
4058 m_userInfoCache[uuid] = null; // Cache negative 4424 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4059 return UUID.Zero.ToString(); 4425 if (account == null)
4060 } 4426 {
4427 m_userInfoCache[uuid] = null; // Cache negative
4428 return UUID.Zero.ToString();
4429 }
4061 4430
4062 4431
4063 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4432 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4064 if (pinfos != null && pinfos.Length > 0) 4433 if (pinfos != null && pinfos.Length > 0)
4065 {
4066 foreach (PresenceInfo p in pinfos)
4067 { 4434 {
4068 if (p.RegionID != UUID.Zero) 4435 foreach (PresenceInfo p in pinfos)
4069 { 4436 {
4070 pinfo = p; 4437 if (p.RegionID != UUID.Zero)
4438 {
4439 pinfo = p;
4440 }
4071 } 4441 }
4072 } 4442 }
4073 }
4074 4443
4075 ce = new UserInfoCacheEntry(); 4444 ce = new UserInfoCacheEntry();
4076 ce.time = Util.EnvironmentTickCount(); 4445 ce.time = Util.EnvironmentTickCount();
4077 ce.account = account; 4446 ce.account = account;
4078 ce.pinfo = pinfo; 4447 ce.pinfo = pinfo;
4079 } 4448 m_userInfoCache[uuid] = ce;
4080 else 4449 }
4081 { 4450 else
4082 if (ce == null) 4451 {
4083 return UUID.Zero.ToString(); 4452 if (ce == null)
4453 return UUID.Zero.ToString();
4084 4454
4085 account = ce.account; 4455 account = ce.account;
4086 pinfo = ce.pinfo; 4456 pinfo = ce.pinfo;
4087 } 4457 }
4088 4458
4089 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4459 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4090 {
4091 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4092 if (pinfos != null && pinfos.Length > 0)
4093 { 4460 {
4094 foreach (PresenceInfo p in pinfos) 4461 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4462 if (pinfos != null && pinfos.Length > 0)
4095 { 4463 {
4096 if (p.RegionID != UUID.Zero) 4464 foreach (PresenceInfo p in pinfos)
4097 { 4465 {
4098 pinfo = p; 4466 if (p.RegionID != UUID.Zero)
4467 {
4468 pinfo = p;
4469 }
4099 } 4470 }
4100 } 4471 }
4101 } 4472 else
4102 else 4473 pinfo = null;
4103 pinfo = null;
4104 4474
4105 ce.time = Util.EnvironmentTickCount(); 4475 ce.time = Util.EnvironmentTickCount();
4106 ce.pinfo = pinfo; 4476 ce.pinfo = pinfo;
4107 } 4477 }
4108 4478
4109 string reply = String.Empty; 4479 string reply = String.Empty;
4110 4480
4111 switch (data) 4481 switch (data)
4112 { 4482 {
4113 case 1: // DATA_ONLINE (0|1) 4483 case 1: // DATA_ONLINE (0|1)
4114 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4484 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4115 reply = "1"; 4485 reply = "1";
4116 else 4486 else
4117 reply = "0"; 4487 reply = "0";
4118 break; 4488 break;
4119 case 2: // DATA_NAME (First Last) 4489 case 2: // DATA_NAME (First Last)
4120 reply = account.FirstName + " " + account.LastName; 4490 reply = account.FirstName + " " + account.LastName;
4121 break; 4491 break;
4122 case 3: // DATA_BORN (YYYY-MM-DD) 4492 case 3: // DATA_BORN (YYYY-MM-DD)
4123 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4493 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4124 born = born.AddSeconds(account.Created); 4494 born = born.AddSeconds(account.Created);
4125 reply = born.ToString("yyyy-MM-dd"); 4495 reply = born.ToString("yyyy-MM-dd");
4126 break; 4496 break;
4127 case 4: // DATA_RATING (0,0,0,0,0,0) 4497 case 4: // DATA_RATING (0,0,0,0,0,0)
4128 reply = "0,0,0,0,0,0"; 4498 reply = "0,0,0,0,0,0";
4129 break; 4499 break;
4130 case 7: // DATA_USERLEVEL (integer) 4500 case 8: // DATA_PAYINFO (0|1|2|3)
4131 reply = account.UserLevel.ToString(); 4501 reply = "0";
4132 break; 4502 break;
4133 case 8: // DATA_PAYINFO (0|1|2|3) 4503 default:
4134 reply = "0"; 4504 return UUID.Zero.ToString(); // Raise no event
4135 break; 4505 }
4136 default:
4137 return UUID.Zero.ToString(); // Raise no event
4138 }
4139 4506
4140 UUID rq = UUID.Random(); 4507 UUID rq = UUID.Random();
4141 4508
4142 UUID tid = AsyncCommands. 4509 UUID tid = AsyncCommands.
4143 DataserverPlugin.RegisterRequest(m_host.LocalId, 4510 DataserverPlugin.RegisterRequest(m_host.LocalId,
4144 m_item.ItemID, rq.ToString()); 4511 m_item.ItemID, rq.ToString());
4145 4512
4146 AsyncCommands. 4513 AsyncCommands.
4147 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4514 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4148 4515
4149 ScriptSleep(100); 4516 ScriptSleep(100);
4150 return tid.ToString(); 4517 return tid.ToString();
4518 }
4519 else
4520 {
4521 ShoutError("Invalid UUID passed to llRequestAgentData.");
4522 }
4523 return "";
4151 } 4524 }
4152 4525
4153 public LSL_String llRequestInventoryData(string name) 4526 public LSL_String llRequestInventoryData(string name)
@@ -4204,13 +4577,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4204 if (UUID.TryParse(agent, out agentId)) 4577 if (UUID.TryParse(agent, out agentId))
4205 { 4578 {
4206 ScenePresence presence = World.GetScenePresence(agentId); 4579 ScenePresence presence = World.GetScenePresence(agentId);
4207 if (presence != null) 4580 if (presence != null && presence.PresenceType != PresenceType.Npc)
4208 { 4581 {
4582 // agent must not be a god
4583 if (presence.UserLevel >= 200) return;
4584
4209 // agent must be over the owners land 4585 // agent must be over the owners land
4210 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4586 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4211 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4587 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4212 { 4588 {
4213 World.TeleportClientHome(agentId, presence.ControllingClient); 4589 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4590 {
4591 // They can't be teleported home for some reason
4592 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4593 if (regionInfo != null)
4594 {
4595 World.RequestTeleportLocation(
4596 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4597 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4598 }
4599 }
4214 } 4600 }
4215 } 4601 }
4216 } 4602 }
@@ -4322,7 +4708,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4322 UUID av = new UUID(); 4708 UUID av = new UUID();
4323 if (!UUID.TryParse(agent,out av)) 4709 if (!UUID.TryParse(agent,out av))
4324 { 4710 {
4325 LSLError("First parameter to llDialog needs to be a key"); 4711 //LSLError("First parameter to llDialog needs to be a key");
4326 return; 4712 return;
4327 } 4713 }
4328 4714
@@ -4354,7 +4740,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4354 public void llCollisionSound(string impact_sound, double impact_volume) 4740 public void llCollisionSound(string impact_sound, double impact_volume)
4355 { 4741 {
4356 m_host.AddScriptLPS(1); 4742 m_host.AddScriptLPS(1);
4357 4743
4744 if(impact_sound == "")
4745 {
4746 m_host.CollisionSoundVolume = (float)impact_volume;
4747 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4748 m_host.CollisionSoundType = 0;
4749 return;
4750 }
4358 // TODO: Parameter check logic required. 4751 // TODO: Parameter check logic required.
4359 UUID soundId = UUID.Zero; 4752 UUID soundId = UUID.Zero;
4360 if (!UUID.TryParse(impact_sound, out soundId)) 4753 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4367,6 +4760,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4367 4760
4368 m_host.CollisionSound = soundId; 4761 m_host.CollisionSound = soundId;
4369 m_host.CollisionSoundVolume = (float)impact_volume; 4762 m_host.CollisionSoundVolume = (float)impact_volume;
4763 m_host.CollisionSoundType = 1;
4370 } 4764 }
4371 4765
4372 public LSL_String llGetAnimation(string id) 4766 public LSL_String llGetAnimation(string id)
@@ -4380,14 +4774,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4380 4774
4381 if (m_host.RegionHandle == presence.RegionHandle) 4775 if (m_host.RegionHandle == presence.RegionHandle)
4382 { 4776 {
4383 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4384
4385 if (presence != null) 4777 if (presence != null)
4386 { 4778 {
4387 AnimationSet currentAnims = presence.Animator.Animations; 4779 if (presence.SitGround)
4388 string currentAnimationState = String.Empty; 4780 return "Sitting on Ground";
4389 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4781 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4390 return currentAnimationState; 4782 return "Sitting";
4783
4784 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4785 string lslMovementAnimation;
4786
4787 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4788 return lslMovementAnimation;
4391 } 4789 }
4392 } 4790 }
4393 4791
@@ -4534,7 +4932,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4534 { 4932 {
4535 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4933 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4536 float distance_term = distance * distance * distance; // Script Energy 4934 float distance_term = distance * distance * distance; // Script Energy
4537 float pusher_mass = m_host.GetMass(); 4935 // use total object mass and not part
4936 float pusher_mass = m_host.ParentGroup.GetMass();
4538 4937
4539 float PUSH_ATTENUATION_DISTANCE = 17f; 4938 float PUSH_ATTENUATION_DISTANCE = 17f;
4540 float PUSH_ATTENUATION_SCALE = 5f; 4939 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4784,6 +5183,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4784 { 5183 {
4785 return item.AssetID.ToString(); 5184 return item.AssetID.ToString();
4786 } 5185 }
5186 m_host.TaskInventory.LockItemsForRead(false);
4787 5187
4788 return UUID.Zero.ToString(); 5188 return UUID.Zero.ToString();
4789 } 5189 }
@@ -4917,7 +5317,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4917 public LSL_Vector llGetCenterOfMass() 5317 public LSL_Vector llGetCenterOfMass()
4918 { 5318 {
4919 m_host.AddScriptLPS(1); 5319 m_host.AddScriptLPS(1);
4920 Vector3 center = m_host.GetGeometricCenter(); 5320 Vector3 center = m_host.GetCenterOfMass();
4921 return new LSL_Vector(center.X,center.Y,center.Z); 5321 return new LSL_Vector(center.X,center.Y,center.Z);
4922 } 5322 }
4923 5323
@@ -4936,14 +5336,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4936 { 5336 {
4937 m_host.AddScriptLPS(1); 5337 m_host.AddScriptLPS(1);
4938 5338
4939 if (src == null) 5339 return src.Length;
4940 {
4941 return 0;
4942 }
4943 else
4944 {
4945 return src.Length;
4946 }
4947 } 5340 }
4948 5341
4949 public LSL_Integer llList2Integer(LSL_List src, int index) 5342 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5014,7 +5407,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5014 else if (src.Data[index] is LSL_Float) 5407 else if (src.Data[index] is LSL_Float)
5015 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5408 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5016 else if (src.Data[index] is LSL_String) 5409 else if (src.Data[index] is LSL_String)
5017 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5410 {
5411 string str = ((LSL_String) src.Data[index]).m_string;
5412 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5413 if (m != Match.Empty)
5414 {
5415 str = m.Value;
5416 double d = 0.0;
5417 if (!Double.TryParse(str, out d))
5418 return 0.0;
5419
5420 return d;
5421 }
5422 return 0.0;
5423 }
5018 return Convert.ToDouble(src.Data[index]); 5424 return Convert.ToDouble(src.Data[index]);
5019 } 5425 }
5020 catch (FormatException) 5426 catch (FormatException)
@@ -5324,7 +5730,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5324 } 5730 }
5325 } 5731 }
5326 } 5732 }
5327 else { 5733 else
5734 {
5328 object[] array = new object[src.Length]; 5735 object[] array = new object[src.Length];
5329 Array.Copy(src.Data, 0, array, 0, src.Length); 5736 Array.Copy(src.Data, 0, array, 0, src.Length);
5330 result = new LSL_List(array); 5737 result = new LSL_List(array);
@@ -5431,7 +5838,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5431 public LSL_Integer llGetRegionAgentCount() 5838 public LSL_Integer llGetRegionAgentCount()
5432 { 5839 {
5433 m_host.AddScriptLPS(1); 5840 m_host.AddScriptLPS(1);
5434 return new LSL_Integer(World.GetRootAgentCount()); 5841
5842 int count = 0;
5843 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5844 count++;
5845 });
5846
5847 return new LSL_Integer(count);
5435 } 5848 }
5436 5849
5437 public LSL_Vector llGetRegionCorner() 5850 public LSL_Vector llGetRegionCorner()
@@ -5711,6 +6124,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5711 flags |= ScriptBaseClass.AGENT_SITTING; 6124 flags |= ScriptBaseClass.AGENT_SITTING;
5712 } 6125 }
5713 6126
6127 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6128 {
6129 flags |= ScriptBaseClass.AGENT_MALE;
6130 }
6131
5714 return flags; 6132 return flags;
5715 } 6133 }
5716 6134
@@ -5857,10 +6275,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5857 m_host.AddScriptLPS(1); 6275 m_host.AddScriptLPS(1);
5858 6276
5859 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6277 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5860 6278 if (parts.Count > 0)
5861 foreach (var part in parts)
5862 { 6279 {
5863 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6280 try
6281 {
6282 foreach (var part in parts)
6283 {
6284 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6285 }
6286 }
6287 finally
6288 {
6289 }
5864 } 6290 }
5865 } 6291 }
5866 6292
@@ -5912,13 +6338,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5912 6338
5913 if (m_host.OwnerID == land.LandData.OwnerID) 6339 if (m_host.OwnerID == land.LandData.OwnerID)
5914 { 6340 {
5915 World.TeleportClientHome(agentID, presence.ControllingClient); 6341 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6342 presence.TeleportWithMomentum(pos, null);
6343 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5916 } 6344 }
5917 } 6345 }
5918 } 6346 }
5919 ScriptSleep(5000); 6347 ScriptSleep(5000);
5920 } 6348 }
5921 6349
6350 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6351 {
6352 return ParseString2List(str, separators, in_spacers, false);
6353 }
6354
5922 public LSL_Integer llOverMyLand(string id) 6355 public LSL_Integer llOverMyLand(string id)
5923 { 6356 {
5924 m_host.AddScriptLPS(1); 6357 m_host.AddScriptLPS(1);
@@ -5977,20 +6410,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5977 return agentSize; 6410 return agentSize;
5978 } 6411 }
5979 6412
5980 public LSL_Integer llSameGroup(string agent) 6413 public LSL_Integer llSameGroup(string id)
5981 { 6414 {
5982 m_host.AddScriptLPS(1); 6415 m_host.AddScriptLPS(1);
5983 UUID agentId = new UUID(); 6416 UUID uuid = new UUID();
5984 if (!UUID.TryParse(agent, out agentId)) 6417 if (!UUID.TryParse(id, out uuid))
5985 return new LSL_Integer(0);
5986 ScenePresence presence = World.GetScenePresence(agentId);
5987 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5988 return new LSL_Integer(0); 6418 return new LSL_Integer(0);
5989 IClientAPI client = presence.ControllingClient; 6419
5990 if (m_host.GroupID == client.ActiveGroupId) 6420 // Check if it's a group key
6421 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5991 return new LSL_Integer(1); 6422 return new LSL_Integer(1);
5992 else 6423
6424 // We got passed a UUID.Zero
6425 if (uuid == UUID.Zero)
6426 return new LSL_Integer(0);
6427
6428 // Handle the case where id names an avatar
6429 ScenePresence presence = World.GetScenePresence(uuid);
6430 if (presence != null)
6431 {
6432 if (presence.IsChildAgent)
6433 return new LSL_Integer(0);
6434
6435 IClientAPI client = presence.ControllingClient;
6436 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6437 return new LSL_Integer(1);
6438
6439 return new LSL_Integer(0);
6440 }
6441
6442 // Handle object case
6443 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6444 if (part != null)
6445 {
6446 // This will handle both deed and non-deed and also the no
6447 // group case
6448 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6449 return new LSL_Integer(1);
6450
5993 return new LSL_Integer(0); 6451 return new LSL_Integer(0);
6452 }
6453
6454 return new LSL_Integer(0);
5994 } 6455 }
5995 6456
5996 public void llUnSit(string id) 6457 public void llUnSit(string id)
@@ -6119,7 +6580,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6119 return m_host.ParentGroup.AttachmentPoint; 6580 return m_host.ParentGroup.AttachmentPoint;
6120 } 6581 }
6121 6582
6122 public LSL_Integer llGetFreeMemory() 6583 public virtual LSL_Integer llGetFreeMemory()
6123 { 6584 {
6124 m_host.AddScriptLPS(1); 6585 m_host.AddScriptLPS(1);
6125 // Make scripts designed for LSO happy 6586 // Make scripts designed for LSO happy
@@ -6236,7 +6697,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6236 SetParticleSystem(m_host, rules); 6697 SetParticleSystem(m_host, rules);
6237 } 6698 }
6238 6699
6239 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6700 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6701 {
6240 6702
6241 6703
6242 if (rules.Length == 0) 6704 if (rules.Length == 0)
@@ -6553,7 +7015,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6553 { 7015 {
6554 // LSL quaternions can normalize to 0, normal Quaternions can't. 7016 // LSL quaternions can normalize to 0, normal Quaternions can't.
6555 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 7017 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6556 rot.z = 1; // ZERO_ROTATION = 0,0,0,1 7018 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6557 7019
6558 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 7020 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z);
6559 part.SitTargetOrientation = Rot2Quaternion(rot); 7021 part.SitTargetOrientation = Rot2Quaternion(rot);
@@ -6710,13 +7172,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6710 UUID av = new UUID(); 7172 UUID av = new UUID();
6711 if (!UUID.TryParse(avatar,out av)) 7173 if (!UUID.TryParse(avatar,out av))
6712 { 7174 {
6713 LSLError("First parameter to llDialog needs to be a key"); 7175 //LSLError("First parameter to llDialog needs to be a key");
6714 return; 7176 return;
6715 } 7177 }
6716 if (buttons.Length < 1) 7178 if (buttons.Length < 1)
6717 { 7179 {
6718 LSLError("No less than 1 button can be shown"); 7180 buttons.Add("OK");
6719 return;
6720 } 7181 }
6721 if (buttons.Length > 12) 7182 if (buttons.Length > 12)
6722 { 7183 {
@@ -6733,7 +7194,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6733 } 7194 }
6734 if (buttons.Data[i].ToString().Length > 24) 7195 if (buttons.Data[i].ToString().Length > 24)
6735 { 7196 {
6736 LSLError("button label cannot be longer than 24 characters"); 7197 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6737 return; 7198 return;
6738 } 7199 }
6739 buts[i] = buttons.Data[i].ToString(); 7200 buts[i] = buttons.Data[i].ToString();
@@ -6800,9 +7261,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6800 return; 7261 return;
6801 } 7262 }
6802 7263
6803 // the rest of the permission checks are done in RezScript, so check the pin there as well 7264 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6804 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7265 if (dest != null)
7266 {
7267 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7268 {
7269 // the rest of the permission checks are done in RezScript, so check the pin there as well
7270 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6805 7271
7272 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7273 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7274 }
7275 }
6806 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7276 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6807 ScriptSleep(3000); 7277 ScriptSleep(3000);
6808 } 7278 }
@@ -6865,19 +7335,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6865 public LSL_String llMD5String(string src, int nonce) 7335 public LSL_String llMD5String(string src, int nonce)
6866 { 7336 {
6867 m_host.AddScriptLPS(1); 7337 m_host.AddScriptLPS(1);
6868 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7338 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6869 } 7339 }
6870 7340
6871 public LSL_String llSHA1String(string src) 7341 public LSL_String llSHA1String(string src)
6872 { 7342 {
6873 m_host.AddScriptLPS(1); 7343 m_host.AddScriptLPS(1);
6874 return Util.SHA1Hash(src).ToLower(); 7344 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6875 } 7345 }
6876 7346
6877 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7347 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6878 { 7348 {
6879 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7349 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6880 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7350 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7351 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7352 return shapeBlock;
6881 7353
6882 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7354 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6883 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7355 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6982,6 +7454,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6982 // Prim type box, cylinder and prism. 7454 // Prim type box, cylinder and prism.
6983 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) 7455 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)
6984 { 7456 {
7457 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7458 return;
7459
6985 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7460 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6986 ObjectShapePacket.ObjectDataBlock shapeBlock; 7461 ObjectShapePacket.ObjectDataBlock shapeBlock;
6987 7462
@@ -7035,6 +7510,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7035 // Prim type sphere. 7510 // Prim type sphere.
7036 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7511 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7037 { 7512 {
7513 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7514 return;
7515
7038 ObjectShapePacket.ObjectDataBlock shapeBlock; 7516 ObjectShapePacket.ObjectDataBlock shapeBlock;
7039 7517
7040 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7518 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7076,6 +7554,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7076 // Prim type torus, tube and ring. 7554 // Prim type torus, tube and ring.
7077 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) 7555 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)
7078 { 7556 {
7557 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7558 return;
7559
7079 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7560 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7080 ObjectShapePacket.ObjectDataBlock shapeBlock; 7561 ObjectShapePacket.ObjectDataBlock shapeBlock;
7081 7562
@@ -7211,6 +7692,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7211 // Prim type sculpt. 7692 // Prim type sculpt.
7212 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7693 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7213 { 7694 {
7695 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7696 return;
7697
7214 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7698 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7215 UUID sculptId; 7699 UUID sculptId;
7216 7700
@@ -7235,7 +7719,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7235 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7719 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7236 { 7720 {
7237 // default 7721 // default
7238 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7722 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7239 } 7723 }
7240 7724
7241 part.Shape.SetSculptProperties((byte)type, sculptId); 7725 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7252,46 +7736,309 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7252 ScriptSleep(200); 7736 ScriptSleep(200);
7253 } 7737 }
7254 7738
7255 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7739 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7256 { 7740 {
7257 m_host.AddScriptLPS(1); 7741 m_host.AddScriptLPS(1);
7258 7742
7259 setLinkPrimParams(linknumber, rules); 7743 setLinkPrimParams(linknumber, rules);
7744 }
7745
7746 private void setLinkPrimParams(int linknumber, LSL_List rules)
7747 {
7748 List<object> parts = new List<object>();
7749 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7750 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7751 foreach (SceneObjectPart p in prims)
7752 parts.Add(p);
7753 foreach (ScenePresence p in avatars)
7754 parts.Add(p);
7755
7756 LSL_List remaining = null;
7757
7758 if (parts.Count > 0)
7759 {
7760 foreach (object part in parts)
7761 {
7762 if (part is SceneObjectPart)
7763 remaining = SetPrimParams((SceneObjectPart)part, rules);
7764 else
7765 remaining = SetPrimParams((ScenePresence)part, rules);
7766 }
7767
7768 while((object)remaining != null && remaining.Length > 2)
7769 {
7770 linknumber = remaining.GetLSLIntegerItem(0);
7771 rules = remaining.GetSublist(1,-1);
7772 parts.Clear();
7773 prims = GetLinkParts(linknumber);
7774 avatars = GetLinkAvatars(linknumber);
7775 foreach (SceneObjectPart p in prims)
7776 parts.Add(p);
7777 foreach (ScenePresence p in avatars)
7778 parts.Add(p);
7779
7780 foreach (object part in parts)
7781 {
7782 if (part is SceneObjectPart)
7783 remaining = SetPrimParams((SceneObjectPart)part, rules);
7784 else
7785 remaining = SetPrimParams((ScenePresence)part, rules);
7786 }
7787 }
7788 }
7789 }
7790
7791 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7792 float material_density, float material_friction,
7793 float material_restitution, float material_gravity_modifier)
7794 {
7795 ExtraPhysicsData physdata = new ExtraPhysicsData();
7796 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7797 physdata.Density = part.Density;
7798 physdata.Friction = part.Friction;
7799 physdata.Bounce = part.Bounciness;
7800 physdata.GravitationModifier = part.GravityModifier;
7801
7802 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7803 physdata.Density = material_density;
7804 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7805 physdata.Friction = material_friction;
7806 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7807 physdata.Bounce = material_restitution;
7808 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7809 physdata.GravitationModifier = material_gravity_modifier;
7810
7811 part.UpdateExtraPhysics(physdata);
7812 }
7813
7814 public void llSetPhysicsMaterial(int material_bits,
7815 float material_gravity_modifier, float material_restitution,
7816 float material_friction, float material_density)
7817 {
7818 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7819 }
7260 7820
7821 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7822 {
7823 llSetLinkPrimitiveParamsFast(linknumber, rules);
7261 ScriptSleep(200); 7824 ScriptSleep(200);
7262 } 7825 }
7263 7826
7264 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7827 // vector up using libomv (c&p from sop )
7828 // vector up rotated by r
7829 private Vector3 Zrot(Quaternion r)
7265 { 7830 {
7266 m_host.AddScriptLPS(1); 7831 double x, y, z, m;
7267 7832
7268 setLinkPrimParams(linknumber, rules); 7833 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7834 if (Math.Abs(1.0 - m) > 0.000001)
7835 {
7836 m = 1.0 / Math.Sqrt(m);
7837 r.X *= (float)m;
7838 r.Y *= (float)m;
7839 r.Z *= (float)m;
7840 r.W *= (float)m;
7841 }
7842
7843 x = 2 * (r.X * r.Z + r.Y * r.W);
7844 y = 2 * (-r.X * r.W + r.Y * r.Z);
7845 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7846
7847 return new Vector3((float)x, (float)y, (float)z);
7269 } 7848 }
7270 7849
7271 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7850 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules)
7272 { 7851 {
7273 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7852 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7274 7853
7275 LSL_List remaining = null; 7854 int idx = 0;
7276 7855
7277 foreach (SceneObjectPart part in parts) 7856 bool positionChanged = false;
7278 remaining = SetPrimParams(part, rules); 7857 Vector3 finalPos = Vector3.Zero;
7279 7858
7280 while(remaining != null && remaining.Length > 2) 7859 try
7281 { 7860 {
7282 linknumber = remaining.GetLSLIntegerItem(0); 7861 while (idx < rules.Length)
7283 rules = remaining.GetSublist(1,-1); 7862 {
7284 parts = GetLinkParts(linknumber); 7863 int code = rules.GetLSLIntegerItem(idx++);
7864
7865 int remain = rules.Length - idx;
7866
7867 switch (code)
7868 {
7869 case (int)ScriptBaseClass.PRIM_POSITION:
7870 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7871 {
7872 if (remain < 1)
7873 return null;
7874
7875 LSL_Vector v;
7876 v = rules.GetVector3Item(idx++);
7877
7878 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7879 if (part == null)
7880 break;
7881
7882 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7883 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7884 if (part.LinkNum > 1)
7885 {
7886 localRot = GetPartLocalRot(part);
7887 localPos = GetPartLocalPos(part);
7888 }
7889
7890 v -= localPos;
7891 v /= localRot;
7892
7893 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7894
7895 v = v + 2 * sitOffset;
7896
7897 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7898 av.SendAvatarDataToAllAgents();
7899
7900 }
7901 break;
7902
7903 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7904 case (int)ScriptBaseClass.PRIM_ROTATION:
7905 {
7906 if (remain < 1)
7907 return null;
7908
7909 LSL_Rotation r;
7910 r = rules.GetQuaternionItem(idx++);
7911
7912 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7913 if (part == null)
7914 break;
7915
7916 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7917 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7918
7919 if (part.LinkNum > 1)
7920 localRot = GetPartLocalRot(part);
7921
7922 r = r * llGetRootRotation() / localRot;
7923 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7924 av.SendAvatarDataToAllAgents();
7925 }
7926 break;
7927
7928 // parse rest doing nothing but number of parameters error check
7929 case (int)ScriptBaseClass.PRIM_SIZE:
7930 case (int)ScriptBaseClass.PRIM_MATERIAL:
7931 case (int)ScriptBaseClass.PRIM_PHANTOM:
7932 case (int)ScriptBaseClass.PRIM_PHYSICS:
7933 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7934 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7935 case (int)ScriptBaseClass.PRIM_NAME:
7936 case (int)ScriptBaseClass.PRIM_DESC:
7937 if (remain < 1)
7938 return null;
7939 idx++;
7940 break;
7941
7942 case (int)ScriptBaseClass.PRIM_GLOW:
7943 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7944 case (int)ScriptBaseClass.PRIM_TEXGEN:
7945 if (remain < 2)
7946 return null;
7947 idx += 2;
7948 break;
7949
7950 case (int)ScriptBaseClass.PRIM_TYPE:
7951 if (remain < 3)
7952 return null;
7953 code = (int)rules.GetLSLIntegerItem(idx++);
7954 remain = rules.Length - idx;
7955 switch (code)
7956 {
7957 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7958 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7959 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7960 if (remain < 6)
7961 return null;
7962 idx += 6;
7963 break;
7964
7965 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7966 if (remain < 5)
7967 return null;
7968 idx += 5;
7969 break;
7970
7971 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7972 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7973 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7974 if (remain < 11)
7975 return null;
7976 idx += 11;
7977 break;
7978
7979 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7980 if (remain < 2)
7981 return null;
7982 idx += 2;
7983 break;
7984 }
7985 break;
7986
7987 case (int)ScriptBaseClass.PRIM_COLOR:
7988 case (int)ScriptBaseClass.PRIM_TEXT:
7989 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7990 case (int)ScriptBaseClass.PRIM_OMEGA:
7991 if (remain < 3)
7992 return null;
7993 idx += 3;
7994 break;
7995
7996 case (int)ScriptBaseClass.PRIM_TEXTURE:
7997 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7998 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
7999 if (remain < 5)
8000 return null;
8001 idx += 5;
8002 break;
8003
8004 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8005 if (remain < 7)
8006 return null;
8007
8008 idx += 7;
8009 break;
8010
8011 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8012 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
8013 return null;
7285 8014
7286 foreach (SceneObjectPart part in parts) 8015 return rules.GetSublist(idx, -1);
7287 remaining = SetPrimParams(part, rules); 8016 }
8017 }
7288 } 8018 }
8019
8020 finally
8021 {
8022 if (positionChanged)
8023 {
8024 av.OffsetPosition = finalPos;
8025// av.SendAvatarDataToAllAgents();
8026 av.SendTerseUpdateToAllClients();
8027 positionChanged = false;
8028 }
8029 }
8030 return null;
7289 } 8031 }
7290 8032
7291 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules) 8033 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules)
7292 { 8034 {
8035 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8036 return null;
8037
7293 int idx = 0; 8038 int idx = 0;
7294 8039
8040 SceneObjectGroup parentgrp = part.ParentGroup;
8041
7295 bool positionChanged = false; 8042 bool positionChanged = false;
7296 LSL_Vector currentPosition = GetPartLocalPos(part); 8043 LSL_Vector currentPosition = GetPartLocalPos(part);
7297 8044
@@ -7314,8 +8061,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7314 return null; 8061 return null;
7315 8062
7316 v=rules.GetVector3Item(idx++); 8063 v=rules.GetVector3Item(idx++);
7317 positionChanged = true;
7318 currentPosition = GetSetPosTarget(part, v, currentPosition); 8064 currentPosition = GetSetPosTarget(part, v, currentPosition);
8065 positionChanged = true;
7319 8066
7320 break; 8067 break;
7321 case (int)ScriptBaseClass.PRIM_SIZE: 8068 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7331,8 +8078,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7331 return null; 8078 return null;
7332 8079
7333 LSL_Rotation q = rules.GetQuaternionItem(idx++); 8080 LSL_Rotation q = rules.GetQuaternionItem(idx++);
8081 SceneObjectPart rootPart = parentgrp.RootPart;
7334 // try to let this work as in SL... 8082 // try to let this work as in SL...
7335 if (part.ParentID == 0) 8083 if (rootPart == part)
7336 { 8084 {
7337 // special case: If we are root, rotate complete SOG to new rotation 8085 // special case: If we are root, rotate complete SOG to new rotation
7338 SetRot(part, Rot2Quaternion(q)); 8086 SetRot(part, Rot2Quaternion(q));
@@ -7340,7 +8088,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7340 else 8088 else
7341 { 8089 {
7342 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 8090 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7343 SceneObjectPart rootPart = part.ParentGroup.RootPart; 8091 // sounds like sl bug that we need to replicate
7344 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 8092 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7345 } 8093 }
7346 8094
@@ -7593,7 +8341,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7593 return null; 8341 return null;
7594 8342
7595 string ph = rules.Data[idx++].ToString(); 8343 string ph = rules.Data[idx++].ToString();
7596 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8344 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7597 8345
7598 break; 8346 break;
7599 8347
@@ -7611,12 +8359,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7611 part.ScriptSetPhysicsStatus(physics); 8359 part.ScriptSetPhysicsStatus(physics);
7612 break; 8360 break;
7613 8361
8362 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8363 if (remain < 1)
8364 return null;
8365
8366 int shape_type = rules.GetLSLIntegerItem(idx++);
8367
8368 ExtraPhysicsData physdata = new ExtraPhysicsData();
8369 physdata.Density = part.Density;
8370 physdata.Bounce = part.Bounciness;
8371 physdata.GravitationModifier = part.GravityModifier;
8372 physdata.PhysShapeType = (PhysShapeType)shape_type;
8373
8374 part.UpdateExtraPhysics(physdata);
8375
8376 break;
8377
8378 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8379 if (remain < 5)
8380 return null;
8381
8382 int material_bits = rules.GetLSLIntegerItem(idx++);
8383 float material_density = (float)rules.GetLSLFloatItem(idx++);
8384 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8385 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8386 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8387
8388 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8389
8390 break;
8391
7614 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8392 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7615 if (remain < 1) 8393 if (remain < 1)
7616 return null; 8394 return null;
7617 string temp = rules.Data[idx++].ToString(); 8395 string temp = rules.Data[idx++].ToString();
7618 8396
7619 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8397 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7620 8398
7621 break; 8399 break;
7622 8400
@@ -7691,7 +8469,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7691 if (part.ParentGroup.RootPart == part) 8469 if (part.ParentGroup.RootPart == part)
7692 { 8470 {
7693 SceneObjectGroup parent = part.ParentGroup; 8471 SceneObjectGroup parent = part.ParentGroup;
7694 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8472 Util.FireAndForget(delegate(object x) {
8473 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8474 });
7695 } 8475 }
7696 else 8476 else
7697 { 8477 {
@@ -7736,10 +8516,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7736 8516
7737 public LSL_String llXorBase64Strings(string str1, string str2) 8517 public LSL_String llXorBase64Strings(string str1, string str2)
7738 { 8518 {
7739 m_host.AddScriptLPS(1); 8519 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7740 Deprecated("llXorBase64Strings"); 8520
7741 ScriptSleep(300); 8521 ScriptSleep(300);
7742 return String.Empty; 8522 m_host.AddScriptLPS(1);
8523
8524 if (str1 == String.Empty)
8525 return String.Empty;
8526 if (str2 == String.Empty)
8527 return str1;
8528
8529 int len = str2.Length;
8530 if ((len % 4) != 0) // LL is EVIL!!!!
8531 {
8532 while (str2.EndsWith("="))
8533 str2 = str2.Substring(0, str2.Length - 1);
8534
8535 len = str2.Length;
8536 int mod = len % 4;
8537
8538 if (mod == 1)
8539 str2 = str2.Substring(0, str2.Length - 1);
8540 else if (mod == 2)
8541 str2 += "==";
8542 else if (mod == 3)
8543 str2 += "=";
8544 }
8545
8546 byte[] data1;
8547 byte[] data2;
8548 try
8549 {
8550 data1 = Convert.FromBase64String(str1);
8551 data2 = Convert.FromBase64String(str2);
8552 }
8553 catch (Exception)
8554 {
8555 return new LSL_String(String.Empty);
8556 }
8557
8558 // For cases where the decoded length of s2 is greater
8559 // than the decoded length of s1, simply perform a normal
8560 // decode and XOR
8561 //
8562 if (data2.Length >= data1.Length)
8563 {
8564 for (int pos = 0 ; pos < data1.Length ; pos++ )
8565 data1[pos] ^= data2[pos];
8566
8567 return Convert.ToBase64String(data1);
8568 }
8569
8570 // Remove padding
8571 while (str1.EndsWith("="))
8572 str1 = str1.Substring(0, str1.Length - 1);
8573 while (str2.EndsWith("="))
8574 str2 = str2.Substring(0, str2.Length - 1);
8575
8576 byte[] d1 = new byte[str1.Length];
8577 byte[] d2 = new byte[str2.Length];
8578
8579 for (int i = 0 ; i < str1.Length ; i++)
8580 {
8581 int idx = b64.IndexOf(str1.Substring(i, 1));
8582 if (idx == -1)
8583 idx = 0;
8584 d1[i] = (byte)idx;
8585 }
8586
8587 for (int i = 0 ; i < str2.Length ; i++)
8588 {
8589 int idx = b64.IndexOf(str2.Substring(i, 1));
8590 if (idx == -1)
8591 idx = 0;
8592 d2[i] = (byte)idx;
8593 }
8594
8595 string output = String.Empty;
8596
8597 for (int pos = 0 ; pos < d1.Length ; pos++)
8598 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8599
8600 while (output.Length % 3 > 0)
8601 output += "=";
8602
8603 return output;
7743 } 8604 }
7744 8605
7745 public void llRemoteDataSetRegion() 8606 public void llRemoteDataSetRegion()
@@ -7863,13 +8724,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7863 public LSL_Integer llGetNumberOfPrims() 8724 public LSL_Integer llGetNumberOfPrims()
7864 { 8725 {
7865 m_host.AddScriptLPS(1); 8726 m_host.AddScriptLPS(1);
7866 int avatarCount = 0; 8727 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7867 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8728
7868 {
7869 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7870 avatarCount++;
7871 });
7872
7873 return m_host.ParentGroup.PrimCount + avatarCount; 8729 return m_host.ParentGroup.PrimCount + avatarCount;
7874 } 8730 }
7875 8731
@@ -7885,55 +8741,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7885 m_host.AddScriptLPS(1); 8741 m_host.AddScriptLPS(1);
7886 UUID objID = UUID.Zero; 8742 UUID objID = UUID.Zero;
7887 LSL_List result = new LSL_List(); 8743 LSL_List result = new LSL_List();
8744
8745 // If the ID is not valid, return null result
7888 if (!UUID.TryParse(obj, out objID)) 8746 if (!UUID.TryParse(obj, out objID))
7889 { 8747 {
7890 result.Add(new LSL_Vector()); 8748 result.Add(new LSL_Vector());
7891 result.Add(new LSL_Vector()); 8749 result.Add(new LSL_Vector());
7892 return result; 8750 return result;
7893 } 8751 }
8752
8753 // Check if this is an attached prim. If so, replace
8754 // the UUID with the avatar UUID and report it's bounding box
8755 SceneObjectPart part = World.GetSceneObjectPart(objID);
8756 if (part != null && part.ParentGroup.IsAttachment)
8757 objID = part.ParentGroup.AttachedAvatar;
8758
8759 // Find out if this is an avatar ID. If so, return it's box
7894 ScenePresence presence = World.GetScenePresence(objID); 8760 ScenePresence presence = World.GetScenePresence(objID);
7895 if (presence != null) 8761 if (presence != null)
7896 { 8762 {
7897 if (presence.ParentID == 0) // not sat on an object 8763 // As per LSL Wiki, there is no difference between sitting
8764 // and standing avatar since server 1.36
8765 LSL_Vector lower;
8766 LSL_Vector upper;
8767 if (presence.Animator.Animations.DefaultAnimation.AnimID
8768 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7898 { 8769 {
7899 LSL_Vector lower; 8770 // This is for ground sitting avatars
7900 LSL_Vector upper; 8771 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7901 if (presence.Animator.Animations.DefaultAnimation.AnimID 8772 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7902 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8773 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7903 {
7904 // This is for ground sitting avatars
7905 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7906 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7907 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7908 }
7909 else
7910 {
7911 // This is for standing/flying avatars
7912 float height = presence.Appearance.AvatarHeight / 2.0f;
7913 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7914 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7915 }
7916 result.Add(lower);
7917 result.Add(upper);
7918 return result;
7919 } 8774 }
7920 else 8775 else
7921 { 8776 {
7922 // sitting on an object so we need the bounding box of that 8777 // This is for standing/flying avatars
7923 // which should include the avatar so set the UUID to the 8778 float height = presence.Appearance.AvatarHeight / 2.0f;
7924 // UUID of the object the avatar is sat on and allow it to fall through 8779 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7925 // to processing an object 8780 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7926 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7927 objID = p.UUID;
7928 } 8781 }
8782
8783 // Adjust to the documented error offsets (see LSL Wiki)
8784 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8785 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8786
8787 if (lower.x > upper.x)
8788 lower.x = upper.x;
8789 if (lower.y > upper.y)
8790 lower.y = upper.y;
8791 if (lower.z > upper.z)
8792 lower.z = upper.z;
8793
8794 result.Add(lower);
8795 result.Add(upper);
8796 return result;
7929 } 8797 }
7930 SceneObjectPart part = World.GetSceneObjectPart(objID); 8798
8799 part = World.GetSceneObjectPart(objID);
7931 // Currently only works for single prims without a sitting avatar 8800 // Currently only works for single prims without a sitting avatar
7932 if (part != null) 8801 if (part != null)
7933 { 8802 {
7934 Vector3 halfSize = part.Scale / 2.0f; 8803 float minX;
7935 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8804 float maxX;
7936 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8805 float minY;
8806 float maxY;
8807 float minZ;
8808 float maxZ;
8809
8810 // This BBox is in sim coordinates, with the offset being
8811 // a contained point.
8812 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8813 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8814
8815 minX -= offsets[0].X;
8816 maxX -= offsets[0].X;
8817 minY -= offsets[0].Y;
8818 maxY -= offsets[0].Y;
8819 minZ -= offsets[0].Z;
8820 maxZ -= offsets[0].Z;
8821
8822 LSL_Vector lower;
8823 LSL_Vector upper;
8824
8825 // Adjust to the documented error offsets (see LSL Wiki)
8826 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8827 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8828
8829 if (lower.x > upper.x)
8830 lower.x = upper.x;
8831 if (lower.y > upper.y)
8832 lower.y = upper.y;
8833 if (lower.z > upper.z)
8834 lower.z = upper.z;
8835
7937 result.Add(lower); 8836 result.Add(lower);
7938 result.Add(upper); 8837 result.Add(upper);
7939 return result; 8838 return result;
@@ -7947,7 +8846,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7947 8846
7948 public LSL_Vector llGetGeometricCenter() 8847 public LSL_Vector llGetGeometricCenter()
7949 { 8848 {
7950 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8849 Vector3 tmp = m_host.GetGeometricCenter();
8850 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7951 } 8851 }
7952 8852
7953 public LSL_List llGetPrimitiveParams(LSL_List rules) 8853 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7960,16 +8860,291 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7960 { 8860 {
7961 m_host.AddScriptLPS(1); 8861 m_host.AddScriptLPS(1);
7962 8862
8863 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8864 // keep other options as before
8865
7963 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8866 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8867 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7964 8868
7965 LSL_List res = new LSL_List(); 8869 LSL_List res = new LSL_List();
7966 8870
7967 foreach (var part in parts) 8871 if (parts.Count > 0)
8872 {
8873 foreach (var part in parts)
8874 {
8875 LSL_List partRes = GetLinkPrimitiveParams(part, rules);
8876 res += partRes;
8877 }
8878 }
8879 if (avatars.Count > 0)
7968 { 8880 {
7969 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8881 foreach (ScenePresence avatar in avatars)
7970 res += partRes; 8882 {
8883 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules);
8884 res += avaRes;
8885 }
7971 } 8886 }
8887 return res;
8888 }
8889
8890 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8891 {
8892 // avatars case
8893 // replies as SL wiki
8894
8895 LSL_List res = new LSL_List();
8896// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8897 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8898
8899 int idx = 0;
8900 while (idx < rules.Length)
8901 {
8902 int code = (int)rules.GetLSLIntegerItem(idx++);
8903 int remain = rules.Length - idx;
8904
8905 switch (code)
8906 {
8907 case (int)ScriptBaseClass.PRIM_MATERIAL:
8908 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
8909 break;
8910
8911 case (int)ScriptBaseClass.PRIM_PHYSICS:
8912 res.Add(new LSL_Integer(0));
8913 break;
8914
8915 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8916 res.Add(new LSL_Integer(0));
8917 break;
7972 8918
8919 case (int)ScriptBaseClass.PRIM_PHANTOM:
8920 res.Add(new LSL_Integer(0));
8921 break;
8922
8923 case (int)ScriptBaseClass.PRIM_POSITION:
8924
8925 Vector3 pos = avatar.OffsetPosition;
8926
8927 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8928 pos -= sitOffset;
8929
8930 if( sitPart != null)
8931 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8932
8933 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8934 break;
8935
8936 case (int)ScriptBaseClass.PRIM_SIZE:
8937 // as in llGetAgentSize above
8938 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8939 break;
8940
8941 case (int)ScriptBaseClass.PRIM_ROTATION:
8942 Quaternion rot = avatar.Rotation;
8943 if (sitPart != null)
8944 {
8945 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8946 }
8947
8948 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8949 break;
8950
8951 case (int)ScriptBaseClass.PRIM_TYPE:
8952 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8953 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8954 res.Add(new LSL_Vector(0f,1.0f,0f));
8955 res.Add(new LSL_Float(0.0f));
8956 res.Add(new LSL_Vector(0, 0, 0));
8957 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8958 res.Add(new LSL_Vector(0, 0, 0));
8959 break;
8960
8961 case (int)ScriptBaseClass.PRIM_TEXTURE:
8962 if (remain < 1)
8963 return res;
8964
8965 int face = (int)rules.GetLSLIntegerItem(idx++);
8966 if (face == ScriptBaseClass.ALL_SIDES)
8967 {
8968 for (face = 0; face < 21; face++)
8969 {
8970 res.Add(new LSL_String(""));
8971 res.Add(new LSL_Vector(0,0,0));
8972 res.Add(new LSL_Vector(0,0,0));
8973 res.Add(new LSL_Float(0.0));
8974 }
8975 }
8976 else
8977 {
8978 if (face >= 0 && face < 21)
8979 {
8980 res.Add(new LSL_String(""));
8981 res.Add(new LSL_Vector(0,0,0));
8982 res.Add(new LSL_Vector(0,0,0));
8983 res.Add(new LSL_Float(0.0));
8984 }
8985 }
8986 break;
8987
8988 case (int)ScriptBaseClass.PRIM_COLOR:
8989 if (remain < 1)
8990 return res;
8991
8992 face = (int)rules.GetLSLIntegerItem(idx++);
8993
8994 if (face == ScriptBaseClass.ALL_SIDES)
8995 {
8996 for (face = 0; face < 21; face++)
8997 {
8998 res.Add(new LSL_Vector(0,0,0));
8999 res.Add(new LSL_Float(0));
9000 }
9001 }
9002 else
9003 {
9004 res.Add(new LSL_Vector(0,0,0));
9005 res.Add(new LSL_Float(0));
9006 }
9007 break;
9008
9009 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
9010 if (remain < 1)
9011 return res;
9012 face = (int)rules.GetLSLIntegerItem(idx++);
9013
9014 if (face == ScriptBaseClass.ALL_SIDES)
9015 {
9016 for (face = 0; face < 21; face++)
9017 {
9018 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
9019 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
9020 }
9021 }
9022 else
9023 {
9024 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
9025 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
9026 }
9027 break;
9028
9029 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
9030 if (remain < 1)
9031 return res;
9032 face = (int)rules.GetLSLIntegerItem(idx++);
9033
9034 if (face == ScriptBaseClass.ALL_SIDES)
9035 {
9036 for (face = 0; face < 21; face++)
9037 {
9038 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9039 }
9040 }
9041 else
9042 {
9043 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9044 }
9045 break;
9046
9047 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
9048 res.Add(new LSL_Integer(0));
9049 res.Add(new LSL_Integer(0));// softness
9050 res.Add(new LSL_Float(0.0f)); // gravity
9051 res.Add(new LSL_Float(0.0f)); // friction
9052 res.Add(new LSL_Float(0.0f)); // wind
9053 res.Add(new LSL_Float(0.0f)); // tension
9054 res.Add(new LSL_Vector(0f,0f,0f));
9055 break;
9056
9057 case (int)ScriptBaseClass.PRIM_TEXGEN:
9058 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9059 if (remain < 1)
9060 return res;
9061 face = (int)rules.GetLSLIntegerItem(idx++);
9062
9063 if (face == ScriptBaseClass.ALL_SIDES)
9064 {
9065 for (face = 0; face < 21; face++)
9066 {
9067 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9068 }
9069 }
9070 else
9071 {
9072 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9073 }
9074 break;
9075
9076 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
9077 res.Add(new LSL_Integer(0));
9078 res.Add(new LSL_Vector(0f,0f,0f));
9079 res.Add(new LSL_Float(0f)); // intensity
9080 res.Add(new LSL_Float(0f)); // radius
9081 res.Add(new LSL_Float(0f)); // falloff
9082 break;
9083
9084 case (int)ScriptBaseClass.PRIM_GLOW:
9085 if (remain < 1)
9086 return res;
9087 face = (int)rules.GetLSLIntegerItem(idx++);
9088
9089 if (face == ScriptBaseClass.ALL_SIDES)
9090 {
9091 for (face = 0; face < 21; face++)
9092 {
9093 res.Add(new LSL_Float(0f));
9094 }
9095 }
9096 else
9097 {
9098 res.Add(new LSL_Float(0f));
9099 }
9100 break;
9101
9102 case (int)ScriptBaseClass.PRIM_TEXT:
9103 res.Add(new LSL_String(""));
9104 res.Add(new LSL_Vector(0f,0f,0f));
9105 res.Add(new LSL_Float(1.0f));
9106 break;
9107
9108 case (int)ScriptBaseClass.PRIM_NAME:
9109 res.Add(new LSL_String(avatar.Name));
9110 break;
9111
9112 case (int)ScriptBaseClass.PRIM_DESC:
9113 res.Add(new LSL_String(""));
9114 break;
9115
9116 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9117 Quaternion lrot = avatar.Rotation;
9118
9119 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9120 {
9121 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9122 }
9123 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9124 break;
9125
9126 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9127 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9128 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9129 lpos -= lsitOffset;
9130
9131 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9132 {
9133 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9134 }
9135 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9136 break;
9137
9138 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9139 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9140 return res;
9141 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9142 LSL_List new_rules = rules.GetSublist(idx, -1);
9143
9144 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9145 return res;
9146 }
9147 }
7973 return res; 9148 return res;
7974 } 9149 }
7975 9150
@@ -8013,13 +9188,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8013 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 9188 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8014 part.AbsolutePosition.Y, 9189 part.AbsolutePosition.Y,
8015 part.AbsolutePosition.Z); 9190 part.AbsolutePosition.Z);
8016 // For some reason, the part.AbsolutePosition.* values do not change if the
8017 // linkset is rotated; they always reflect the child prim's world position
8018 // as though the linkset is unrotated. This is incompatible behavior with SL's
8019 // implementation, so will break scripts imported from there (not to mention it
8020 // makes it more difficult to determine a child prim's actual inworld position).
8021 if (part.ParentID != 0)
8022 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8023 res.Add(v); 9191 res.Add(v);
8024 break; 9192 break;
8025 9193
@@ -8190,56 +9358,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8190 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 9358 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8191 if (remain < 1) 9359 if (remain < 1)
8192 return res; 9360 return res;
8193 9361 face = (int)rules.GetLSLIntegerItem(idx++);
8194 face=(int)rules.GetLSLIntegerItem(idx++);
8195 9362
8196 tex = part.Shape.Textures; 9363 tex = part.Shape.Textures;
9364 int shiny;
8197 if (face == ScriptBaseClass.ALL_SIDES) 9365 if (face == ScriptBaseClass.ALL_SIDES)
8198 { 9366 {
8199 for (face = 0; face < GetNumberOfSides(part); face++) 9367 for (face = 0; face < GetNumberOfSides(part); face++)
8200 { 9368 {
8201 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9369 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8202 // Convert Shininess to PRIM_SHINY_* 9370 if (shinyness == Shininess.High)
8203 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9371 {
8204 // PRIM_BUMP_* 9372 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8205 res.Add(new LSL_Integer((int)texface.Bump)); 9373 }
9374 else if (shinyness == Shininess.Medium)
9375 {
9376 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9377 }
9378 else if (shinyness == Shininess.Low)
9379 {
9380 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9381 }
9382 else
9383 {
9384 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9385 }
9386 res.Add(new LSL_Integer(shiny));
9387 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8206 } 9388 }
8207 } 9389 }
8208 else 9390 else
8209 { 9391 {
8210 if (face >= 0 && face < GetNumberOfSides(part)) 9392 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9393 if (shinyness == Shininess.High)
8211 { 9394 {
8212 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9395 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8213 // Convert Shininess to PRIM_SHINY_* 9396 }
8214 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9397 else if (shinyness == Shininess.Medium)
8215 // PRIM_BUMP_* 9398 {
8216 res.Add(new LSL_Integer((int)texface.Bump)); 9399 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9400 }
9401 else if (shinyness == Shininess.Low)
9402 {
9403 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9404 }
9405 else
9406 {
9407 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8217 } 9408 }
9409 res.Add(new LSL_Integer(shiny));
9410 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8218 } 9411 }
8219 break; 9412 break;
8220 9413
8221 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 9414 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8222 if (remain < 1) 9415 if (remain < 1)
8223 return res; 9416 return res;
8224 9417 face = (int)rules.GetLSLIntegerItem(idx++);
8225 face=(int)rules.GetLSLIntegerItem(idx++);
8226 9418
8227 tex = part.Shape.Textures; 9419 tex = part.Shape.Textures;
9420 int fullbright;
8228 if (face == ScriptBaseClass.ALL_SIDES) 9421 if (face == ScriptBaseClass.ALL_SIDES)
8229 { 9422 {
8230 for (face = 0; face < GetNumberOfSides(part); face++) 9423 for (face = 0; face < GetNumberOfSides(part); face++)
8231 { 9424 {
8232 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9425 if (tex.GetFace((uint)face).Fullbright == true)
8233 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9426 {
9427 fullbright = ScriptBaseClass.TRUE;
9428 }
9429 else
9430 {
9431 fullbright = ScriptBaseClass.FALSE;
9432 }
9433 res.Add(new LSL_Integer(fullbright));
8234 } 9434 }
8235 } 9435 }
8236 else 9436 else
8237 { 9437 {
8238 if (face >= 0 && face < GetNumberOfSides(part)) 9438 if (tex.GetFace((uint)face).Fullbright == true)
8239 { 9439 {
8240 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9440 fullbright = ScriptBaseClass.TRUE;
8241 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9441 }
9442 else
9443 {
9444 fullbright = ScriptBaseClass.FALSE;
8242 } 9445 }
9446 res.Add(new LSL_Integer(fullbright));
8243 } 9447 }
8244 break; 9448 break;
8245 9449
@@ -8261,27 +9465,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8261 break; 9465 break;
8262 9466
8263 case (int)ScriptBaseClass.PRIM_TEXGEN: 9467 case (int)ScriptBaseClass.PRIM_TEXGEN:
9468 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8264 if (remain < 1) 9469 if (remain < 1)
8265 return res; 9470 return res;
8266 9471 face = (int)rules.GetLSLIntegerItem(idx++);
8267 face=(int)rules.GetLSLIntegerItem(idx++);
8268 9472
8269 tex = part.Shape.Textures; 9473 tex = part.Shape.Textures;
8270 if (face == ScriptBaseClass.ALL_SIDES) 9474 if (face == ScriptBaseClass.ALL_SIDES)
8271 { 9475 {
8272 for (face = 0; face < GetNumberOfSides(part); face++) 9476 for (face = 0; face < GetNumberOfSides(part); face++)
8273 { 9477 {
8274 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9478 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8275 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9479 {
8276 res.Add(new LSL_Integer((uint)texgen >> 1)); 9480 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9481 }
9482 else
9483 {
9484 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9485 }
8277 } 9486 }
8278 } 9487 }
8279 else 9488 else
8280 { 9489 {
8281 if (face >= 0 && face < GetNumberOfSides(part)) 9490 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9491 {
9492 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9493 }
9494 else
8282 { 9495 {
8283 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9496 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8284 res.Add(new LSL_Integer((uint)texgen >> 1));
8285 } 9497 }
8286 } 9498 }
8287 break; 9499 break;
@@ -8304,25 +9516,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8304 case (int)ScriptBaseClass.PRIM_GLOW: 9516 case (int)ScriptBaseClass.PRIM_GLOW:
8305 if (remain < 1) 9517 if (remain < 1)
8306 return res; 9518 return res;
8307 9519 face = (int)rules.GetLSLIntegerItem(idx++);
8308 face=(int)rules.GetLSLIntegerItem(idx++);
8309 9520
8310 tex = part.Shape.Textures; 9521 tex = part.Shape.Textures;
9522 float primglow;
8311 if (face == ScriptBaseClass.ALL_SIDES) 9523 if (face == ScriptBaseClass.ALL_SIDES)
8312 { 9524 {
8313 for (face = 0; face < GetNumberOfSides(part); face++) 9525 for (face = 0; face < GetNumberOfSides(part); face++)
8314 { 9526 {
8315 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9527 primglow = tex.GetFace((uint)face).Glow;
8316 res.Add(new LSL_Float(texface.Glow)); 9528 res.Add(new LSL_Float(primglow));
8317 } 9529 }
8318 } 9530 }
8319 else 9531 else
8320 { 9532 {
8321 if (face >= 0 && face < GetNumberOfSides(part)) 9533 primglow = tex.GetFace((uint)face).Glow;
8322 { 9534 res.Add(new LSL_Float(primglow));
8323 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8324 res.Add(new LSL_Float(texface.Glow));
8325 }
8326 } 9535 }
8327 break; 9536 break;
8328 9537
@@ -8334,18 +9543,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8334 textColor.B)); 9543 textColor.B));
8335 res.Add(new LSL_Float(textColor.A)); 9544 res.Add(new LSL_Float(textColor.A));
8336 break; 9545 break;
9546
8337 case (int)ScriptBaseClass.PRIM_NAME: 9547 case (int)ScriptBaseClass.PRIM_NAME:
8338 res.Add(new LSL_String(part.Name)); 9548 res.Add(new LSL_String(part.Name));
8339 break; 9549 break;
9550
8340 case (int)ScriptBaseClass.PRIM_DESC: 9551 case (int)ScriptBaseClass.PRIM_DESC:
8341 res.Add(new LSL_String(part.Description)); 9552 res.Add(new LSL_String(part.Description));
8342 break; 9553 break;
9554
8343 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9555 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8344 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9556 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8345 break; 9557 break;
9558
8346 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9559 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8347 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9560 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8348 break; 9561 break;
9562 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9563 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9564 return res;
9565 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9566 LSL_List new_rules = rules.GetSublist(idx, -1);
9567 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9568 res += tres;
9569 return res;
8349 case (int)ScriptBaseClass.PRIM_SLICE: 9570 case (int)ScriptBaseClass.PRIM_SLICE:
8350 PrimType prim_type = part.GetPrimType(); 9571 PrimType prim_type = part.GetPrimType();
8351 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING); 9572 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING);
@@ -8947,8 +10168,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8947 // The function returns an ordered list 10168 // The function returns an ordered list
8948 // representing the tokens found in the supplied 10169 // representing the tokens found in the supplied
8949 // sources string. If two successive tokenizers 10170 // sources string. If two successive tokenizers
8950 // are encountered, then a NULL entry is added 10171 // are encountered, then a null-string entry is
8951 // to the list. 10172 // added to the list.
8952 // 10173 //
8953 // It is a precondition that the source and 10174 // It is a precondition that the source and
8954 // toekizer lisst are non-null. If they are null, 10175 // toekizer lisst are non-null. If they are null,
@@ -8956,7 +10177,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8956 // while their lengths are being determined. 10177 // while their lengths are being determined.
8957 // 10178 //
8958 // A small amount of working memoryis required 10179 // A small amount of working memoryis required
8959 // of approximately 8*#tokenizers. 10180 // of approximately 8*#tokenizers + 8*srcstrlen.
8960 // 10181 //
8961 // There are many ways in which this function 10182 // There are many ways in which this function
8962 // can be implemented, this implementation is 10183 // can be implemented, this implementation is
@@ -8972,155 +10193,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8972 // and eliminates redundant tokenizers as soon 10193 // and eliminates redundant tokenizers as soon
8973 // as is possible. 10194 // as is possible.
8974 // 10195 //
8975 // The implementation tries to avoid any copying 10196 // The implementation tries to minimize temporary
8976 // of arrays or other objects. 10197 // garbage generation.
8977 // </remarks> 10198 // </remarks>
8978 10199
8979 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 10200 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8980 { 10201 {
8981 int beginning = 0; 10202 return ParseString2List(src, separators, spacers, true);
8982 int srclen = src.Length; 10203 }
8983 int seplen = separators.Length;
8984 object[] separray = separators.Data;
8985 int spclen = spacers.Length;
8986 object[] spcarray = spacers.Data;
8987 int mlen = seplen+spclen;
8988
8989 int[] offset = new int[mlen+1];
8990 bool[] active = new bool[mlen];
8991
8992 int best;
8993 int j;
8994
8995 // Initial capacity reduces resize cost
8996 10204
8997 LSL_List tokens = new LSL_List(); 10205 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
10206 {
10207 int srclen = src.Length;
10208 int seplen = separators.Length;
10209 object[] separray = separators.Data;
10210 int spclen = spacers.Length;
10211 object[] spcarray = spacers.Data;
10212 int dellen = 0;
10213 string[] delarray = new string[seplen+spclen];
8998 10214
8999 // All entries are initially valid 10215 int outlen = 0;
10216 string[] outarray = new string[srclen*2+1];
9000 10217
9001 for (int i = 0; i < mlen; i++) 10218 int i, j;
9002 active[i] = true; 10219 string d;
9003 10220
9004 offset[mlen] = srclen; 10221 m_host.AddScriptLPS(1);
9005 10222
9006 while (beginning < srclen) 10223 /*
10224 * Convert separator and spacer lists to C# strings.
10225 * Also filter out null strings so we don't hang.
10226 */
10227 for (i = 0; i < seplen; i ++)
9007 { 10228 {
10229 d = separray[i].ToString();
10230 if (d.Length > 0)
10231 {
10232 delarray[dellen++] = d;
10233 }
10234 }
10235 seplen = dellen;
9008 10236
9009 best = mlen; // as bad as it gets 10237 for (i = 0; i < spclen; i ++)
10238 {
10239 d = spcarray[i].ToString();
10240 if (d.Length > 0)
10241 {
10242 delarray[dellen++] = d;
10243 }
10244 }
9010 10245
9011 // Scan for separators 10246 /*
10247 * Scan through source string from beginning to end.
10248 */
10249 for (i = 0;;)
10250 {
9012 10251
9013 for (j = 0; j < seplen; j++) 10252 /*
10253 * Find earliest delimeter in src starting at i (if any).
10254 */
10255 int earliestDel = -1;
10256 int earliestSrc = srclen;
10257 string earliestStr = null;
10258 for (j = 0; j < dellen; j ++)
9014 { 10259 {
9015 if (separray[j].ToString() == String.Empty) 10260 d = delarray[j];
9016 active[j] = false; 10261 if (d != null)
9017
9018 if (active[j])
9019 { 10262 {
9020 // scan all of the markers 10263 int index = src.IndexOf(d, i);
9021 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10264 if (index < 0)
9022 { 10265 {
9023 // not present at all 10266 delarray[j] = null; // delim nowhere in src, don't check it anymore
9024 active[j] = false;
9025 } 10267 }
9026 else 10268 else if (index < earliestSrc)
9027 { 10269 {
9028 // present and correct 10270 earliestSrc = index; // where delimeter starts in source string
9029 if (offset[j] < offset[best]) 10271 earliestDel = j; // where delimeter is in delarray[]
9030 { 10272 earliestStr = d; // the delimeter string from delarray[]
9031 // closest so far 10273 if (index == i) break; // can't do any better than found at beg of string
9032 best = j;
9033 if (offset[best] == beginning)
9034 break;
9035 }
9036 } 10274 }
9037 } 10275 }
9038 } 10276 }
9039 10277
9040 // Scan for spacers 10278 /*
9041 10279 * Output source string starting at i through start of earliest delimeter.
9042 if (offset[best] != beginning) 10280 */
10281 if (keepNulls || (earliestSrc > i))
9043 { 10282 {
9044 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10283 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9045 {
9046 if (spcarray[j-seplen].ToString() == String.Empty)
9047 active[j] = false;
9048
9049 if (active[j])
9050 {
9051 // scan all of the markers
9052 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9053 {
9054 // not present at all
9055 active[j] = false;
9056 }
9057 else
9058 {
9059 // present and correct
9060 if (offset[j] < offset[best])
9061 {
9062 // closest so far
9063 best = j;
9064 }
9065 }
9066 }
9067 }
9068 } 10284 }
9069 10285
9070 // This is the normal exit from the scanning loop 10286 /*
10287 * If no delimeter found at or after i, we're done scanning.
10288 */
10289 if (earliestDel < 0) break;
9071 10290
9072 if (best == mlen) 10291 /*
10292 * If delimeter was a spacer, output the spacer.
10293 */
10294 if (earliestDel >= seplen)
9073 { 10295 {
9074 // no markers were found on this pass 10296 outarray[outlen++] = earliestStr;
9075 // so we're pretty much done
9076 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9077 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9078 break;
9079 } 10297 }
9080 10298
9081 // Otherwise we just add the newly delimited token 10299 /*
9082 // and recalculate where the search should continue. 10300 * Look at rest of src string following delimeter.
9083 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10301 */
9084 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10302 i = earliestSrc + earliestStr.Length;
9085
9086 if (best < seplen)
9087 {
9088 beginning = offset[best] + (separray[best].ToString()).Length;
9089 }
9090 else
9091 {
9092 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9093 string str = spcarray[best - seplen].ToString();
9094 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9095 tokens.Add(new LSL_String(str));
9096 }
9097 } 10303 }
9098 10304
9099 // This an awkward an not very intuitive boundary case. If the 10305 /*
9100 // last substring is a tokenizer, then there is an implied trailing 10306 * Make up an exact-sized output array suitable for an LSL_List object.
9101 // null list entry. Hopefully the single comparison will not be too 10307 */
9102 // arduous. Alternatively the 'break' could be replced with a return 10308 object[] outlist = new object[outlen];
9103 // but that's shabby programming. 10309 for (i = 0; i < outlen; i ++)
9104
9105 if ((beginning == srclen) && (keepNulls))
9106 { 10310 {
9107 if (srclen != 0) 10311 outlist[i] = new LSL_String(outarray[i]);
9108 tokens.Add(new LSL_String(""));
9109 } 10312 }
9110 10313 return new LSL_List(outlist);
9111 return tokens;
9112 }
9113
9114 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9115 {
9116 m_host.AddScriptLPS(1);
9117 return this.ParseString(src, separators, spacers, false);
9118 }
9119
9120 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9121 {
9122 m_host.AddScriptLPS(1);
9123 return this.ParseString(src, separators, spacers, true);
9124 } 10314 }
9125 10315
9126 public LSL_Integer llGetObjectPermMask(int mask) 10316 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9215,6 +10405,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9215 case 4: 10405 case 4:
9216 return (int)item.NextPermissions; 10406 return (int)item.NextPermissions;
9217 } 10407 }
10408 m_host.TaskInventory.LockItemsForRead(false);
9218 10409
9219 return -1; 10410 return -1;
9220 } 10411 }
@@ -9405,9 +10596,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9405 { 10596 {
9406 try 10597 try
9407 { 10598 {
10599 /*
9408 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10600 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9409 if (obj != null) 10601 if (obj != null)
9410 return (double)obj.GetMass(); 10602 return (double)obj.GetMass();
10603 */
10604 // return total object mass
10605 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10606 if (obj != null)
10607 return obj.GetMass();
10608
9411 // the object is null so the key is for an avatar 10609 // the object is null so the key is for an avatar
9412 ScenePresence avatar = World.GetScenePresence(key); 10610 ScenePresence avatar = World.GetScenePresence(key);
9413 if (avatar != null) 10611 if (avatar != null)
@@ -9427,7 +10625,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9427 } 10625 }
9428 10626
9429 /// <summary> 10627 /// <summary>
9430 /// illListReplaceList removes the sub-list defined by the inclusive indices 10628 /// llListReplaceList removes the sub-list defined by the inclusive indices
9431 /// start and end and inserts the src list in its place. The inclusive 10629 /// start and end and inserts the src list in its place. The inclusive
9432 /// nature of the indices means that at least one element must be deleted 10630 /// nature of the indices means that at least one element must be deleted
9433 /// if the indices are within the bounds of the existing list. I.e. 2,2 10631 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9484,16 +10682,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9484 // based upon end. Note that if end exceeds the upper 10682 // based upon end. Note that if end exceeds the upper
9485 // bound in this case, the entire destination list 10683 // bound in this case, the entire destination list
9486 // is removed. 10684 // is removed.
9487 else 10685 else if (start == 0)
9488 { 10686 {
9489 if (end + 1 < dest.Length) 10687 if (end + 1 < dest.Length)
9490 {
9491 return src + dest.GetSublist(end + 1, -1); 10688 return src + dest.GetSublist(end + 1, -1);
9492 }
9493 else 10689 else
9494 {
9495 return src; 10690 return src;
9496 } 10691 }
10692 else // Start < 0
10693 {
10694 if (end + 1 < dest.Length)
10695 return dest.GetSublist(end + 1, -1);
10696 else
10697 return new LSL_List();
9497 } 10698 }
9498 } 10699 }
9499 // Finally, if start > end, we strip away a prefix and 10700 // Finally, if start > end, we strip away a prefix and
@@ -9544,17 +10745,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9544 int width = 0; 10745 int width = 0;
9545 int height = 0; 10746 int height = 0;
9546 10747
9547 ParcelMediaCommandEnum? commandToSend = null; 10748 uint commandToSend = 0;
9548 float time = 0.0f; // default is from start 10749 float time = 0.0f; // default is from start
9549 10750
9550 ScenePresence presence = null; 10751 ScenePresence presence = null;
9551 10752
9552 for (int i = 0; i < commandList.Data.Length; i++) 10753 for (int i = 0; i < commandList.Data.Length; i++)
9553 { 10754 {
9554 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10755 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9555 switch (command) 10756 switch (command)
9556 { 10757 {
9557 case ParcelMediaCommandEnum.Agent: 10758 case (uint)ParcelMediaCommandEnum.Agent:
9558 // we send only to one agent 10759 // we send only to one agent
9559 if ((i + 1) < commandList.Length) 10760 if ((i + 1) < commandList.Length)
9560 { 10761 {
@@ -9571,25 +10772,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9571 } 10772 }
9572 break; 10773 break;
9573 10774
9574 case ParcelMediaCommandEnum.Loop: 10775 case (uint)ParcelMediaCommandEnum.Loop:
9575 loop = 1; 10776 loop = 1;
9576 commandToSend = command; 10777 commandToSend = command;
9577 update = true; //need to send the media update packet to set looping 10778 update = true; //need to send the media update packet to set looping
9578 break; 10779 break;
9579 10780
9580 case ParcelMediaCommandEnum.Play: 10781 case (uint)ParcelMediaCommandEnum.Play:
9581 loop = 0; 10782 loop = 0;
9582 commandToSend = command; 10783 commandToSend = command;
9583 update = true; //need to send the media update packet to make sure it doesn't loop 10784 update = true; //need to send the media update packet to make sure it doesn't loop
9584 break; 10785 break;
9585 10786
9586 case ParcelMediaCommandEnum.Pause: 10787 case (uint)ParcelMediaCommandEnum.Pause:
9587 case ParcelMediaCommandEnum.Stop: 10788 case (uint)ParcelMediaCommandEnum.Stop:
9588 case ParcelMediaCommandEnum.Unload: 10789 case (uint)ParcelMediaCommandEnum.Unload:
9589 commandToSend = command; 10790 commandToSend = command;
9590 break; 10791 break;
9591 10792
9592 case ParcelMediaCommandEnum.Url: 10793 case (uint)ParcelMediaCommandEnum.Url:
9593 if ((i + 1) < commandList.Length) 10794 if ((i + 1) < commandList.Length)
9594 { 10795 {
9595 if (commandList.Data[i + 1] is LSL_String) 10796 if (commandList.Data[i + 1] is LSL_String)
@@ -9602,7 +10803,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9602 } 10803 }
9603 break; 10804 break;
9604 10805
9605 case ParcelMediaCommandEnum.Texture: 10806 case (uint)ParcelMediaCommandEnum.Texture:
9606 if ((i + 1) < commandList.Length) 10807 if ((i + 1) < commandList.Length)
9607 { 10808 {
9608 if (commandList.Data[i + 1] is LSL_String) 10809 if (commandList.Data[i + 1] is LSL_String)
@@ -9615,7 +10816,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9615 } 10816 }
9616 break; 10817 break;
9617 10818
9618 case ParcelMediaCommandEnum.Time: 10819 case (uint)ParcelMediaCommandEnum.Time:
9619 if ((i + 1) < commandList.Length) 10820 if ((i + 1) < commandList.Length)
9620 { 10821 {
9621 if (commandList.Data[i + 1] is LSL_Float) 10822 if (commandList.Data[i + 1] is LSL_Float)
@@ -9627,7 +10828,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9627 } 10828 }
9628 break; 10829 break;
9629 10830
9630 case ParcelMediaCommandEnum.AutoAlign: 10831 case (uint)ParcelMediaCommandEnum.AutoAlign:
9631 if ((i + 1) < commandList.Length) 10832 if ((i + 1) < commandList.Length)
9632 { 10833 {
9633 if (commandList.Data[i + 1] is LSL_Integer) 10834 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9641,7 +10842,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9641 } 10842 }
9642 break; 10843 break;
9643 10844
9644 case ParcelMediaCommandEnum.Type: 10845 case (uint)ParcelMediaCommandEnum.Type:
9645 if ((i + 1) < commandList.Length) 10846 if ((i + 1) < commandList.Length)
9646 { 10847 {
9647 if (commandList.Data[i + 1] is LSL_String) 10848 if (commandList.Data[i + 1] is LSL_String)
@@ -9654,7 +10855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9654 } 10855 }
9655 break; 10856 break;
9656 10857
9657 case ParcelMediaCommandEnum.Desc: 10858 case (uint)ParcelMediaCommandEnum.Desc:
9658 if ((i + 1) < commandList.Length) 10859 if ((i + 1) < commandList.Length)
9659 { 10860 {
9660 if (commandList.Data[i + 1] is LSL_String) 10861 if (commandList.Data[i + 1] is LSL_String)
@@ -9667,7 +10868,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9667 } 10868 }
9668 break; 10869 break;
9669 10870
9670 case ParcelMediaCommandEnum.Size: 10871 case (uint)ParcelMediaCommandEnum.Size:
9671 if ((i + 2) < commandList.Length) 10872 if ((i + 2) < commandList.Length)
9672 { 10873 {
9673 if (commandList.Data[i + 1] is LSL_Integer) 10874 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9737,7 +10938,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9737 } 10938 }
9738 } 10939 }
9739 10940
9740 if (commandToSend != null) 10941 if (commandToSend != 0)
9741 { 10942 {
9742 // the commandList contained a start/stop/... command, too 10943 // the commandList contained a start/stop/... command, too
9743 if (presence == null) 10944 if (presence == null)
@@ -9774,7 +10975,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9774 10975
9775 if (aList.Data[i] != null) 10976 if (aList.Data[i] != null)
9776 { 10977 {
9777 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10978 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9778 { 10979 {
9779 case ParcelMediaCommandEnum.Url: 10980 case ParcelMediaCommandEnum.Url:
9780 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10981 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9831,15 +11032,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9831 11032
9832 if (quick_pay_buttons.Data.Length < 4) 11033 if (quick_pay_buttons.Data.Length < 4)
9833 { 11034 {
9834 LSLError("List must have at least 4 elements"); 11035 int x;
9835 return; 11036 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
11037 {
11038 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
11039 }
9836 } 11040 }
9837 m_host.ParentGroup.RootPart.PayPrice[0]=price; 11041 int[] nPrice = new int[5];
9838 11042 nPrice[0] = price;
9839 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 11043 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9840 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 11044 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9841 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 11045 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9842 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 11046 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
11047 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9843 m_host.ParentGroup.HasGroupChanged = true; 11048 m_host.ParentGroup.HasGroupChanged = true;
9844 } 11049 }
9845 11050
@@ -9856,7 +11061,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9856 return new LSL_Vector(); 11061 return new LSL_Vector();
9857 } 11062 }
9858 11063
9859 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11064// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11065 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9860 if (presence != null) 11066 if (presence != null)
9861 { 11067 {
9862 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 11068 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9878,7 +11084,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9878 return new LSL_Rotation(); 11084 return new LSL_Rotation();
9879 } 11085 }
9880 11086
9881 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11087// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11088 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9882 if (presence != null) 11089 if (presence != null)
9883 { 11090 {
9884 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 11091 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9938,8 +11145,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9938 { 11145 {
9939 m_host.AddScriptLPS(1); 11146 m_host.AddScriptLPS(1);
9940 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 11147 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9941 if (detectedParams == null) return; // only works on the first detected avatar 11148 if (detectedParams == null)
9942 11149 {
11150 if (m_host.ParentGroup.IsAttachment == true)
11151 {
11152 detectedParams = new DetectParams();
11153 detectedParams.Key = m_host.OwnerID;
11154 }
11155 else
11156 {
11157 return;
11158 }
11159 }
11160
9943 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 11161 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9944 if (avatar != null) 11162 if (avatar != null)
9945 { 11163 {
@@ -9947,6 +11165,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9947 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 11165 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9948 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 11166 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9949 } 11167 }
11168
9950 ScriptSleep(1000); 11169 ScriptSleep(1000);
9951 } 11170 }
9952 11171
@@ -10070,12 +11289,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10070 11289
10071 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11290 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10072 object[] data = rules.Data; 11291 object[] data = rules.Data;
10073 for (int i = 0; i < data.Length; ++i) { 11292 for (int i = 0; i < data.Length; ++i)
11293 {
10074 int type = Convert.ToInt32(data[i++].ToString()); 11294 int type = Convert.ToInt32(data[i++].ToString());
10075 if (i >= data.Length) break; // odd number of entries => ignore the last 11295 if (i >= data.Length) break; // odd number of entries => ignore the last
10076 11296
10077 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11297 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10078 switch (type) { 11298 switch (type)
11299 {
10079 case ScriptBaseClass.CAMERA_FOCUS: 11300 case ScriptBaseClass.CAMERA_FOCUS:
10080 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11301 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10081 case ScriptBaseClass.CAMERA_POSITION: 11302 case ScriptBaseClass.CAMERA_POSITION:
@@ -10181,19 +11402,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10181 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11402 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10182 { 11403 {
10183 m_host.AddScriptLPS(1); 11404 m_host.AddScriptLPS(1);
10184 string ret = String.Empty; 11405
10185 string src1 = llBase64ToString(str1); 11406 if (str1 == String.Empty)
10186 string src2 = llBase64ToString(str2); 11407 return String.Empty;
10187 int c = 0; 11408 if (str2 == String.Empty)
10188 for (int i = 0; i < src1.Length; i++) 11409 return str1;
11410
11411 int len = str2.Length;
11412 if ((len % 4) != 0) // LL is EVIL!!!!
10189 { 11413 {
10190 ret += (char) (src1[i] ^ src2[c]); 11414 while (str2.EndsWith("="))
11415 str2 = str2.Substring(0, str2.Length - 1);
11416
11417 len = str2.Length;
11418 int mod = len % 4;
10191 11419
10192 c++; 11420 if (mod == 1)
10193 if (c >= src2.Length) 11421 str2 = str2.Substring(0, str2.Length - 1);
10194 c = 0; 11422 else if (mod == 2)
11423 str2 += "==";
11424 else if (mod == 3)
11425 str2 += "=";
10195 } 11426 }
10196 return llStringToBase64(ret); 11427
11428 byte[] data1;
11429 byte[] data2;
11430 try
11431 {
11432 data1 = Convert.FromBase64String(str1);
11433 data2 = Convert.FromBase64String(str2);
11434 }
11435 catch (Exception)
11436 {
11437 return new LSL_String(String.Empty);
11438 }
11439
11440 byte[] d2 = new Byte[data1.Length];
11441 int pos = 0;
11442
11443 if (data1.Length <= data2.Length)
11444 {
11445 Array.Copy(data2, 0, d2, 0, data1.Length);
11446 }
11447 else
11448 {
11449 while (pos < data1.Length)
11450 {
11451 len = data1.Length - pos;
11452 if (len > data2.Length)
11453 len = data2.Length;
11454
11455 Array.Copy(data2, 0, d2, pos, len);
11456 pos += len;
11457 }
11458 }
11459
11460 for (pos = 0 ; pos < data1.Length ; pos++ )
11461 data1[pos] ^= d2[pos];
11462
11463 return Convert.ToBase64String(data1);
10197 } 11464 }
10198 11465
10199 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11466 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10246,16 +11513,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10246 if (userAgent != null) 11513 if (userAgent != null)
10247 httpHeaders["User-Agent"] = userAgent; 11514 httpHeaders["User-Agent"] = userAgent;
10248 11515
11516 // See if the URL contains any header hacks
11517 string[] urlParts = url.Split(new char[] {'\n'});
11518 if (urlParts.Length > 1)
11519 {
11520 // Iterate the passed headers and parse them
11521 for (int i = 1 ; i < urlParts.Length ; i++ )
11522 {
11523 // The rest of those would be added to the body in SL.
11524 // Let's not do that.
11525 if (urlParts[i] == String.Empty)
11526 break;
11527
11528 // See if this could be a valid header
11529 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11530 if (headerParts.Length != 2)
11531 continue;
11532
11533 string headerName = headerParts[0].Trim();
11534 string headerValue = headerParts[1].Trim();
11535
11536 // Filter out headers that could be used to abuse
11537 // another system or cloak the request
11538 if (headerName.ToLower() == "x-secondlife-shard" ||
11539 headerName.ToLower() == "x-secondlife-object-name" ||
11540 headerName.ToLower() == "x-secondlife-object-key" ||
11541 headerName.ToLower() == "x-secondlife-region" ||
11542 headerName.ToLower() == "x-secondlife-local-position" ||
11543 headerName.ToLower() == "x-secondlife-local-velocity" ||
11544 headerName.ToLower() == "x-secondlife-local-rotation" ||
11545 headerName.ToLower() == "x-secondlife-owner-name" ||
11546 headerName.ToLower() == "x-secondlife-owner-key" ||
11547 headerName.ToLower() == "connection" ||
11548 headerName.ToLower() == "content-length" ||
11549 headerName.ToLower() == "from" ||
11550 headerName.ToLower() == "host" ||
11551 headerName.ToLower() == "proxy-authorization" ||
11552 headerName.ToLower() == "referer" ||
11553 headerName.ToLower() == "trailer" ||
11554 headerName.ToLower() == "transfer-encoding" ||
11555 headerName.ToLower() == "via" ||
11556 headerName.ToLower() == "authorization")
11557 continue;
11558
11559 httpHeaders[headerName] = headerValue;
11560 }
11561
11562 // Finally, strip any protocol specifier from the URL
11563 url = urlParts[0].Trim();
11564 int idx = url.IndexOf(" HTTP/");
11565 if (idx != -1)
11566 url = url.Substring(0, idx);
11567 }
11568
10249 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11569 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10250 Regex r = new Regex(authregex); 11570 Regex r = new Regex(authregex);
10251 int[] gnums = r.GetGroupNumbers(); 11571 int[] gnums = r.GetGroupNumbers();
10252 Match m = r.Match(url); 11572 Match m = r.Match(url);
10253 if (m.Success) { 11573 if (m.Success)
10254 for (int i = 1; i < gnums.Length; i++) { 11574 {
11575 for (int i = 1; i < gnums.Length; i++)
11576 {
10255 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11577 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10256 //CaptureCollection cc = g.Captures; 11578 //CaptureCollection cc = g.Captures;
10257 } 11579 }
10258 if (m.Groups.Count == 5) { 11580 if (m.Groups.Count == 5)
11581 {
10259 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11582 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10260 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11583 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10261 } 11584 }
@@ -10458,6 +11781,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10458 11781
10459 LSL_List ret = new LSL_List(); 11782 LSL_List ret = new LSL_List();
10460 UUID key = new UUID(); 11783 UUID key = new UUID();
11784
11785
10461 if (UUID.TryParse(id, out key)) 11786 if (UUID.TryParse(id, out key))
10462 { 11787 {
10463 ScenePresence av = World.GetScenePresence(key); 11788 ScenePresence av = World.GetScenePresence(key);
@@ -10475,13 +11800,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10475 ret.Add(new LSL_String("")); 11800 ret.Add(new LSL_String(""));
10476 break; 11801 break;
10477 case ScriptBaseClass.OBJECT_POS: 11802 case ScriptBaseClass.OBJECT_POS:
10478 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11803 Vector3 avpos;
11804
11805 if (av.ParentID != 0 && av.ParentPart != null)
11806 {
11807 avpos = av.OffsetPosition;
11808
11809 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11810 avpos -= sitOffset;
11811
11812 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11813 }
11814 else
11815 avpos = av.AbsolutePosition;
11816
11817 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10479 break; 11818 break;
10480 case ScriptBaseClass.OBJECT_ROT: 11819 case ScriptBaseClass.OBJECT_ROT:
10481 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11820 Quaternion avrot = av.Rotation;
11821 if (av.ParentID != 0 && av.ParentPart != null)
11822 {
11823 avrot = av.ParentPart.GetWorldRotation() * avrot;
11824 }
11825 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10482 break; 11826 break;
10483 case ScriptBaseClass.OBJECT_VELOCITY: 11827 case ScriptBaseClass.OBJECT_VELOCITY:
10484 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11828 Vector3 avvel = av.Velocity;
11829 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10485 break; 11830 break;
10486 case ScriptBaseClass.OBJECT_OWNER: 11831 case ScriptBaseClass.OBJECT_OWNER:
10487 ret.Add(new LSL_String(id)); 11832 ret.Add(new LSL_String(id));
@@ -10537,11 +11882,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10537 case ScriptBaseClass.OBJECT_NAME: 11882 case ScriptBaseClass.OBJECT_NAME:
10538 ret.Add(new LSL_String(obj.Name)); 11883 ret.Add(new LSL_String(obj.Name));
10539 break; 11884 break;
10540 case ScriptBaseClass.OBJECT_DESC: 11885 case ScriptBaseClass.OBJECT_DESC:
10541 ret.Add(new LSL_String(obj.Description)); 11886 ret.Add(new LSL_String(obj.Description));
10542 break; 11887 break;
10543 case ScriptBaseClass.OBJECT_POS: 11888 case ScriptBaseClass.OBJECT_POS:
10544 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11889 Vector3 opos = obj.AbsolutePosition;
11890 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10545 break; 11891 break;
10546 case ScriptBaseClass.OBJECT_ROT: 11892 case ScriptBaseClass.OBJECT_ROT:
10547 { 11893 {
@@ -10557,7 +11903,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10557 } 11903 }
10558 break; 11904 break;
10559 case ScriptBaseClass.OBJECT_VELOCITY: 11905 case ScriptBaseClass.OBJECT_VELOCITY:
10560 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); 11906 Vector3 ovel = obj.Velocity;
11907 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
10561 break; 11908 break;
10562 case ScriptBaseClass.OBJECT_OWNER: 11909 case ScriptBaseClass.OBJECT_OWNER:
10563 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11910 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -10591,9 +11938,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10591 // The value returned in SL for normal prims is prim count 11938 // The value returned in SL for normal prims is prim count
10592 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11939 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10593 break; 11940 break;
10594 // The following 3 costs I have intentionaly coded to return zero. They are part of 11941
10595 // "Land Impact" calculations. These calculations are probably not applicable 11942 // costs below may need to be diferent for root parts, need to check
10596 // to OpenSim and are not yet complete in SL
10597 case ScriptBaseClass.OBJECT_SERVER_COST: 11943 case ScriptBaseClass.OBJECT_SERVER_COST:
10598 // The linden calculation is here 11944 // The linden calculation is here
10599 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11945 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10601,16 +11947,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10601 ret.Add(new LSL_Float(0)); 11947 ret.Add(new LSL_Float(0));
10602 break; 11948 break;
10603 case ScriptBaseClass.OBJECT_STREAMING_COST: 11949 case ScriptBaseClass.OBJECT_STREAMING_COST:
10604 // The linden calculation is here 11950 // The value returned in SL for normal prims is prim count * 0.06
10605 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11951 ret.Add(new LSL_Float(obj.StreamingCost));
10606 // The value returned in SL for normal prims looks like the prim count * 0.06
10607 ret.Add(new LSL_Float(0));
10608 break; 11952 break;
10609 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11953 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10610 // The linden calculation is here 11954 // The value returned in SL for normal prims is prim count
10611 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11955 ret.Add(new LSL_Float(obj.PhysicsCost));
10612 // The value returned in SL for normal prims looks like the prim count
10613 ret.Add(new LSL_Float(0));
10614 break; 11956 break;
10615 default: 11957 default:
10616 // Invalid or unhandled constant. 11958 // Invalid or unhandled constant.
@@ -10808,15 +12150,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10808 return GetLinkPrimitiveParams(obj, rules); 12150 return GetLinkPrimitiveParams(obj, rules);
10809 } 12151 }
10810 12152
10811 public void print(string str) 12153 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10812 { 12154 {
10813 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 12155 List<SceneObjectPart> parts = GetLinkParts(link);
10814 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 12156 if (parts.Count < 1)
10815 if (ossl != null) 12157 return 0;
10816 { 12158
10817 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12159 return GetNumberOfSides(parts[0]);
10818 m_log.Info("LSL print():" + str);
10819 }
10820 } 12160 }
10821 12161
10822 private string Name2Username(string name) 12162 private string Name2Username(string name)
@@ -10861,7 +12201,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10861 12201
10862 return rq.ToString(); 12202 return rq.ToString();
10863 } 12203 }
10864 12204/*
12205 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12206 {
12207 m_SayShoutCount = 0;
12208 }
12209*/
10865 private struct Tri 12210 private struct Tri
10866 { 12211 {
10867 public Vector3 p1; 12212 public Vector3 p1;
@@ -11001,9 +12346,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11001 12346
11002 ContactResult result = new ContactResult (); 12347 ContactResult result = new ContactResult ();
11003 result.ConsumerID = group.LocalId; 12348 result.ConsumerID = group.LocalId;
11004 result.Depth = intersection.distance; 12349// result.Depth = intersection.distance;
11005 result.Normal = intersection.normal; 12350 result.Normal = intersection.normal;
11006 result.Pos = intersection.ipoint; 12351 result.Pos = intersection.ipoint;
12352 result.Depth = Vector3.Mag(rayStart - result.Pos);
11007 12353
11008 contacts.Add(result); 12354 contacts.Add(result);
11009 }); 12355 });
@@ -11136,6 +12482,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11136 12482
11137 return contacts[0]; 12483 return contacts[0];
11138 } 12484 }
12485/*
12486 // not done:
12487 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12488 {
12489 ContactResult[] contacts = null;
12490 World.ForEachSOG(delegate(SceneObjectGroup group)
12491 {
12492 if (m_host.ParentGroup == group)
12493 return;
12494
12495 if (group.IsAttachment)
12496 return;
12497
12498 if(group.RootPart.PhysActor != null)
12499 return;
12500
12501 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12502 });
12503 return contacts;
12504 }
12505*/
11139 12506
11140 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12507 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11141 { 12508 {
@@ -11177,32 +12544,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11177 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12544 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11178 12545
11179 12546
11180 if (checkTerrain) 12547 if (World.SuportsRayCastFiltered())
11181 { 12548 {
11182 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12549 if (dist == 0)
11183 if (groundContact != null) 12550 return list;
11184 results.Add((ContactResult)groundContact);
11185 }
11186 12551
11187 if (checkAgents) 12552 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11188 { 12553 if (checkTerrain)
11189 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12554 rayfilter |= RayFilterFlags.land;
11190 foreach (ContactResult r in agentHits) 12555// if (checkAgents)
11191 results.Add(r); 12556// rayfilter |= RayFilterFlags.agent;
11192 } 12557 if (checkPhysical)
12558 rayfilter |= RayFilterFlags.physical;
12559 if (checkNonPhysical)
12560 rayfilter |= RayFilterFlags.nonphysical;
12561 if (detectPhantom)
12562 rayfilter |= RayFilterFlags.LSLPhanton;
12563
12564 Vector3 direction = dir * ( 1/dist);
11193 12565
11194 if (checkPhysical || checkNonPhysical || detectPhantom) 12566 if(rayfilter == 0)
12567 {
12568 list.Add(new LSL_Integer(0));
12569 return list;
12570 }
12571
12572 // get some more contacts to sort ???
12573 int physcount = 4 * count;
12574 if (physcount > 20)
12575 physcount = 20;
12576
12577 object physresults;
12578 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12579
12580 if (physresults == null)
12581 {
12582 list.Add(new LSL_Integer(-3)); // timeout error
12583 return list;
12584 }
12585
12586 results = (List<ContactResult>)physresults;
12587
12588 // for now physics doesn't detect sitted avatars so do it outside physics
12589 if (checkAgents)
12590 {
12591 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12592 foreach (ContactResult r in agentHits)
12593 results.Add(r);
12594 }
12595
12596 // TODO: Replace this with a better solution. ObjectIntersection can only
12597 // detect nonphysical phantoms. They are detected by virtue of being
12598 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12599 // physicsl phantoms as done by the physics scene
12600 // We don't want anything else but phantoms here.
12601 if (detectPhantom)
12602 {
12603 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12604 foreach (ContactResult r in objectHits)
12605 results.Add(r);
12606 }
12607 }
12608 else
11195 { 12609 {
11196 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12610 if (checkTerrain)
11197 foreach (ContactResult r in objectHits) 12611 {
11198 results.Add(r); 12612 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12613 if (groundContact != null)
12614 results.Add((ContactResult)groundContact);
12615 }
12616
12617 if (checkAgents)
12618 {
12619 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12620 foreach (ContactResult r in agentHits)
12621 results.Add(r);
12622 }
12623
12624 if (checkPhysical || checkNonPhysical || detectPhantom)
12625 {
12626 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12627 foreach (ContactResult r in objectHits)
12628 results.Add(r);
12629 }
11199 } 12630 }
11200 12631
11201 results.Sort(delegate(ContactResult a, ContactResult b) 12632 results.Sort(delegate(ContactResult a, ContactResult b)
11202 { 12633 {
11203 return a.Depth.CompareTo(b.Depth); 12634 return a.Depth.CompareTo(b.Depth);
11204 }); 12635 });
11205 12636
11206 int values = 0; 12637 int values = 0;
11207 SceneObjectGroup thisgrp = m_host.ParentGroup; 12638 SceneObjectGroup thisgrp = m_host.ParentGroup;
11208 12639
@@ -11295,7 +12726,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11295 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12726 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11296 if (!isAccount) return 0; 12727 if (!isAccount) return 0;
11297 if (estate.HasAccess(id)) return 1; 12728 if (estate.HasAccess(id)) return 1;
11298 if (estate.IsBanned(id)) 12729 if (estate.IsBanned(id, World.GetUserFlags(id)))
11299 estate.RemoveBan(id); 12730 estate.RemoveBan(id);
11300 estate.AddEstateUser(id); 12731 estate.AddEstateUser(id);
11301 break; 12732 break;
@@ -11314,14 +12745,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11314 break; 12745 break;
11315 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12746 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11316 if (!isAccount) return 0; 12747 if (!isAccount) return 0;
11317 if (estate.IsBanned(id)) return 1; 12748 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11318 EstateBan ban = new EstateBan(); 12749 EstateBan ban = new EstateBan();
11319 ban.EstateID = estate.EstateID; 12750 ban.EstateID = estate.EstateID;
11320 ban.BannedUserID = id; 12751 ban.BannedUserID = id;
11321 estate.AddBan(ban); 12752 estate.AddBan(ban);
11322 break; 12753 break;
11323 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12754 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11324 if (!isAccount || !estate.IsBanned(id)) return 0; 12755 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11325 estate.RemoveBan(id); 12756 estate.RemoveBan(id);
11326 break; 12757 break;
11327 default: return 0; 12758 default: return 0;
@@ -11350,7 +12781,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11350 return 16384; 12781 return 16384;
11351 } 12782 }
11352 12783
11353 public LSL_Integer llGetUsedMemory() 12784 public virtual LSL_Integer llGetUsedMemory()
11354 { 12785 {
11355 m_host.AddScriptLPS(1); 12786 m_host.AddScriptLPS(1);
11356 // The value returned for LSO scripts in SL 12787 // The value returned for LSO scripts in SL
@@ -11378,7 +12809,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11378 public void llSetSoundQueueing(int queue) 12809 public void llSetSoundQueueing(int queue)
11379 { 12810 {
11380 m_host.AddScriptLPS(1); 12811 m_host.AddScriptLPS(1);
11381 NotImplemented("llSetSoundQueueing");
11382 } 12812 }
11383 12813
11384 public void llCollisionSprite(string impact_sprite) 12814 public void llCollisionSprite(string impact_sprite)
@@ -11390,10 +12820,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11390 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12820 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11391 { 12821 {
11392 m_host.AddScriptLPS(1); 12822 m_host.AddScriptLPS(1);
11393 NotImplemented("llGodLikeRezObject"); 12823
12824 if (!World.Permissions.IsGod(m_host.OwnerID))
12825 NotImplemented("llGodLikeRezObject");
12826
12827 AssetBase rezAsset = World.AssetService.Get(inventory);
12828 if (rezAsset == null)
12829 {
12830 llSay(0, "Asset not found");
12831 return;
12832 }
12833
12834 SceneObjectGroup group = null;
12835
12836 try
12837 {
12838 string xmlData = Utils.BytesToString(rezAsset.Data);
12839 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12840 }
12841 catch
12842 {
12843 llSay(0, "Asset not found");
12844 return;
12845 }
12846
12847 if (group == null)
12848 {
12849 llSay(0, "Asset not found");
12850 return;
12851 }
12852
12853 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12854 group.RootPart.AttachOffset = group.AbsolutePosition;
12855
12856 group.ResetIDs();
12857
12858 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12859 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12860 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12861 group.ScheduleGroupForFullUpdate();
12862
12863 // objects rezzed with this method are die_at_edge by default.
12864 group.RootPart.SetDieAtEdge(true);
12865
12866 group.ResumeScripts();
12867
12868 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12869 "object_rez", new Object[] {
12870 new LSL_String(
12871 group.RootPart.UUID.ToString()) },
12872 new DetectParams[0]));
12873 }
12874
12875 public LSL_String llTransferLindenDollars(string destination, int amount)
12876 {
12877 UUID txn = UUID.Random();
12878
12879 Util.FireAndForget(delegate(object x)
12880 {
12881 int replycode = 0;
12882 string replydata = destination + "," + amount.ToString();
12883
12884 try
12885 {
12886 TaskInventoryItem item = m_item;
12887 if (item == null)
12888 {
12889 replydata = "SERVICE_ERROR";
12890 return;
12891 }
12892
12893 m_host.AddScriptLPS(1);
12894
12895 if (item.PermsGranter == UUID.Zero)
12896 {
12897 replydata = "MISSING_PERMISSION_DEBIT";
12898 return;
12899 }
12900
12901 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12902 {
12903 replydata = "MISSING_PERMISSION_DEBIT";
12904 return;
12905 }
12906
12907 UUID toID = new UUID();
12908
12909 if (!UUID.TryParse(destination, out toID))
12910 {
12911 replydata = "INVALID_AGENT";
12912 return;
12913 }
12914
12915 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12916
12917 if (money == null)
12918 {
12919 replydata = "TRANSFERS_DISABLED";
12920 return;
12921 }
12922
12923 bool result = money.ObjectGiveMoney(
12924 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12925
12926 if (result)
12927 {
12928 replycode = 1;
12929 return;
12930 }
12931
12932 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12933 }
12934 finally
12935 {
12936 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12937 "transaction_result", new Object[] {
12938 new LSL_String(txn.ToString()),
12939 new LSL_Integer(replycode),
12940 new LSL_String(replydata) },
12941 new DetectParams[0]));
12942 }
12943 });
12944
12945 return txn.ToString();
11394 } 12946 }
11395 12947
11396 #endregion 12948 #endregion
12949
12950 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12951 {
12952 SceneObjectGroup group = m_host.ParentGroup;
12953
12954 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12955 return;
12956 if (group.IsAttachment)
12957 return;
12958
12959 if (frames.Data.Length > 0) // We are getting a new motion
12960 {
12961 if (group.RootPart.KeyframeMotion != null)
12962 group.RootPart.KeyframeMotion.Stop();
12963 group.RootPart.KeyframeMotion = null;
12964
12965 int idx = 0;
12966
12967 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12968 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12969
12970 while (idx < options.Data.Length)
12971 {
12972 int option = (int)options.GetLSLIntegerItem(idx++);
12973 int remain = options.Data.Length - idx;
12974
12975 switch (option)
12976 {
12977 case ScriptBaseClass.KFM_MODE:
12978 if (remain < 1)
12979 break;
12980 int modeval = (int)options.GetLSLIntegerItem(idx++);
12981 switch(modeval)
12982 {
12983 case ScriptBaseClass.KFM_FORWARD:
12984 mode = KeyframeMotion.PlayMode.Forward;
12985 break;
12986 case ScriptBaseClass.KFM_REVERSE:
12987 mode = KeyframeMotion.PlayMode.Reverse;
12988 break;
12989 case ScriptBaseClass.KFM_LOOP:
12990 mode = KeyframeMotion.PlayMode.Loop;
12991 break;
12992 case ScriptBaseClass.KFM_PING_PONG:
12993 mode = KeyframeMotion.PlayMode.PingPong;
12994 break;
12995 }
12996 break;
12997 case ScriptBaseClass.KFM_DATA:
12998 if (remain < 1)
12999 break;
13000 int dataval = (int)options.GetLSLIntegerItem(idx++);
13001 data = (KeyframeMotion.DataFormat)dataval;
13002 break;
13003 }
13004 }
13005
13006 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
13007
13008 idx = 0;
13009
13010 int elemLength = 2;
13011 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
13012 elemLength = 3;
13013
13014 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
13015 while (idx < frames.Data.Length)
13016 {
13017 int remain = frames.Data.Length - idx;
13018
13019 if (remain < elemLength)
13020 break;
13021
13022 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
13023 frame.Position = null;
13024 frame.Rotation = null;
13025
13026 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
13027 {
13028 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
13029 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
13030 }
13031 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
13032 {
13033 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
13034 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
13035 }
13036
13037 float tempf = (float)frames.GetLSLFloatItem(idx++);
13038 frame.TimeMS = (int)(tempf * 1000.0f);
13039
13040 keyframes.Add(frame);
13041 }
13042
13043 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
13044 group.RootPart.KeyframeMotion.Start();
13045 }
13046 else
13047 {
13048 if (group.RootPart.KeyframeMotion == null)
13049 return;
13050
13051 if (options.Data.Length == 0)
13052 {
13053 group.RootPart.KeyframeMotion.Stop();
13054 return;
13055 }
13056
13057 int code = (int)options.GetLSLIntegerItem(0);
13058
13059 int idx = 0;
13060
13061 while (idx < options.Data.Length)
13062 {
13063 int option = (int)options.GetLSLIntegerItem(idx++);
13064 int remain = options.Data.Length - idx;
13065
13066 switch (option)
13067 {
13068 case ScriptBaseClass.KFM_COMMAND:
13069 int cmd = (int)options.GetLSLIntegerItem(idx++);
13070 switch (cmd)
13071 {
13072 case ScriptBaseClass.KFM_CMD_PLAY:
13073 group.RootPart.KeyframeMotion.Start();
13074 break;
13075 case ScriptBaseClass.KFM_CMD_STOP:
13076 group.RootPart.KeyframeMotion.Stop();
13077 break;
13078 case ScriptBaseClass.KFM_CMD_PAUSE:
13079 group.RootPart.KeyframeMotion.Pause();
13080 break;
13081 }
13082 break;
13083 }
13084 }
13085 }
13086 }
11397 } 13087 }
11398 13088
11399 public class NotecardCache 13089 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 859ee93..2f02f1f 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>
@@ -916,18 +925,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
916 if (target != null) 925 if (target != null)
917 { 926 {
918 UUID animID=UUID.Zero; 927 UUID animID=UUID.Zero;
919 lock (m_host.TaskInventory) 928 m_host.TaskInventory.LockItemsForRead(true);
929 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
920 { 930 {
921 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 931 if (inv.Value.Name == animation)
922 { 932 {
923 if (inv.Value.Name == animation) 933 if (inv.Value.Type == (int)AssetType.Animation)
924 { 934 animID = inv.Value.AssetID;
925 if (inv.Value.Type == (int)AssetType.Animation) 935 continue;
926 animID = inv.Value.AssetID;
927 continue;
928 }
929 } 936 }
930 } 937 }
938 m_host.TaskInventory.LockItemsForRead(false);
931 if (animID == UUID.Zero) 939 if (animID == UUID.Zero)
932 target.Animator.AddAnimation(animation, m_host.UUID); 940 target.Animator.AddAnimation(animation, m_host.UUID);
933 else 941 else
@@ -968,6 +976,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
968 else 976 else
969 animID = UUID.Zero; 977 animID = UUID.Zero;
970 } 978 }
979 m_host.TaskInventory.LockItemsForRead(false);
971 980
972 if (animID == UUID.Zero) 981 if (animID == UUID.Zero)
973 target.Animator.RemoveAnimation(animation); 982 target.Animator.RemoveAnimation(animation);
@@ -1801,6 +1810,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1801 1810
1802 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1811 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1803 { 1812 {
1813 m_host.TaskInventory.LockItemsForRead(true);
1804 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1814 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1805 { 1815 {
1806 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1816 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1808,6 +1818,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1808 assetID = item.AssetID; 1818 assetID = item.AssetID;
1809 } 1819 }
1810 } 1820 }
1821 m_host.TaskInventory.LockItemsForRead(false);
1811 } 1822 }
1812 1823
1813 if (assetID == UUID.Zero) 1824 if (assetID == UUID.Zero)
@@ -2279,7 +2290,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2279 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2290 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2280 m_host.AddScriptLPS(1); 2291 m_host.AddScriptLPS(1);
2281 2292
2282 return NpcCreate(firstname, lastname, position, notecard, false, false); 2293 return NpcCreate(firstname, lastname, position, notecard, true, false);
2283 } 2294 }
2284 2295
2285 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2296 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2290,24 +2301,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2290 return NpcCreate( 2301 return NpcCreate(
2291 firstname, lastname, position, notecard, 2302 firstname, lastname, position, notecard,
2292 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2303 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2293 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2304 false);
2305// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2294 } 2306 }
2295 2307
2296 private LSL_Key NpcCreate( 2308 private LSL_Key NpcCreate(
2297 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2309 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2298 { 2310 {
2311 if (!owned)
2312 OSSLError("Unowned NPCs are unsupported");
2313
2314 string groupTitle = String.Empty;
2315
2316 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2317 return new LSL_Key(UUID.Zero.ToString());
2318
2319 if (firstname != String.Empty || lastname != String.Empty)
2320 {
2321 if (firstname != "Shown outfit:")
2322 groupTitle = "- NPC -";
2323 }
2324
2299 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2325 INPCModule module = World.RequestModuleInterface<INPCModule>();
2300 if (module != null) 2326 if (module != null)
2301 { 2327 {
2302 AvatarAppearance appearance = null; 2328 AvatarAppearance appearance = null;
2303 2329
2304 UUID id; 2330// UUID id;
2305 if (UUID.TryParse(notecard, out id)) 2331// if (UUID.TryParse(notecard, out id))
2306 { 2332// {
2307 ScenePresence clonePresence = World.GetScenePresence(id); 2333// ScenePresence clonePresence = World.GetScenePresence(id);
2308 if (clonePresence != null) 2334// if (clonePresence != null)
2309 appearance = clonePresence.Appearance; 2335// appearance = clonePresence.Appearance;
2310 } 2336// }
2311 2337
2312 if (appearance == null) 2338 if (appearance == null)
2313 { 2339 {
@@ -2335,6 +2361,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2335 World, 2361 World,
2336 appearance); 2362 appearance);
2337 2363
2364 ScenePresence sp;
2365 if (World.TryGetScenePresence(x, out sp))
2366 {
2367 sp.Grouptitle = groupTitle;
2368 sp.SendAvatarDataToAllAgents();
2369 }
2338 return new LSL_Key(x.ToString()); 2370 return new LSL_Key(x.ToString());
2339 } 2371 }
2340 2372
@@ -2636,16 +2668,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2636 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2668 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2637 m_host.AddScriptLPS(1); 2669 m_host.AddScriptLPS(1);
2638 2670
2639 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2671 ManualResetEvent ev = new ManualResetEvent(false);
2640 if (module != null)
2641 {
2642 UUID npcId = new UUID(npc.m_string);
2643 2672
2644 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2673 Util.FireAndForget(delegate(object x) {
2645 return; 2674 try
2675 {
2676 INPCModule module = World.RequestModuleInterface<INPCModule>();
2677 if (module != null)
2678 {
2679 UUID npcId = new UUID(npc.m_string);
2646 2680
2647 module.DeleteNPC(npcId, World); 2681 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2648 } 2682 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2683 {
2684 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2685 return;
2686 }
2687
2688 module.DeleteNPC(npcId, World);
2689 }
2690 }
2691 finally
2692 {
2693 ev.Set();
2694 }
2695 });
2696 ev.WaitOne();
2649 } 2697 }
2650 2698
2651 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2699 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3338,4 +3386,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3338 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString()); 3386 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString());
3339 } 3387 }
3340 } 3388 }
3341} \ No newline at end of file 3389}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index a626be8..678f9d5 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.X, q.Y, q.Z, q.W); 355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -476,7 +477,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
476 // Position of a sensor in a child prim attached to an avatar 477 // Position of a sensor in a child prim attached to an avatar
477 // will be still wrong. 478 // will be still wrong.
478 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 479 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
479 q = avatar.Rotation * q; 480 if (avatar == null)
481 return sensedEntities;
482 fromRegionPos = avatar.AbsolutePosition;
483 q = avatar.Rotation;
480 } 484 }
481 485
482 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -492,7 +496,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
492// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 496// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
493// presence.Name, presence.PresenceType, ts.name, ts.type); 497// presence.Name, presence.PresenceType, ts.name, ts.type);
494 498
495 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 499 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
496 { 500 {
497 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 501 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
498 if (npcData == null || !npcData.SenseAsAgent) 502 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 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
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.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 3fb463b..af35258 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -126,6 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
126 LSL_Float llGetEnergy(); 126 LSL_Float llGetEnergy();
127 LSL_Vector llGetForce(); 127 LSL_Vector llGetForce();
128 LSL_Integer llGetFreeMemory(); 128 LSL_Integer llGetFreeMemory();
129 LSL_Integer llGetUsedMemory();
129 LSL_Integer llGetFreeURLs(); 130 LSL_Integer llGetFreeURLs();
130 LSL_Vector llGetGeometricCenter(); 131 LSL_Vector llGetGeometricCenter();
131 LSL_Float llGetGMTclock(); 132 LSL_Float llGetGMTclock();
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
149 LSL_Vector llGetLocalPos(); 150 LSL_Vector llGetLocalPos();
150 LSL_Rotation llGetLocalRot(); 151 LSL_Rotation llGetLocalRot();
151 LSL_Float llGetMass(); 152 LSL_Float llGetMass();
153 LSL_Float llGetMassMKS();
152 LSL_Integer llGetMemoryLimit(); 154 LSL_Integer llGetMemoryLimit();
153 void llGetNextEmail(string address, string subject); 155 void llGetNextEmail(string address, string subject);
154 LSL_String llGetNotecardLine(string name, int line); 156 LSL_String llGetNotecardLine(string name, int line);
@@ -202,12 +204,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
202 LSL_String llGetTimestamp(); 204 LSL_String llGetTimestamp();
203 LSL_Vector llGetTorque(); 205 LSL_Vector llGetTorque();
204 LSL_Integer llGetUnixTime(); 206 LSL_Integer llGetUnixTime();
205 LSL_Integer llGetUsedMemory();
206 LSL_Vector llGetVel(); 207 LSL_Vector llGetVel();
207 LSL_Float llGetWallclock(); 208 LSL_Float llGetWallclock();
208 void llGiveInventory(string destination, string inventory); 209 void llGiveInventory(string destination, string inventory);
209 void llGiveInventoryList(string destination, string category, LSL_List inventory); 210 void llGiveInventoryList(string destination, string category, LSL_List inventory);
210 LSL_Integer llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
212 LSL_String llTransferLindenDollars(string destination, int amount);
211 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
212 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
213 LSL_Vector llGroundContour(LSL_Vector offset); 215 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -330,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
330 void llSensorRemove(); 332 void llSensorRemove();
331 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate); 333 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate);
332 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
333 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
334 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
335 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -355,11 +358,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
355 void llSetParcelMusicURL(string url); 358 void llSetParcelMusicURL(string url);
356 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 359 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
357 void llSetPos(LSL_Vector pos); 360 void llSetPos(LSL_Vector pos);
361 LSL_Integer llSetRegionPos(LSL_Vector pos);
358 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 362 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
359 void llSetPrimitiveParams(LSL_List rules); 363 void llSetPrimitiveParams(LSL_List rules);
360 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 364 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
361 void llSetPrimURL(string url); 365 void llSetPrimURL(string url);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
363 void llSetRemoteScriptAccessPin(int pin); 366 void llSetRemoteScriptAccessPin(int pin);
364 void llSetRot(LSL_Rotation rot); 367 void llSetRot(LSL_Rotation rot);
365 void llSetScale(LSL_Vector scale); 368 void llSetScale(LSL_Vector scale);
@@ -379,6 +382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
379 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 382 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
380 void llSetVehicleType(int type); 383 void llSetVehicleType(int type);
381 void llSetVehicleVectorParam(int param, LSL_Vector vec); 384 void llSetVehicleVectorParam(int param, LSL_Vector vec);
385 void llSetVelocity(LSL_Vector velocity, int local);
382 void llShout(int channelID, string text); 386 void llShout(int channelID, string text);
383 LSL_Float llSin(double f); 387 LSL_Float llSin(double f);
384 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 388 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -422,9 +426,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
422 LSL_Vector llWind(LSL_Vector offset); 426 LSL_Vector llWind(LSL_Vector offset);
423 LSL_String llXorBase64Strings(string str1, string str2); 427 LSL_String llXorBase64Strings(string str1, string str2);
424 LSL_String llXorBase64StringsCorrect(string str1, string str2); 428 LSL_String llXorBase64StringsCorrect(string str1, string str2);
425 void print(string str); 429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
426 431
427 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
428 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 433 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
429 } 435 }
430} 436}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 1f000a3..8c34ed3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -85,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
85 // Avatar Info Commands 85 // Avatar Info Commands
86 string osGetAgentIP(string agent); 86 string osGetAgentIP(string agent);
87 LSL_List osGetAgents(); 87 LSL_List osGetAgents();
88 88
89 // Teleport commands 89 // Teleport commands
90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
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.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index cad8518..05ba222 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -56,7 +56,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
56 public const int ACTIVE = 2; 56 public const int ACTIVE = 2;
57 public const int PASSIVE = 4; 57 public const int PASSIVE = 4;
58 public const int SCRIPTED = 8; 58 public const int SCRIPTED = 8;
59 public const int OS_NPC = 0x01000000;
60 59
61 public const int CONTROL_FWD = 1; 60 public const int CONTROL_FWD = 1;
62 public const int CONTROL_BACK = 2; 61 public const int CONTROL_BACK = 2;
@@ -95,6 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
95 public const int AGENT_CROUCHING = 1024; 94 public const int AGENT_CROUCHING = 1024;
96 public const int AGENT_BUSY = 2048; 95 public const int AGENT_BUSY = 2048;
97 public const int AGENT_ALWAYS_RUN = 4096; 96 public const int AGENT_ALWAYS_RUN = 4096;
97 public const int AGENT_MALE = 8192;
98 98
99 //Particle Systems 99 //Particle Systems
100 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 100 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -285,6 +285,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
285 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 285 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
286 public const int CHANGED_MEDIA = 2048; 286 public const int CHANGED_MEDIA = 2048;
287 public const int CHANGED_ANIMATION = 16384; 287 public const int CHANGED_ANIMATION = 16384;
288 public const int CHANGED_POSITION = 32768;
288 public const int TYPE_INVALID = 0; 289 public const int TYPE_INVALID = 0;
289 public const int TYPE_INTEGER = 1; 290 public const int TYPE_INTEGER = 1;
290 public const int TYPE_FLOAT = 2; 291 public const int TYPE_FLOAT = 2;
@@ -590,6 +591,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
590 public const int PRIM_MEDIA_PERM_OWNER = 1; 591 public const int PRIM_MEDIA_PERM_OWNER = 1;
591 public const int PRIM_MEDIA_PERM_GROUP = 2; 592 public const int PRIM_MEDIA_PERM_GROUP = 2;
592 public const int PRIM_MEDIA_PERM_ANYONE = 4; 593 public const int PRIM_MEDIA_PERM_ANYONE = 4;
594
595 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
596 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
597 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
598 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
599
600 public const int PRIM_PHYSICS_MATERIAL = 31;
601 public const int DENSITY = 1;
602 public const int FRICTION = 2;
603 public const int RESTITUTION = 4;
604 public const int GRAVITY_MULTIPLIER = 8;
593 605
594 // extra constants for llSetPrimMediaParams 606 // extra constants for llSetPrimMediaParams
595 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 607 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -662,6 +674,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
662 674
663 public static readonly LSLInteger RCERR_UNKNOWN = -1; 675 public static readonly LSLInteger RCERR_UNKNOWN = -1;
664 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 676 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
665 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 677 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
678
679 public const int KFM_MODE = 1;
680 public const int KFM_LOOP = 1;
681 public const int KFM_REVERSE = 3;
682 public const int KFM_FORWARD = 0;
683 public const int KFM_PING_PONG = 2;
684 public const int KFM_DATA = 2;
685 public const int KFM_TRANSLATION = 2;
686 public const int KFM_ROTATION = 1;
687 public const int KFM_COMMAND = 0;
688 public const int KFM_CMD_PLAY = 0;
689 public const int KFM_CMD_STOP = 1;
690 public const int KFM_CMD_PAUSE = 2;
666 } 691 }
667} 692}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index c457880..89b6eff 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -314,6 +315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 315 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 316 }
316 317
318 [DebuggerNonUserCode]
317 public void llDie() 319 public void llDie()
318 { 320 {
319 m_LSL_Functions.llDie(); 321 m_LSL_Functions.llDie();
@@ -474,6 +476,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
474 return m_LSL_Functions.llGetFreeMemory(); 476 return m_LSL_Functions.llGetFreeMemory();
475 } 477 }
476 478
479 public LSL_Integer llGetUsedMemory()
480 {
481 return m_LSL_Functions.llGetUsedMemory();
482 }
483
477 public LSL_Integer llGetFreeURLs() 484 public LSL_Integer llGetFreeURLs()
478 { 485 {
479 return m_LSL_Functions.llGetFreeURLs(); 486 return m_LSL_Functions.llGetFreeURLs();
@@ -579,6 +586,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
579 return m_LSL_Functions.llGetMass(); 586 return m_LSL_Functions.llGetMass();
580 } 587 }
581 588
589 public LSL_Float llGetMassMKS()
590 {
591 return m_LSL_Functions.llGetMassMKS();
592 }
593
582 public LSL_Integer llGetMemoryLimit() 594 public LSL_Integer llGetMemoryLimit()
583 { 595 {
584 return m_LSL_Functions.llGetMemoryLimit(); 596 return m_LSL_Functions.llGetMemoryLimit();
@@ -844,11 +856,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
844 return m_LSL_Functions.llGetUnixTime(); 856 return m_LSL_Functions.llGetUnixTime();
845 } 857 }
846 858
847 public LSL_Integer llGetUsedMemory()
848 {
849 return m_LSL_Functions.llGetUsedMemory();
850 }
851
852 public LSL_Vector llGetVel() 859 public LSL_Vector llGetVel()
853 { 860 {
854 return m_LSL_Functions.llGetVel(); 861 return m_LSL_Functions.llGetVel();
@@ -874,6 +881,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
874 return m_LSL_Functions.llGiveMoney(destination, amount); 881 return m_LSL_Functions.llGiveMoney(destination, amount);
875 } 882 }
876 883
884 public LSL_String llTransferLindenDollars(string destination, int amount)
885 {
886 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
887 }
888
877 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 889 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
878 { 890 {
879 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 891 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1483,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1483 m_LSL_Functions.llSetAlpha(alpha, face); 1495 m_LSL_Functions.llSetAlpha(alpha, face);
1484 } 1496 }
1485 1497
1498 public void llSetAngularVelocity(LSL_Vector angvelocity, int local)
1499 {
1500 m_LSL_Functions.llSetAngularVelocity(angvelocity, local);
1501 }
1502
1486 public void llSetBuoyancy(double buoyancy) 1503 public void llSetBuoyancy(double buoyancy)
1487 { 1504 {
1488 m_LSL_Functions.llSetBuoyancy(buoyancy); 1505 m_LSL_Functions.llSetBuoyancy(buoyancy);
@@ -1603,6 +1620,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1603 m_LSL_Functions.llSetPos(pos); 1620 m_LSL_Functions.llSetPos(pos);
1604 } 1621 }
1605 1622
1623 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1624 {
1625 return m_LSL_Functions.llSetRegionPos(pos);
1626 }
1627
1606 public void llSetPrimitiveParams(LSL_List rules) 1628 public void llSetPrimitiveParams(LSL_List rules)
1607 { 1629 {
1608 m_LSL_Functions.llSetPrimitiveParams(rules); 1630 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1618,11 +1640,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1618 m_LSL_Functions.llSetPrimURL(url); 1640 m_LSL_Functions.llSetPrimURL(url);
1619 } 1641 }
1620 1642
1621 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1622 {
1623 return m_LSL_Functions.llSetRegionPos(pos);
1624 }
1625
1626 public void llSetRemoteScriptAccessPin(int pin) 1643 public void llSetRemoteScriptAccessPin(int pin)
1627 { 1644 {
1628 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1645 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1718,6 +1735,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1718 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1735 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1719 } 1736 }
1720 1737
1738 public void llSetVelocity(LSL_Vector velocity, int local)
1739 {
1740 m_LSL_Functions.llSetVelocity(velocity, local);
1741 }
1742
1721 public void llShout(int channelID, string text) 1743 public void llShout(int channelID, string text)
1722 { 1744 {
1723 m_LSL_Functions.llShout(channelID, text); 1745 m_LSL_Functions.llShout(channelID, text);
@@ -1968,9 +1990,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1968 return m_LSL_Functions.llClearLinkMedia(link, face); 1990 return m_LSL_Functions.llClearLinkMedia(link, face);
1969 } 1991 }
1970 1992
1971 public void print(string str) 1993 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1994 {
1995 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1996 }
1997
1998 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1999 {
2000 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2001 }
2002
2003 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1972 { 2004 {
1973 m_LSL_Functions.print(str); 2005 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1974 } 2006 }
1975 } 2007 }
1976} 2008}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);