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.cs3193
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs102
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs11
-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.cs28
-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, 2904 insertions, 810 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 5b22860..693992a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -304,6 +304,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
304 return null; 304 return null;
305 } 305 }
306 306
307 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
308 {
309 // Remove a specific script
310
311 // Remove dataserver events
312 m_Dataserver[engine].RemoveEvents(localID, itemID);
313
314 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
315 if (comms != null)
316 comms.DeleteListener(itemID);
317
318 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
319 xmlrpc.DeleteChannels(itemID);
320 xmlrpc.CancelSRDRequests(itemID);
321
322 // Remove Sensors
323 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
324
325 }
326
307 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 327 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
308 { 328 {
309 List<Object> data = new List<Object>(); 329 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 084bd41..6dfd723 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,10 +28,12 @@
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);
@@ -236,9 +279,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
236 } 279 }
237 } 280 }
238 281
282 public List<ScenePresence> GetLinkAvatars(int linkType)
283 {
284 List<ScenePresence> ret = new List<ScenePresence>();
285 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
286 return ret;
287
288 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
289
290 switch (linkType)
291 {
292 case ScriptBaseClass.LINK_SET:
293 return avs;
294
295 case ScriptBaseClass.LINK_ROOT:
296 return ret;
297
298 case ScriptBaseClass.LINK_ALL_OTHERS:
299 return avs;
300
301 case ScriptBaseClass.LINK_ALL_CHILDREN:
302 return avs;
303
304 case ScriptBaseClass.LINK_THIS:
305 return ret;
306
307 default:
308 if (linkType < 0)
309 return ret;
310
311 int partCount = m_host.ParentGroup.GetPartCount();
312
313 if (linkType <= partCount)
314 {
315 return ret;
316 }
317 else
318 {
319 linkType = linkType - partCount;
320 if (linkType > avs.Count)
321 {
322 return ret;
323 }
324 else
325 {
326 ret.Add(avs[linkType-1]);
327 return ret;
328 }
329 }
330 }
331 }
332
239 public List<SceneObjectPart> GetLinkParts(int linkType) 333 public List<SceneObjectPart> GetLinkParts(int linkType)
240 { 334 {
241 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 335 List<SceneObjectPart> ret = new List<SceneObjectPart>();
336 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
337 return ret;
242 ret.Add(m_host); 338 ret.Add(m_host);
243 339
244 switch (linkType) 340 switch (linkType)
@@ -437,31 +533,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
437 533
438 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 534 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
439 535
440 /// <summary> 536 // Utility function for llRot2Euler
441 /// Convert an LSL rotation to a Euler vector. 537
442 /// </summary> 538 // normalize an angle between -PI and PI (-180 to +180 degrees)
443 /// <remarks> 539 protected double NormalizeAngle(double angle)
444 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
445 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
446 /// </remarks>
447 /// <param name="r"></param>
448 /// <returns></returns>
449 public LSL_Vector llRot2Euler(LSL_Rotation r)
450 { 540 {
451 m_host.AddScriptLPS(1); 541 if (angle > -Math.PI && angle < Math.PI)
542 return angle;
543
544 int numPis = (int)(Math.PI / angle);
545 double remainder = angle - Math.PI * numPis;
546 if (numPis % 2 == 1)
547 return Math.PI - angle;
548 return remainder;
549 }
452 550
453 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 551 public LSL_Vector llRot2Euler(LSL_Rotation q1)
454 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 552 {
455 if (m == 0.0) return new LSL_Vector(); 553 m_host.AddScriptLPS(1);
456 double x = Math.Atan2(-v.y, v.z); 554 LSL_Vector eul = new LSL_Vector();
457 double sin = v.x / m;
458 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
459 double y = Math.Asin(sin);
460 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
461 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)));
462 double z = Math.Atan2(v.y, v.x);
463 555
464 return new LSL_Vector(x, y, z); 556 double sqw = q1.s*q1.s;
557 double sqx = q1.x*q1.x;
558 double sqy = q1.z*q1.z;
559 double sqz = q1.y*q1.y;
560 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
561 double test = q1.x*q1.z + q1.y*q1.s;
562 if (test > 0.4999*unit) { // singularity at north pole
563 eul.z = 2 * Math.Atan2(q1.x,q1.s);
564 eul.y = Math.PI/2;
565 eul.x = 0;
566 return eul;
567 }
568 if (test < -0.4999*unit) { // singularity at south pole
569 eul.z = -2 * Math.Atan2(q1.x,q1.s);
570 eul.y = -Math.PI/2;
571 eul.x = 0;
572 return eul;
573 }
574 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
575 eul.y = Math.Asin(2*test/unit);
576 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
577 return eul;
465 } 578 }
466 579
467 /* From wiki: 580 /* From wiki:
@@ -514,18 +627,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
514 m_host.AddScriptLPS(1); 627 m_host.AddScriptLPS(1);
515 628
516 double x,y,z,s; 629 double x,y,z,s;
517 630 v.x *= 0.5;
518 double c1 = Math.Cos(v.x * 0.5); 631 v.y *= 0.5;
519 double c2 = Math.Cos(v.y * 0.5); 632 v.z *= 0.5;
520 double c3 = Math.Cos(v.z * 0.5); 633 double c1 = Math.Cos(v.x);
521 double s1 = Math.Sin(v.x * 0.5); 634 double c2 = Math.Cos(v.y);
522 double s2 = Math.Sin(v.y * 0.5); 635 double c1c2 = c1 * c2;
523 double s3 = Math.Sin(v.z * 0.5); 636 double s1 = Math.Sin(v.x);
524 637 double s2 = Math.Sin(v.y);
525 x = s1 * c2 * c3 + c1 * s2 * s3; 638 double s1s2 = s1 * s2;
526 y = c1 * s2 * c3 - s1 * c2 * s3; 639 double c1s2 = c1 * s2;
527 z = s1 * s2 * c3 + c1 * c2 * s3; 640 double s1c2 = s1 * c2;
528 s = c1 * c2 * c3 - s1 * s2 * s3; 641 double c3 = Math.Cos(v.z);
642 double s3 = Math.Sin(v.z);
643
644 x = s1c2 * c3 + c1s2 * s3;
645 y = c1s2 * c3 - s1c2 * s3;
646 z = s1s2 * c3 + c1c2 * s3;
647 s = c1c2 * c3 - s1s2 * s3;
529 648
530 return new LSL_Rotation(x, y, z, s); 649 return new LSL_Rotation(x, y, z, s);
531 } 650 }
@@ -663,77 +782,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
663 { 782 {
664 //A and B should both be normalized 783 //A and B should both be normalized
665 m_host.AddScriptLPS(1); 784 m_host.AddScriptLPS(1);
666 LSL_Rotation rotBetween; 785 /* This method is more accurate than the SL one, and thus causes problems
667 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 786 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
668 // continue calculation. 787
669 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 788 double dotProduct = LSL_Vector.Dot(a, b);
789 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
790 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
791 double angle = Math.Acos(dotProduct / magProduct);
792 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
793 double s = Math.Sin(angle / 2);
794
795 double x = axis.x * s;
796 double y = axis.y * s;
797 double z = axis.z * s;
798 double w = Math.Cos(angle / 2);
799
800 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
801 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
802
803 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
804 */
805
806 // This method mimics the 180 errors found in SL
807 // See www.euclideanspace.com... angleBetween
808 LSL_Vector vec_a = a;
809 LSL_Vector vec_b = b;
810
811 // Eliminate zero length
812 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
813 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
814 if (vec_a_mag < 0.00001 ||
815 vec_b_mag < 0.00001)
670 { 816 {
671 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 817 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
672 } 818 }
673 else 819
820 // Normalize
821 vec_a = llVecNorm(vec_a);
822 vec_b = llVecNorm(vec_b);
823
824 // Calculate axis and rotation angle
825 LSL_Vector axis = vec_a % vec_b;
826 LSL_Float cos_theta = vec_a * vec_b;
827
828 // Check if parallel
829 if (cos_theta > 0.99999)
674 { 830 {
675 a = LSL_Vector.Norm(a); 831 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
676 b = LSL_Vector.Norm(b); 832 }
677 double dotProduct = LSL_Vector.Dot(a, b); 833
678 // There are two degenerate cases possible. These are for vectors 180 or 834 // Check if anti-parallel
679 // 0 degrees apart. These have to be detected and handled individually. 835 else if (cos_theta < -0.99999)
680 // 836 {
681 // Check for vectors 180 degrees apart. 837 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
682 // A dot product of -1 would mean the angle between vectors is 180 degrees. 838 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
683 if (dotProduct < -0.9999999f) 839 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
684 { 840 }
685 // First assume X axis is orthogonal to the vectors. 841 else // other rotation
686 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 842 {
687 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 843 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
688 // Check for near zero vector. A very small non-zero number here will create 844 axis = llVecNorm(axis);
689 // a rotation in an undesired direction. 845 double x, y, z, s, t;
690 if (LSL_Vector.Mag(orthoVector) > 0.0001) 846 s = Math.Cos(theta);
691 { 847 t = Math.Sin(theta);
692 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 848 x = axis.x * t;
693 } 849 y = axis.y * t;
694 // If the magnitude of the vector was near zero, then assume the X axis is not 850 z = axis.z * t;
695 // orthogonal and use the Z axis instead. 851 return new LSL_Rotation(x,y,z,s);
696 else
697 {
698 // Set 180 z rotation.
699 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
700 }
701 }
702 // Check for parallel vectors.
703 // A dot product of 1 would mean the angle between vectors is 0 degrees.
704 else if (dotProduct > 0.9999999f)
705 {
706 // Set zero rotation.
707 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
708 }
709 else
710 {
711 // All special checks have been performed so get the axis of rotation.
712 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
713 // Quarternion s value is the length of the unit vector + dot product.
714 double qs = 1.0 + dotProduct;
715 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
716 // Normalize the rotation.
717 double mag = LSL_Rotation.Mag(rotBetween);
718 // We shouldn't have to worry about a divide by zero here. The qs value will be
719 // non-zero because we already know if we're here, then the dotProduct is not -1 so
720 // qs will not be zero. Also, we've already handled the input vectors being zero so the
721 // crossProduct vector should also not be zero.
722 rotBetween.x = rotBetween.x / mag;
723 rotBetween.y = rotBetween.y / mag;
724 rotBetween.z = rotBetween.z / mag;
725 rotBetween.s = rotBetween.s / mag;
726 // Check for undefined values and set zero rotation if any found. This code might not actually be required
727 // any longer since zero vectors are checked for at the top.
728 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
729 {
730 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
731 }
732 }
733 } 852 }
734 return rotBetween;
735 } 853 }
736 854
737 public void llWhisper(int channelID, string text) 855 public void llWhisper(int channelID, string text)
738 { 856 {
739 m_host.AddScriptLPS(1); 857 m_host.AddScriptLPS(1);
@@ -749,10 +867,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
749 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 867 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
750 } 868 }
751 869
870 private void CheckSayShoutTime()
871 {
872 DateTime now = DateTime.UtcNow;
873 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
874 {
875 m_lastSayShoutCheck = now;
876 m_SayShoutCount = 0;
877 }
878 else
879 m_SayShoutCount++;
880 }
881
752 public void llSay(int channelID, string text) 882 public void llSay(int channelID, string text)
753 { 883 {
754 m_host.AddScriptLPS(1); 884 m_host.AddScriptLPS(1);
755 885
886 if (channelID == 0)
887// m_SayShoutCount++;
888 CheckSayShoutTime();
889
890 if (m_SayShoutCount >= 11)
891 ScriptSleep(2000);
892
756 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 893 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
757 { 894 {
758 Console.WriteLine(text); 895 Console.WriteLine(text);
@@ -775,6 +912,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
775 { 912 {
776 m_host.AddScriptLPS(1); 913 m_host.AddScriptLPS(1);
777 914
915 if (channelID == 0)
916// m_SayShoutCount++;
917 CheckSayShoutTime();
918
919 if (m_SayShoutCount >= 11)
920 ScriptSleep(2000);
921
778 if (text.Length > 1023) 922 if (text.Length > 1023)
779 text = text.Substring(0, 1023); 923 text = text.Substring(0, 1023);
780 924
@@ -806,22 +950,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
806 950
807 public void llRegionSayTo(string target, int channel, string msg) 951 public void llRegionSayTo(string target, int channel, string msg)
808 { 952 {
953 string error = String.Empty;
954
809 if (msg.Length > 1023) 955 if (msg.Length > 1023)
810 msg = msg.Substring(0, 1023); 956 msg = msg.Substring(0, 1023);
811 957
812 m_host.AddScriptLPS(1); 958 m_host.AddScriptLPS(1);
813 959
814 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
815 {
816 return;
817 }
818
819 UUID TargetID; 960 UUID TargetID;
820 UUID.TryParse(target, out TargetID); 961 UUID.TryParse(target, out TargetID);
821 962
822 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 963 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
823 if (wComm != null) 964 if (wComm != null)
824 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 965 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
966 LSLError(error);
825 } 967 }
826 968
827 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 969 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1077,10 +1219,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1077 return detectedParams.TouchUV; 1219 return detectedParams.TouchUV;
1078 } 1220 }
1079 1221
1222 [DebuggerNonUserCode]
1080 public virtual void llDie() 1223 public virtual void llDie()
1081 { 1224 {
1082 m_host.AddScriptLPS(1); 1225 m_host.AddScriptLPS(1);
1083 throw new SelfDeleteException(); 1226 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1084 } 1227 }
1085 1228
1086 public LSL_Float llGround(LSL_Vector offset) 1229 public LSL_Float llGround(LSL_Vector offset)
@@ -1153,6 +1296,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1153 1296
1154 public void llSetStatus(int status, int value) 1297 public void llSetStatus(int status, int value)
1155 { 1298 {
1299 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1300 return;
1156 m_host.AddScriptLPS(1); 1301 m_host.AddScriptLPS(1);
1157 1302
1158 int statusrotationaxis = 0; 1303 int statusrotationaxis = 0;
@@ -1176,6 +1321,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1176 if (!allow) 1321 if (!allow)
1177 return; 1322 return;
1178 1323
1324 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1325 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1326 return;
1327
1179 m_host.ScriptSetPhysicsStatus(true); 1328 m_host.ScriptSetPhysicsStatus(true);
1180 } 1329 }
1181 else 1330 else
@@ -1385,6 +1534,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1385 { 1534 {
1386 m_host.AddScriptLPS(1); 1535 m_host.AddScriptLPS(1);
1387 1536
1537 SetColor(m_host, color, face);
1538 }
1539
1540 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1541 {
1542 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1543 return;
1544
1545 Primitive.TextureEntry tex = part.Shape.Textures;
1546 Color4 texcolor;
1547 if (face >= 0 && face < GetNumberOfSides(part))
1548 {
1549 texcolor = tex.CreateFace((uint)face).RGBA;
1550 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1551 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1552 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1553 tex.FaceTextures[face].RGBA = texcolor;
1554 part.UpdateTextureEntry(tex.GetBytes());
1555 return;
1556 }
1557 else if (face == ScriptBaseClass.ALL_SIDES)
1558 {
1559 for (uint i = 0; i < GetNumberOfSides(part); i++)
1560 {
1561 if (tex.FaceTextures[i] != null)
1562 {
1563 texcolor = tex.FaceTextures[i].RGBA;
1564 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1565 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1566 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1567 tex.FaceTextures[i].RGBA = texcolor;
1568 }
1569 texcolor = tex.DefaultTexture.RGBA;
1570 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1571 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1572 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1573 tex.DefaultTexture.RGBA = texcolor;
1574 }
1575 part.UpdateTextureEntry(tex.GetBytes());
1576 return;
1577 }
1578
1388 if (face == ScriptBaseClass.ALL_SIDES) 1579 if (face == ScriptBaseClass.ALL_SIDES)
1389 face = SceneObjectPart.ALL_SIDES; 1580 face = SceneObjectPart.ALL_SIDES;
1390 1581
@@ -1393,6 +1584,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1393 1584
1394 public void SetTexGen(SceneObjectPart part, int face,int style) 1585 public void SetTexGen(SceneObjectPart part, int face,int style)
1395 { 1586 {
1587 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1588 return;
1589
1396 Primitive.TextureEntry tex = part.Shape.Textures; 1590 Primitive.TextureEntry tex = part.Shape.Textures;
1397 MappingType textype; 1591 MappingType textype;
1398 textype = MappingType.Default; 1592 textype = MappingType.Default;
@@ -1423,6 +1617,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1423 1617
1424 public void SetGlow(SceneObjectPart part, int face, float glow) 1618 public void SetGlow(SceneObjectPart part, int face, float glow)
1425 { 1619 {
1620 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1621 return;
1622
1426 Primitive.TextureEntry tex = part.Shape.Textures; 1623 Primitive.TextureEntry tex = part.Shape.Textures;
1427 if (face >= 0 && face < GetNumberOfSides(part)) 1624 if (face >= 0 && face < GetNumberOfSides(part))
1428 { 1625 {
@@ -1448,6 +1645,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1448 1645
1449 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1646 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1450 { 1647 {
1648 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1649 return;
1451 1650
1452 Shininess sval = new Shininess(); 1651 Shininess sval = new Shininess();
1453 1652
@@ -1498,6 +1697,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1498 1697
1499 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1698 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1500 { 1699 {
1700 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1701 return;
1702
1501 Primitive.TextureEntry tex = part.Shape.Textures; 1703 Primitive.TextureEntry tex = part.Shape.Textures;
1502 if (face >= 0 && face < GetNumberOfSides(part)) 1704 if (face >= 0 && face < GetNumberOfSides(part))
1503 { 1705 {
@@ -1558,13 +1760,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1558 m_host.AddScriptLPS(1); 1760 m_host.AddScriptLPS(1);
1559 1761
1560 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1762 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1561 1763 if (parts.Count > 0)
1562 foreach (SceneObjectPart part in parts) 1764 {
1563 SetAlpha(part, alpha, face); 1765 try
1766 {
1767 parts[0].ParentGroup.areUpdatesSuspended = true;
1768 foreach (SceneObjectPart part in parts)
1769 SetAlpha(part, alpha, face);
1770 }
1771 finally
1772 {
1773 parts[0].ParentGroup.areUpdatesSuspended = false;
1774 }
1775 }
1564 } 1776 }
1565 1777
1566 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1778 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1567 { 1779 {
1780 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1781 return;
1782
1568 Primitive.TextureEntry tex = part.Shape.Textures; 1783 Primitive.TextureEntry tex = part.Shape.Textures;
1569 Color4 texcolor; 1784 Color4 texcolor;
1570 if (face >= 0 && face < GetNumberOfSides(part)) 1785 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1617,7 +1832,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1617 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1832 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1618 float wind, float tension, LSL_Vector Force) 1833 float wind, float tension, LSL_Vector Force)
1619 { 1834 {
1620 if (part == null) 1835 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1621 return; 1836 return;
1622 1837
1623 if (flexi) 1838 if (flexi)
@@ -1651,7 +1866,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1651 /// <param name="falloff"></param> 1866 /// <param name="falloff"></param>
1652 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1867 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1653 { 1868 {
1654 if (part == null) 1869 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1655 return; 1870 return;
1656 1871
1657 if (light) 1872 if (light)
@@ -1684,11 +1899,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1684 Primitive.TextureEntry tex = part.Shape.Textures; 1899 Primitive.TextureEntry tex = part.Shape.Textures;
1685 Color4 texcolor; 1900 Color4 texcolor;
1686 LSL_Vector rgb = new LSL_Vector(); 1901 LSL_Vector rgb = new LSL_Vector();
1902 int nsides = GetNumberOfSides(part);
1903
1687 if (face == ScriptBaseClass.ALL_SIDES) 1904 if (face == ScriptBaseClass.ALL_SIDES)
1688 { 1905 {
1689 int i; 1906 int i;
1690 1907 for (i = 0; i < nsides; i++)
1691 for (i = 0 ; i < GetNumberOfSides(part); i++)
1692 { 1908 {
1693 texcolor = tex.GetFace((uint)i).RGBA; 1909 texcolor = tex.GetFace((uint)i).RGBA;
1694 rgb.x += texcolor.R; 1910 rgb.x += texcolor.R;
@@ -1696,14 +1912,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1696 rgb.z += texcolor.B; 1912 rgb.z += texcolor.B;
1697 } 1913 }
1698 1914
1699 rgb.x /= (float)GetNumberOfSides(part); 1915 float invnsides = 1.0f / (float)nsides;
1700 rgb.y /= (float)GetNumberOfSides(part); 1916
1701 rgb.z /= (float)GetNumberOfSides(part); 1917 rgb.x *= invnsides;
1918 rgb.y *= invnsides;
1919 rgb.z *= invnsides;
1702 1920
1703 return rgb; 1921 return rgb;
1704 } 1922 }
1705 1923 if (face >= 0 && face < nsides)
1706 if (face >= 0 && face < GetNumberOfSides(part))
1707 { 1924 {
1708 texcolor = tex.GetFace((uint)face).RGBA; 1925 texcolor = tex.GetFace((uint)face).RGBA;
1709 rgb.x = texcolor.R; 1926 rgb.x = texcolor.R;
@@ -1730,15 +1947,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1730 m_host.AddScriptLPS(1); 1947 m_host.AddScriptLPS(1);
1731 1948
1732 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1949 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1733 1950 if (parts.Count > 0)
1734 foreach (SceneObjectPart part in parts) 1951 {
1735 SetTexture(part, texture, face); 1952 try
1736 1953 {
1954 parts[0].ParentGroup.areUpdatesSuspended = true;
1955 foreach (SceneObjectPart part in parts)
1956 SetTexture(part, texture, face);
1957 }
1958 finally
1959 {
1960 parts[0].ParentGroup.areUpdatesSuspended = false;
1961 }
1962 }
1737 ScriptSleep(200); 1963 ScriptSleep(200);
1738 } 1964 }
1739 1965
1740 protected void SetTexture(SceneObjectPart part, string texture, int face) 1966 protected void SetTexture(SceneObjectPart part, string texture, int face)
1741 { 1967 {
1968 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1969 return;
1970
1742 UUID textureID = new UUID(); 1971 UUID textureID = new UUID();
1743 1972
1744 textureID = InventoryKey(texture, (int)AssetType.Texture); 1973 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1783,6 +2012,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1783 2012
1784 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2013 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1785 { 2014 {
2015 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2016 return;
2017
1786 Primitive.TextureEntry tex = part.Shape.Textures; 2018 Primitive.TextureEntry tex = part.Shape.Textures;
1787 if (face >= 0 && face < GetNumberOfSides(part)) 2019 if (face >= 0 && face < GetNumberOfSides(part))
1788 { 2020 {
@@ -1819,6 +2051,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1819 2051
1820 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2052 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1821 { 2053 {
2054 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2055 return;
2056
1822 Primitive.TextureEntry tex = part.Shape.Textures; 2057 Primitive.TextureEntry tex = part.Shape.Textures;
1823 if (face >= 0 && face < GetNumberOfSides(part)) 2058 if (face >= 0 && face < GetNumberOfSides(part))
1824 { 2059 {
@@ -1855,6 +2090,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1855 2090
1856 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2091 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1857 { 2092 {
2093 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2094 return;
2095
1858 Primitive.TextureEntry tex = part.Shape.Textures; 2096 Primitive.TextureEntry tex = part.Shape.Textures;
1859 if (face >= 0 && face < GetNumberOfSides(part)) 2097 if (face >= 0 && face < GetNumberOfSides(part))
1860 { 2098 {
@@ -1975,7 +2213,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1975 2213
1976 bool sameParcel = here.GlobalID == there.GlobalID; 2214 bool sameParcel = here.GlobalID == there.GlobalID;
1977 2215
1978 if (!sameParcel && !World.Permissions.CanRezObject(m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))) 2216 if (!sameParcel && !World.Permissions.CanObjectEntry(m_host.UUID, false, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)))
1979 { 2217 {
1980 return 0; 2218 return 0;
1981 } 2219 }
@@ -2024,24 +2262,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2024 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2262 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2025 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2263 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2026 { 2264 {
2027 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2265 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2266 return;
2267
2028 LSL_Vector currentPos = GetPartLocalPos(part); 2268 LSL_Vector currentPos = GetPartLocalPos(part);
2269 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2029 2270
2030 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2031 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2032 2271
2033 if (part.ParentGroup.RootPart == part) 2272 if (part.ParentGroup.RootPart == part)
2034 { 2273 {
2035 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2036 targetPos.z = ground;
2037 SceneObjectGroup parent = part.ParentGroup; 2274 SceneObjectGroup parent = part.ParentGroup;
2038 LSL_Vector real_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); 2275 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2039 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2276 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2277 return;
2278 Util.FireAndForget(delegate(object x) {
2279 parent.UpdateGroupPosition(dest);
2280 });
2040 } 2281 }
2041 else 2282 else
2042 { 2283 {
2043 LSL_Vector rel_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); 2284 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2044 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2045 SceneObjectGroup parent = part.ParentGroup; 2285 SceneObjectGroup parent = part.ParentGroup;
2046 parent.HasGroupChanged = true; 2286 parent.HasGroupChanged = true;
2047 parent.ScheduleGroupForTerseUpdate(); 2287 parent.ScheduleGroupForTerseUpdate();
@@ -2074,17 +2314,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2074 else 2314 else
2075 { 2315 {
2076 if (part.ParentGroup.IsAttachment) 2316 if (part.ParentGroup.IsAttachment)
2077 {
2078 pos = part.AttachedPos; 2317 pos = part.AttachedPos;
2079 }
2080 else 2318 else
2081 {
2082 pos = part.AbsolutePosition; 2319 pos = part.AbsolutePosition;
2083 }
2084 } 2320 }
2085 2321
2086// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2087
2088 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2322 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2089 } 2323 }
2090 2324
@@ -2093,18 +2327,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2093 m_host.AddScriptLPS(1); 2327 m_host.AddScriptLPS(1);
2094 2328
2095 // try to let this work as in SL... 2329 // try to let this work as in SL...
2096 if (m_host.ParentID == 0) 2330 if (m_host.LinkNum < 2)
2097 { 2331 {
2098 // special case: If we are root, rotate complete SOG to new rotation 2332 // Special case: If we are root, rotate complete SOG to new
2333 // rotation.
2334 // We are root if the link number is 0 (single prim) or 1
2335 // (root prim). ParentID may be nonzero in attachments and
2336 // using it would cause attachments and HUDs to rotate
2337 // to the wrong positions.
2338
2099 SetRot(m_host, Rot2Quaternion(rot)); 2339 SetRot(m_host, Rot2Quaternion(rot));
2100 } 2340 }
2101 else 2341 else
2102 { 2342 {
2103 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2343 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2104 SceneObjectPart rootPart = m_host.ParentGroup.RootPart; 2344 SceneObjectPart rootPart;
2105 if (rootPart != null) // better safe than sorry 2345 if (m_host.ParentGroup != null) // better safe than sorry
2106 { 2346 {
2107 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); 2347 rootPart = m_host.ParentGroup.RootPart;
2348 if (rootPart != null)
2349 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2108 } 2350 }
2109 } 2351 }
2110 2352
@@ -2114,31 +2356,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2114 public void llSetLocalRot(LSL_Rotation rot) 2356 public void llSetLocalRot(LSL_Rotation rot)
2115 { 2357 {
2116 m_host.AddScriptLPS(1); 2358 m_host.AddScriptLPS(1);
2359
2117 SetRot(m_host, Rot2Quaternion(rot)); 2360 SetRot(m_host, Rot2Quaternion(rot));
2118 ScriptSleep(200); 2361 ScriptSleep(200);
2119 } 2362 }
2120 2363
2121 protected void SetRot(SceneObjectPart part, Quaternion rot) 2364 protected void SetRot(SceneObjectPart part, Quaternion rot)
2122 { 2365 {
2123 part.UpdateRotation(rot); 2366 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2124 // Update rotation does not move the object in the physics scene if it's a linkset. 2367 return;
2125 2368
2126//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2369 bool isroot = (part == part.ParentGroup.RootPart);
2127// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2370 bool isphys;
2128 2371
2129 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2130 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2131 // It's perfectly okay when the object is not an active physical body though.
2132 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2133 // but only if the object is not physial and active. This is important for rotating doors.
2134 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2135 // scene
2136 PhysicsActor pa = part.PhysActor; 2372 PhysicsActor pa = part.PhysActor;
2137 2373
2138 if (pa != null && !pa.IsPhysical) 2374 // keep using physactor ideia of isphysical
2375 // it should be SOP ideia of that
2376 // not much of a issue with ubitODE
2377 if (pa != null && pa.IsPhysical)
2378 isphys = true;
2379 else
2380 isphys = false;
2381
2382 // SL doesn't let scripts rotate root of physical linksets
2383 if (isroot && isphys)
2384 return;
2385
2386 part.UpdateRotation(rot);
2387
2388 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2389 // so do a nasty update of parts positions if is a root part rotation
2390 if (isroot && pa != null) // with if above implies non physical root part
2139 { 2391 {
2140 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2392 part.ParentGroup.ResetChildPrimPhysicsPositions();
2141 } 2393 }
2394 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2395 {
2396 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2397 if (sittingavas.Count > 0)
2398 {
2399 foreach (ScenePresence av in sittingavas)
2400 {
2401 if (isroot || part.LocalId == av.ParentID)
2402 av.SendTerseUpdateToAllClients();
2403 }
2404 }
2405 }
2142 } 2406 }
2143 2407
2144 /// <summary> 2408 /// <summary>
@@ -2186,8 +2450,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2186 2450
2187 public LSL_Rotation llGetLocalRot() 2451 public LSL_Rotation llGetLocalRot()
2188 { 2452 {
2453 return GetPartLocalRot(m_host);
2454 }
2455
2456 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2457 {
2189 m_host.AddScriptLPS(1); 2458 m_host.AddScriptLPS(1);
2190 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2459 Quaternion rot = part.RotationOffset;
2460 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2191 } 2461 }
2192 2462
2193 public void llSetForce(LSL_Vector force, int local) 2463 public void llSetForce(LSL_Vector force, int local)
@@ -2271,16 +2541,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2271 m_host.ApplyImpulse(v, local != 0); 2541 m_host.ApplyImpulse(v, local != 0);
2272 } 2542 }
2273 2543
2544
2274 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2545 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2275 { 2546 {
2276 m_host.AddScriptLPS(1); 2547 m_host.AddScriptLPS(1);
2277 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2548 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2278 } 2549 }
2279 2550
2280 public void llSetTorque(LSL_Vector torque, int local) 2551 public void llSetTorque(LSL_Vector torque, int local)
2281 { 2552 {
2282 m_host.AddScriptLPS(1); 2553 m_host.AddScriptLPS(1);
2283 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2554 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2284 } 2555 }
2285 2556
2286 public LSL_Vector llGetTorque() 2557 public LSL_Vector llGetTorque()
@@ -2297,20 +2568,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2297 llSetTorque(torque, local); 2568 llSetTorque(torque, local);
2298 } 2569 }
2299 2570
2571 public void llSetVelocity(LSL_Vector vel, int local)
2572 {
2573 m_host.AddScriptLPS(1);
2574 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2575 }
2576
2300 public LSL_Vector llGetVel() 2577 public LSL_Vector llGetVel()
2301 { 2578 {
2302 m_host.AddScriptLPS(1); 2579 m_host.AddScriptLPS(1);
2303 2580
2304 Vector3 vel; 2581 Vector3 vel = Vector3.Zero;
2305 2582
2306 if (m_host.ParentGroup.IsAttachment) 2583 if (m_host.ParentGroup.IsAttachment)
2307 { 2584 {
2308 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2585 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2309 vel = avatar.Velocity; 2586 if (avatar != null)
2587 vel = avatar.Velocity;
2310 } 2588 }
2311 else 2589 else
2312 { 2590 {
2313 vel = m_host.Velocity; 2591 vel = m_host.ParentGroup.RootPart.Velocity;
2314 } 2592 }
2315 2593
2316 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2594 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2322,10 +2600,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2322 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2600 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2323 } 2601 }
2324 2602
2603 public void llSetAngularVelocity(LSL_Vector avel, int local)
2604 {
2605 m_host.AddScriptLPS(1);
2606 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2607 }
2608
2325 public LSL_Vector llGetOmega() 2609 public LSL_Vector llGetOmega()
2326 { 2610 {
2327 m_host.AddScriptLPS(1); 2611 m_host.AddScriptLPS(1);
2328 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2612 Vector3 avel = m_host.AngularVelocity;
2613 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2329 } 2614 }
2330 2615
2331 public LSL_Float llGetTimeOfDay() 2616 public LSL_Float llGetTimeOfDay()
@@ -2854,16 +3139,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2854 new_group.RootPart.UUID.ToString()) }, 3139 new_group.RootPart.UUID.ToString()) },
2855 new DetectParams[0])); 3140 new DetectParams[0]));
2856 3141
2857 float groupmass = new_group.GetMass(); 3142 // do recoil
3143 SceneObjectGroup hostgrp = m_host.ParentGroup;
3144 if (hostgrp == null)
3145 return;
3146
3147 if (hostgrp.IsAttachment) // don't recoil avatars
3148 return;
2858 3149
2859 PhysicsActor pa = new_group.RootPart.PhysActor; 3150 PhysicsActor pa = new_group.RootPart.PhysActor;
2860 3151
2861 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) 3152 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero)
2862 { 3153 {
2863 //Recoil. 3154 float groupmass = new_group.GetMass();
2864 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); 3155 llvel *= -groupmass;
3156 llApplyImpulse(new LSL_Vector(llvel.X, llvel.Y,llvel.Z), 0);
2865 } 3157 }
2866 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3158 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3159 return;
3160
2867 }); 3161 });
2868 3162
2869 //ScriptSleep((int)((groupmass * velmag) / 10)); 3163 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2878,35 +3172,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2878 public void llLookAt(LSL_Vector target, double strength, double damping) 3172 public void llLookAt(LSL_Vector target, double strength, double damping)
2879 { 3173 {
2880 m_host.AddScriptLPS(1); 3174 m_host.AddScriptLPS(1);
2881 // Determine where we are looking from
2882 LSL_Vector from = llGetPos();
2883 3175
2884 // Work out the normalised vector from the source to the target 3176 // Get the normalized vector to the target
2885 LSL_Vector delta = llVecNorm(target - from); 3177 LSL_Vector d1 = llVecNorm(target - llGetPos());
2886 LSL_Vector angle = new LSL_Vector(0,0,0);
2887 3178
2888 // Calculate the yaw 3179 // Get the bearing (yaw)
2889 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3180 LSL_Vector a1 = new LSL_Vector(0,0,0);
2890 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3181 a1.z = llAtan2(d1.y, d1.x);
2891 3182
2892 // Calculate pitch 3183 // Get the elevation (pitch)
2893 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3184 LSL_Vector a2 = new LSL_Vector(0,0,0);
3185 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2894 3186
2895 // we need to convert from a vector describing 3187 LSL_Rotation r1 = llEuler2Rot(a1);
2896 // the angles of rotation in radians into rotation value 3188 LSL_Rotation r2 = llEuler2Rot(a2);
2897 LSL_Rotation rot = llEuler2Rot(angle); 3189 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2898
2899 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2900 // set the rotation of the object, copy that behavior
2901 PhysicsActor pa = m_host.PhysActor;
2902 3190
2903 if (strength == 0 || pa == null || !pa.IsPhysical) 3191 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2904 { 3192 {
2905 llSetRot(rot); 3193 // Do nothing if either value is 0 (this has been checked in SL)
3194 if (strength <= 0.0 || damping <= 0.0)
3195 return;
3196
3197 llSetRot(r3 * r2 * r1);
2906 } 3198 }
2907 else 3199 else
2908 { 3200 {
2909 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3201 if (strength == 0)
3202 {
3203 llSetRot(r3 * r2 * r1);
3204 return;
3205 }
3206
3207 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2910 } 3208 }
2911 } 3209 }
2912 3210
@@ -2952,17 +3250,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2952 } 3250 }
2953 else 3251 else
2954 { 3252 {
2955 if (m_host.IsRoot) 3253 // new SL always returns object mass
2956 { 3254// if (m_host.IsRoot)
3255// {
2957 return m_host.ParentGroup.GetMass(); 3256 return m_host.ParentGroup.GetMass();
2958 } 3257// }
2959 else 3258// else
2960 { 3259// {
2961 return m_host.GetMass(); 3260// return m_host.GetMass();
2962 } 3261// }
2963 } 3262 }
2964 } 3263 }
2965 3264
3265
3266 public LSL_Float llGetMassMKS()
3267 {
3268 return 100f * llGetMass();
3269 }
3270
2966 public void llCollisionFilter(string name, string id, int accept) 3271 public void llCollisionFilter(string name, string id, int accept)
2967 { 3272 {
2968 m_host.AddScriptLPS(1); 3273 m_host.AddScriptLPS(1);
@@ -3037,7 +3342,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3037 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3342 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3038 3343
3039 if (attachmentsModule != null) 3344 if (attachmentsModule != null)
3040 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false); 3345 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true);
3041 else 3346 else
3042 return false; 3347 return false;
3043 } 3348 }
@@ -3067,9 +3372,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3067 { 3372 {
3068 m_host.AddScriptLPS(1); 3373 m_host.AddScriptLPS(1);
3069 3374
3070// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3071// return;
3072
3073 if (m_item.PermsGranter != m_host.OwnerID) 3375 if (m_item.PermsGranter != m_host.OwnerID)
3074 return; 3376 return;
3075 3377
@@ -3112,6 +3414,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3112 3414
3113 public void llInstantMessage(string user, string message) 3415 public void llInstantMessage(string user, string message)
3114 { 3416 {
3417 UUID result;
3418 if (!UUID.TryParse(user, out result))
3419 {
3420 ShoutError("An invalid key was passed to llInstantMessage");
3421 ScriptSleep(2000);
3422 return;
3423 }
3424
3425
3115 m_host.AddScriptLPS(1); 3426 m_host.AddScriptLPS(1);
3116 3427
3117 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3428 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3126,14 +3437,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3126 UUID friendTransactionID = UUID.Random(); 3437 UUID friendTransactionID = UUID.Random();
3127 3438
3128 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3439 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3129 3440
3130 GridInstantMessage msg = new GridInstantMessage(); 3441 GridInstantMessage msg = new GridInstantMessage();
3131 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3442 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3132 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3443 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3133 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3444 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3134// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3445// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3135// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3446// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3136 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3447// DateTime dt = DateTime.UtcNow;
3448//
3449// // Ticks from UtcNow, but make it look like local. Evil, huh?
3450// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3451//
3452// try
3453// {
3454// // Convert that to the PST timezone
3455// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3456// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3457// }
3458// catch
3459// {
3460// // No logging here, as it could be VERY spammy
3461// }
3462//
3463// // And make it look local again to fool the unix time util
3464// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3465
3466 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3467
3137 //if (client != null) 3468 //if (client != null)
3138 //{ 3469 //{
3139 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3470 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3147,12 +3478,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3147 msg.message = message.Substring(0, 1024); 3478 msg.message = message.Substring(0, 1024);
3148 else 3479 else
3149 msg.message = message; 3480 msg.message = message;
3150 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3481 msg.dialog = (byte)19; // MessageFromObject
3151 msg.fromGroup = false;// fromGroup; 3482 msg.fromGroup = false;// fromGroup;
3152 msg.offline = (byte)0; //offline; 3483 msg.offline = (byte)0; //offline;
3153 msg.ParentEstateID = 0; //ParentEstateID; 3484 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3154 msg.Position = new Vector3(m_host.AbsolutePosition); 3485 msg.Position = new Vector3(m_host.AbsolutePosition);
3155 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3486 msg.RegionID = World.RegionInfo.RegionID.Guid;
3156 msg.binaryBucket 3487 msg.binaryBucket
3157 = Util.StringToBytes256( 3488 = Util.StringToBytes256(
3158 "{0}/{1}/{2}/{3}", 3489 "{0}/{1}/{2}/{3}",
@@ -3180,7 +3511,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3180 } 3511 }
3181 3512
3182 emailModule.SendEmail(m_host.UUID, address, subject, message); 3513 emailModule.SendEmail(m_host.UUID, address, subject, message);
3183 llSleep(EMAIL_PAUSE_TIME); 3514 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3184 } 3515 }
3185 3516
3186 public void llGetNextEmail(string address, string subject) 3517 public void llGetNextEmail(string address, string subject)
@@ -3424,15 +3755,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3424 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3755 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3425 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3756 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3426 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3757 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3758 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3427 ScriptBaseClass.PERMISSION_ATTACH; 3759 ScriptBaseClass.PERMISSION_ATTACH;
3428 3760
3429 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3761 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3430 { 3762 {
3431 lock (m_host.TaskInventory) 3763 m_host.TaskInventory.LockItemsForWrite(true);
3432 { 3764 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3433 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3765 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3434 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3766 m_host.TaskInventory.LockItemsForWrite(false);
3435 }
3436 3767
3437 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3768 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3438 "run_time_permissions", new Object[] { 3769 "run_time_permissions", new Object[] {
@@ -3442,28 +3773,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3442 return; 3773 return;
3443 } 3774 }
3444 } 3775 }
3445 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3776 else
3446 { 3777 {
3447 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3778 bool sitting = false;
3448 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3779 if (m_host.SitTargetAvatar == agentID)
3449 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3780 {
3450 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3781 sitting = true;
3451 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3782 }
3783 else
3784 {
3785 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3786 {
3787 if (p.SitTargetAvatar == agentID)
3788 sitting = true;
3789 }
3790 }
3452 3791
3453 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3792 if (sitting)
3454 { 3793 {
3455 lock (m_host.TaskInventory) 3794 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3795 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3796 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3797 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3798 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3799
3800 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3456 { 3801 {
3802 m_host.TaskInventory.LockItemsForWrite(true);
3457 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3803 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3458 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3804 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3459 } 3805 m_host.TaskInventory.LockItemsForWrite(false);
3460 3806
3461 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3807 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3462 "run_time_permissions", new Object[] { 3808 "run_time_permissions", new Object[] {
3463 new LSL_Integer(perm) }, 3809 new LSL_Integer(perm) },
3464 new DetectParams[0])); 3810 new DetectParams[0]));
3465 3811
3466 return; 3812 return;
3813 }
3467 } 3814 }
3468 } 3815 }
3469 3816
@@ -3500,11 +3847,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3500 3847
3501 if (!m_waitingForScriptAnswer) 3848 if (!m_waitingForScriptAnswer)
3502 { 3849 {
3503 lock (m_host.TaskInventory) 3850 m_host.TaskInventory.LockItemsForWrite(true);
3504 { 3851 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3505 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3852 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3506 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3853 m_host.TaskInventory.LockItemsForWrite(false);
3507 }
3508 3854
3509 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3855 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3510 m_waitingForScriptAnswer=true; 3856 m_waitingForScriptAnswer=true;
@@ -3533,14 +3879,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3533 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3879 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3534 llReleaseControls(); 3880 llReleaseControls();
3535 3881
3536 lock (m_host.TaskInventory) 3882 m_host.TaskInventory.LockItemsForWrite(true);
3537 { 3883 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3538 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3884 m_host.TaskInventory.LockItemsForWrite(false);
3539 } 3885
3540 3886 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3541 m_ScriptEngine.PostScriptEvent( 3887 "run_time_permissions", new Object[] {
3542 m_item.ItemID, 3888 new LSL_Integer(answer) },
3543 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3889 new DetectParams[0]));
3544 } 3890 }
3545 3891
3546 public LSL_String llGetPermissionsKey() 3892 public LSL_String llGetPermissionsKey()
@@ -3579,14 +3925,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3579 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3925 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3580 { 3926 {
3581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3927 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3582 3928 if (parts.Count > 0)
3583 foreach (SceneObjectPart part in parts) 3929 {
3584 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3930 try
3931 {
3932 parts[0].ParentGroup.areUpdatesSuspended = true;
3933 foreach (SceneObjectPart part in parts)
3934 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3935 }
3936 finally
3937 {
3938 parts[0].ParentGroup.areUpdatesSuspended = false;
3939 }
3940 }
3585 } 3941 }
3586 3942
3587 public void llCreateLink(string target, int parent) 3943 public void llCreateLink(string target, int parent)
3588 { 3944 {
3589 m_host.AddScriptLPS(1); 3945 m_host.AddScriptLPS(1);
3946
3590 UUID targetID; 3947 UUID targetID;
3591 3948
3592 if (!UUID.TryParse(target, out targetID)) 3949 if (!UUID.TryParse(target, out targetID))
@@ -3692,10 +4049,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3692 // Restructuring Multiple Prims. 4049 // Restructuring Multiple Prims.
3693 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4050 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3694 parts.Remove(parentPrim.RootPart); 4051 parts.Remove(parentPrim.RootPart);
3695 foreach (SceneObjectPart part in parts) 4052 if (parts.Count > 0)
3696 { 4053 {
3697 parentPrim.DelinkFromGroup(part.LocalId, true); 4054 try
4055 {
4056 parts[0].ParentGroup.areUpdatesSuspended = true;
4057 foreach (SceneObjectPart part in parts)
4058 {
4059 parentPrim.DelinkFromGroup(part.LocalId, true);
4060 }
4061 }
4062 finally
4063 {
4064 parts[0].ParentGroup.areUpdatesSuspended = false;
4065 }
3698 } 4066 }
4067
3699 parentPrim.HasGroupChanged = true; 4068 parentPrim.HasGroupChanged = true;
3700 parentPrim.ScheduleGroupForFullUpdate(); 4069 parentPrim.ScheduleGroupForFullUpdate();
3701 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4070 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3704,12 +4073,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3704 { 4073 {
3705 SceneObjectPart newRoot = parts[0]; 4074 SceneObjectPart newRoot = parts[0];
3706 parts.Remove(newRoot); 4075 parts.Remove(newRoot);
3707 foreach (SceneObjectPart part in parts) 4076
4077 try
3708 { 4078 {
3709 // Required for linking 4079 parts[0].ParentGroup.areUpdatesSuspended = true;
3710 part.ClearUpdateSchedule(); 4080 foreach (SceneObjectPart part in parts)
3711 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4081 {
4082 part.ClearUpdateSchedule();
4083 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4084 }
3712 } 4085 }
4086 finally
4087 {
4088 parts[0].ParentGroup.areUpdatesSuspended = false;
4089 }
4090
4091
3713 newRoot.ParentGroup.HasGroupChanged = true; 4092 newRoot.ParentGroup.HasGroupChanged = true;
3714 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4093 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3715 } 4094 }
@@ -3729,6 +4108,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3729 public void llBreakAllLinks() 4108 public void llBreakAllLinks()
3730 { 4109 {
3731 m_host.AddScriptLPS(1); 4110 m_host.AddScriptLPS(1);
4111
4112 TaskInventoryItem item = m_item;
4113
4114 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4115 && !m_automaticLinkPermission)
4116 {
4117 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4118 return;
4119 }
4120
3732 SceneObjectGroup parentPrim = m_host.ParentGroup; 4121 SceneObjectGroup parentPrim = m_host.ParentGroup;
3733 if (parentPrim.AttachmentPoint != 0) 4122 if (parentPrim.AttachmentPoint != 0)
3734 return; // Fail silently if attached 4123 return; // Fail silently if attached
@@ -3748,25 +4137,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3748 public LSL_String llGetLinkKey(int linknum) 4137 public LSL_String llGetLinkKey(int linknum)
3749 { 4138 {
3750 m_host.AddScriptLPS(1); 4139 m_host.AddScriptLPS(1);
3751 List<UUID> keytable = new List<UUID>();
3752 // parse for sitting avatare-uuids
3753 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3754 {
3755 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3756 keytable.Add(presence.UUID);
3757 });
3758
3759 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3760 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3761 {
3762 return keytable[totalprims - linknum].ToString();
3763 }
3764
3765 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3766 {
3767 return m_host.UUID.ToString();
3768 }
3769
3770 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4140 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3771 if (part != null) 4141 if (part != null)
3772 { 4142 {
@@ -3774,6 +4144,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3774 } 4144 }
3775 else 4145 else
3776 { 4146 {
4147 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4148 {
4149 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4150
4151 if (linknum < 0)
4152 return UUID.Zero.ToString();
4153
4154 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4155 if (avatars.Count > linknum)
4156 {
4157 return avatars[linknum].UUID.ToString();
4158 }
4159 }
3777 return UUID.Zero.ToString(); 4160 return UUID.Zero.ToString();
3778 } 4161 }
3779 } 4162 }
@@ -3873,17 +4256,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3873 m_host.AddScriptLPS(1); 4256 m_host.AddScriptLPS(1);
3874 int count = 0; 4257 int count = 0;
3875 4258
3876 lock (m_host.TaskInventory) 4259 m_host.TaskInventory.LockItemsForRead(true);
4260 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3877 { 4261 {
3878 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4262 if (inv.Value.Type == type || type == -1)
3879 { 4263 {
3880 if (inv.Value.Type == type || type == -1) 4264 count = count + 1;
3881 {
3882 count = count + 1;
3883 }
3884 } 4265 }
3885 } 4266 }
3886 4267
4268 m_host.TaskInventory.LockItemsForRead(false);
3887 return count; 4269 return count;
3888 } 4270 }
3889 4271
@@ -3892,16 +4274,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3892 m_host.AddScriptLPS(1); 4274 m_host.AddScriptLPS(1);
3893 ArrayList keys = new ArrayList(); 4275 ArrayList keys = new ArrayList();
3894 4276
3895 lock (m_host.TaskInventory) 4277 m_host.TaskInventory.LockItemsForRead(true);
4278 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3896 { 4279 {
3897 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4280 if (inv.Value.Type == type || type == -1)
3898 { 4281 {
3899 if (inv.Value.Type == type || type == -1) 4282 keys.Add(inv.Value.Name);
3900 {
3901 keys.Add(inv.Value.Name);
3902 }
3903 } 4283 }
3904 } 4284 }
4285 m_host.TaskInventory.LockItemsForRead(false);
3905 4286
3906 if (keys.Count == 0) 4287 if (keys.Count == 0)
3907 { 4288 {
@@ -3939,7 +4320,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3939 if (item == null) 4320 if (item == null)
3940 { 4321 {
3941 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4322 llSay(0, String.Format("Could not find object '{0}'", inventory));
3942 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4323 return;
4324// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3943 } 4325 }
3944 4326
3945 UUID objId = item.ItemID; 4327 UUID objId = item.ItemID;
@@ -3967,33 +4349,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3967 return; 4349 return;
3968 } 4350 }
3969 } 4351 }
4352
3970 // destination is an avatar 4353 // destination is an avatar
3971 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4354 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3972 4355
3973 if (agentItem == null) 4356 if (agentItem == null)
3974 return; 4357 return;
3975 4358
3976 if (m_TransferModule != null) 4359 byte[] bucket = new byte[1];
3977 { 4360 bucket[0] = (byte)item.Type;
3978 byte[] bucket = new byte[] { (byte)item.Type }; 4361 //byte[] objBytes = agentItem.ID.GetBytes();
4362 //Array.Copy(objBytes, 0, bucket, 1, 16);
3979 4363
3980 GridInstantMessage msg = new GridInstantMessage(World, 4364 GridInstantMessage msg = new GridInstantMessage(World,
3981 m_host.UUID, m_host.Name + ", an object owned by " + 4365 m_host.OwnerID, m_host.Name, destId,
3982 resolveName(m_host.OwnerID) + ",", destId, 4366 (byte)InstantMessageDialog.TaskInventoryOffered,
3983 (byte)InstantMessageDialog.TaskInventoryOffered, 4367 false, item.Name+". "+m_host.Name+" is located at "+
3984 false, item.Name + "\n" + m_host.Name + " is located at " + 4368 World.RegionInfo.RegionName+" "+
3985 World.RegionInfo.RegionName+" "+ 4369 m_host.AbsolutePosition.ToString(),
3986 m_host.AbsolutePosition.ToString(), 4370 agentItem.ID, true, m_host.AbsolutePosition,
3987 agentItem.ID, true, m_host.AbsolutePosition, 4371 bucket);
3988 bucket);
3989 4372
3990 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4373 ScenePresence sp;
3991 }
3992 4374
4375 if (World.TryGetScenePresence(destId, out sp))
4376 {
4377 sp.ControllingClient.SendInstantMessage(msg);
4378 }
4379 else
4380 {
4381 if (m_TransferModule != null)
4382 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4383 }
4384
4385 //This delay should only occur when giving inventory to avatars.
3993 ScriptSleep(3000); 4386 ScriptSleep(3000);
3994 } 4387 }
3995 } 4388 }
3996 4389
4390 [DebuggerNonUserCode]
3997 public void llRemoveInventory(string name) 4391 public void llRemoveInventory(string name)
3998 { 4392 {
3999 m_host.AddScriptLPS(1); 4393 m_host.AddScriptLPS(1);
@@ -4039,109 +4433,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4039 { 4433 {
4040 m_host.AddScriptLPS(1); 4434 m_host.AddScriptLPS(1);
4041 4435
4042 UUID uuid = (UUID)id; 4436 UUID uuid;
4043 PresenceInfo pinfo = null; 4437 if (UUID.TryParse(id, out uuid))
4044 UserAccount account;
4045
4046 UserInfoCacheEntry ce;
4047 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4048 { 4438 {
4049 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4439 PresenceInfo pinfo = null;
4050 if (account == null) 4440 UserAccount account;
4441
4442 UserInfoCacheEntry ce;
4443 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4051 { 4444 {
4052 m_userInfoCache[uuid] = null; // Cache negative 4445 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4053 return UUID.Zero.ToString(); 4446 if (account == null)
4054 } 4447 {
4448 m_userInfoCache[uuid] = null; // Cache negative
4449 return UUID.Zero.ToString();
4450 }
4055 4451
4056 4452
4057 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4453 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4058 if (pinfos != null && pinfos.Length > 0) 4454 if (pinfos != null && pinfos.Length > 0)
4059 {
4060 foreach (PresenceInfo p in pinfos)
4061 { 4455 {
4062 if (p.RegionID != UUID.Zero) 4456 foreach (PresenceInfo p in pinfos)
4063 { 4457 {
4064 pinfo = p; 4458 if (p.RegionID != UUID.Zero)
4459 {
4460 pinfo = p;
4461 }
4065 } 4462 }
4066 } 4463 }
4067 }
4068 4464
4069 ce = new UserInfoCacheEntry(); 4465 ce = new UserInfoCacheEntry();
4070 ce.time = Util.EnvironmentTickCount(); 4466 ce.time = Util.EnvironmentTickCount();
4071 ce.account = account; 4467 ce.account = account;
4072 ce.pinfo = pinfo; 4468 ce.pinfo = pinfo;
4073 } 4469 m_userInfoCache[uuid] = ce;
4074 else 4470 }
4075 { 4471 else
4076 if (ce == null) 4472 {
4077 return UUID.Zero.ToString(); 4473 if (ce == null)
4474 return UUID.Zero.ToString();
4078 4475
4079 account = ce.account; 4476 account = ce.account;
4080 pinfo = ce.pinfo; 4477 pinfo = ce.pinfo;
4081 } 4478 }
4082 4479
4083 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4480 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4084 {
4085 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4086 if (pinfos != null && pinfos.Length > 0)
4087 { 4481 {
4088 foreach (PresenceInfo p in pinfos) 4482 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4483 if (pinfos != null && pinfos.Length > 0)
4089 { 4484 {
4090 if (p.RegionID != UUID.Zero) 4485 foreach (PresenceInfo p in pinfos)
4091 { 4486 {
4092 pinfo = p; 4487 if (p.RegionID != UUID.Zero)
4488 {
4489 pinfo = p;
4490 }
4093 } 4491 }
4094 } 4492 }
4095 } 4493 else
4096 else 4494 pinfo = null;
4097 pinfo = null;
4098 4495
4099 ce.time = Util.EnvironmentTickCount(); 4496 ce.time = Util.EnvironmentTickCount();
4100 ce.pinfo = pinfo; 4497 ce.pinfo = pinfo;
4101 } 4498 }
4102 4499
4103 string reply = String.Empty; 4500 string reply = String.Empty;
4104 4501
4105 switch (data) 4502 switch (data)
4106 { 4503 {
4107 case 1: // DATA_ONLINE (0|1) 4504 case 1: // DATA_ONLINE (0|1)
4108 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4505 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4109 reply = "1"; 4506 reply = "1";
4110 else 4507 else
4111 reply = "0"; 4508 reply = "0";
4112 break; 4509 break;
4113 case 2: // DATA_NAME (First Last) 4510 case 2: // DATA_NAME (First Last)
4114 reply = account.FirstName + " " + account.LastName; 4511 reply = account.FirstName + " " + account.LastName;
4115 break; 4512 break;
4116 case 3: // DATA_BORN (YYYY-MM-DD) 4513 case 3: // DATA_BORN (YYYY-MM-DD)
4117 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4514 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4118 born = born.AddSeconds(account.Created); 4515 born = born.AddSeconds(account.Created);
4119 reply = born.ToString("yyyy-MM-dd"); 4516 reply = born.ToString("yyyy-MM-dd");
4120 break; 4517 break;
4121 case 4: // DATA_RATING (0,0,0,0,0,0) 4518 case 4: // DATA_RATING (0,0,0,0,0,0)
4122 reply = "0,0,0,0,0,0"; 4519 reply = "0,0,0,0,0,0";
4123 break; 4520 break;
4124 case 7: // DATA_USERLEVEL (integer) 4521 case 8: // DATA_PAYINFO (0|1|2|3)
4125 reply = account.UserLevel.ToString(); 4522 reply = "0";
4126 break; 4523 break;
4127 case 8: // DATA_PAYINFO (0|1|2|3) 4524 default:
4128 reply = "0"; 4525 return UUID.Zero.ToString(); // Raise no event
4129 break; 4526 }
4130 default:
4131 return UUID.Zero.ToString(); // Raise no event
4132 }
4133 4527
4134 UUID rq = UUID.Random(); 4528 UUID rq = UUID.Random();
4135 4529
4136 UUID tid = AsyncCommands. 4530 UUID tid = AsyncCommands.
4137 DataserverPlugin.RegisterRequest(m_host.LocalId, 4531 DataserverPlugin.RegisterRequest(m_host.LocalId,
4138 m_item.ItemID, rq.ToString()); 4532 m_item.ItemID, rq.ToString());
4139 4533
4140 AsyncCommands. 4534 AsyncCommands.
4141 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4535 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4142 4536
4143 ScriptSleep(100); 4537 ScriptSleep(100);
4144 return tid.ToString(); 4538 return tid.ToString();
4539 }
4540 else
4541 {
4542 ShoutError("Invalid UUID passed to llRequestAgentData.");
4543 }
4544 return "";
4145 } 4545 }
4146 4546
4147 public LSL_String llRequestInventoryData(string name) 4547 public LSL_String llRequestInventoryData(string name)
@@ -4198,13 +4598,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4198 if (UUID.TryParse(agent, out agentId)) 4598 if (UUID.TryParse(agent, out agentId))
4199 { 4599 {
4200 ScenePresence presence = World.GetScenePresence(agentId); 4600 ScenePresence presence = World.GetScenePresence(agentId);
4201 if (presence != null) 4601 if (presence != null && presence.PresenceType != PresenceType.Npc)
4202 { 4602 {
4603 // agent must not be a god
4604 if (presence.UserLevel >= 200) return;
4605
4203 // agent must be over the owners land 4606 // agent must be over the owners land
4204 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4607 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4205 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4608 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4206 { 4609 {
4207 World.TeleportClientHome(agentId, presence.ControllingClient); 4610 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4611 {
4612 // They can't be teleported home for some reason
4613 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4614 if (regionInfo != null)
4615 {
4616 World.RequestTeleportLocation(
4617 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4618 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4619 }
4620 }
4208 } 4621 }
4209 } 4622 }
4210 } 4623 }
@@ -4316,7 +4729,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4316 UUID av = new UUID(); 4729 UUID av = new UUID();
4317 if (!UUID.TryParse(agent,out av)) 4730 if (!UUID.TryParse(agent,out av))
4318 { 4731 {
4319 LSLError("First parameter to llDialog needs to be a key"); 4732 //LSLError("First parameter to llDialog needs to be a key");
4320 return; 4733 return;
4321 } 4734 }
4322 4735
@@ -4348,7 +4761,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4348 public void llCollisionSound(string impact_sound, double impact_volume) 4761 public void llCollisionSound(string impact_sound, double impact_volume)
4349 { 4762 {
4350 m_host.AddScriptLPS(1); 4763 m_host.AddScriptLPS(1);
4351 4764
4765 if(impact_sound == "")
4766 {
4767 m_host.CollisionSoundVolume = (float)impact_volume;
4768 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4769 m_host.CollisionSoundType = 0;
4770 return;
4771 }
4352 // TODO: Parameter check logic required. 4772 // TODO: Parameter check logic required.
4353 UUID soundId = UUID.Zero; 4773 UUID soundId = UUID.Zero;
4354 if (!UUID.TryParse(impact_sound, out soundId)) 4774 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4361,6 +4781,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4361 4781
4362 m_host.CollisionSound = soundId; 4782 m_host.CollisionSound = soundId;
4363 m_host.CollisionSoundVolume = (float)impact_volume; 4783 m_host.CollisionSoundVolume = (float)impact_volume;
4784 m_host.CollisionSoundType = 1;
4364 } 4785 }
4365 4786
4366 public LSL_String llGetAnimation(string id) 4787 public LSL_String llGetAnimation(string id)
@@ -4374,14 +4795,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4374 4795
4375 if (m_host.RegionHandle == presence.RegionHandle) 4796 if (m_host.RegionHandle == presence.RegionHandle)
4376 { 4797 {
4377 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4378
4379 if (presence != null) 4798 if (presence != null)
4380 { 4799 {
4381 AnimationSet currentAnims = presence.Animator.Animations; 4800 if (presence.SitGround)
4382 string currentAnimationState = String.Empty; 4801 return "Sitting on Ground";
4383 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4802 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4384 return currentAnimationState; 4803 return "Sitting";
4804
4805 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4806 string lslMovementAnimation;
4807
4808 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4809 return lslMovementAnimation;
4385 } 4810 }
4386 } 4811 }
4387 4812
@@ -4528,7 +4953,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4528 { 4953 {
4529 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4954 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4530 float distance_term = distance * distance * distance; // Script Energy 4955 float distance_term = distance * distance * distance; // Script Energy
4531 float pusher_mass = m_host.GetMass(); 4956 // use total object mass and not part
4957 float pusher_mass = m_host.ParentGroup.GetMass();
4532 4958
4533 float PUSH_ATTENUATION_DISTANCE = 17f; 4959 float PUSH_ATTENUATION_DISTANCE = 17f;
4534 float PUSH_ATTENUATION_SCALE = 5f; 4960 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4778,6 +5204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4778 { 5204 {
4779 return item.AssetID.ToString(); 5205 return item.AssetID.ToString();
4780 } 5206 }
5207 m_host.TaskInventory.LockItemsForRead(false);
4781 5208
4782 return UUID.Zero.ToString(); 5209 return UUID.Zero.ToString();
4783 } 5210 }
@@ -4911,7 +5338,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4911 public LSL_Vector llGetCenterOfMass() 5338 public LSL_Vector llGetCenterOfMass()
4912 { 5339 {
4913 m_host.AddScriptLPS(1); 5340 m_host.AddScriptLPS(1);
4914 Vector3 center = m_host.GetGeometricCenter(); 5341 Vector3 center = m_host.GetCenterOfMass();
4915 return new LSL_Vector(center.X,center.Y,center.Z); 5342 return new LSL_Vector(center.X,center.Y,center.Z);
4916 } 5343 }
4917 5344
@@ -4930,14 +5357,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4930 { 5357 {
4931 m_host.AddScriptLPS(1); 5358 m_host.AddScriptLPS(1);
4932 5359
4933 if (src == null) 5360 return src.Length;
4934 {
4935 return 0;
4936 }
4937 else
4938 {
4939 return src.Length;
4940 }
4941 } 5361 }
4942 5362
4943 public LSL_Integer llList2Integer(LSL_List src, int index) 5363 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4983,7 +5403,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4983 else if (src.Data[index] is LSL_Float) 5403 else if (src.Data[index] is LSL_Float)
4984 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5404 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4985 else if (src.Data[index] is LSL_String) 5405 else if (src.Data[index] is LSL_String)
4986 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5406 {
5407 string str = ((LSL_String) src.Data[index]).m_string;
5408 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5409 if (m != Match.Empty)
5410 {
5411 str = m.Value;
5412 double d = 0.0;
5413 if (!Double.TryParse(str, out d))
5414 return 0.0;
5415
5416 return d;
5417 }
5418 return 0.0;
5419 }
4987 return Convert.ToDouble(src.Data[index]); 5420 return Convert.ToDouble(src.Data[index]);
4988 } 5421 }
4989 catch (FormatException) 5422 catch (FormatException)
@@ -5256,7 +5689,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5256 } 5689 }
5257 } 5690 }
5258 } 5691 }
5259 else { 5692 else
5693 {
5260 object[] array = new object[src.Length]; 5694 object[] array = new object[src.Length];
5261 Array.Copy(src.Data, 0, array, 0, src.Length); 5695 Array.Copy(src.Data, 0, array, 0, src.Length);
5262 result = new LSL_List(array); 5696 result = new LSL_List(array);
@@ -5363,7 +5797,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5363 public LSL_Integer llGetRegionAgentCount() 5797 public LSL_Integer llGetRegionAgentCount()
5364 { 5798 {
5365 m_host.AddScriptLPS(1); 5799 m_host.AddScriptLPS(1);
5366 return new LSL_Integer(World.GetRootAgentCount()); 5800
5801 int count = 0;
5802 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5803 count++;
5804 });
5805
5806 return new LSL_Integer(count);
5367 } 5807 }
5368 5808
5369 public LSL_Vector llGetRegionCorner() 5809 public LSL_Vector llGetRegionCorner()
@@ -5643,6 +6083,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5643 flags |= ScriptBaseClass.AGENT_SITTING; 6083 flags |= ScriptBaseClass.AGENT_SITTING;
5644 } 6084 }
5645 6085
6086 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6087 {
6088 flags |= ScriptBaseClass.AGENT_MALE;
6089 }
6090
5646 return flags; 6091 return flags;
5647 } 6092 }
5648 6093
@@ -5789,10 +6234,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5789 m_host.AddScriptLPS(1); 6234 m_host.AddScriptLPS(1);
5790 6235
5791 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6236 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5792 6237 if (parts.Count > 0)
5793 foreach (var part in parts)
5794 { 6238 {
5795 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6239 try
6240 {
6241 parts[0].ParentGroup.areUpdatesSuspended = true;
6242 foreach (var part in parts)
6243 {
6244 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6245 }
6246 }
6247 finally
6248 {
6249 parts[0].ParentGroup.areUpdatesSuspended = false;
6250 }
5796 } 6251 }
5797 } 6252 }
5798 6253
@@ -5844,13 +6299,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5844 6299
5845 if (m_host.OwnerID == land.LandData.OwnerID) 6300 if (m_host.OwnerID == land.LandData.OwnerID)
5846 { 6301 {
5847 World.TeleportClientHome(agentID, presence.ControllingClient); 6302 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6303 presence.TeleportWithMomentum(pos, null);
6304 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5848 } 6305 }
5849 } 6306 }
5850 } 6307 }
5851 ScriptSleep(5000); 6308 ScriptSleep(5000);
5852 } 6309 }
5853 6310
6311 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6312 {
6313 return ParseString2List(str, separators, in_spacers, false);
6314 }
6315
5854 public LSL_Integer llOverMyLand(string id) 6316 public LSL_Integer llOverMyLand(string id)
5855 { 6317 {
5856 m_host.AddScriptLPS(1); 6318 m_host.AddScriptLPS(1);
@@ -5909,20 +6371,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5909 return agentSize; 6371 return agentSize;
5910 } 6372 }
5911 6373
5912 public LSL_Integer llSameGroup(string agent) 6374 public LSL_Integer llSameGroup(string id)
5913 { 6375 {
5914 m_host.AddScriptLPS(1); 6376 m_host.AddScriptLPS(1);
5915 UUID agentId = new UUID(); 6377 UUID uuid = new UUID();
5916 if (!UUID.TryParse(agent, out agentId)) 6378 if (!UUID.TryParse(id, out uuid))
5917 return new LSL_Integer(0); 6379 return new LSL_Integer(0);
5918 ScenePresence presence = World.GetScenePresence(agentId); 6380
5919 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6381 // Check if it's a group key
5920 return new LSL_Integer(0); 6382 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5921 IClientAPI client = presence.ControllingClient;
5922 if (m_host.GroupID == client.ActiveGroupId)
5923 return new LSL_Integer(1); 6383 return new LSL_Integer(1);
5924 else 6384
6385 // We got passed a UUID.Zero
6386 if (uuid == UUID.Zero)
6387 return new LSL_Integer(0);
6388
6389 // Handle the case where id names an avatar
6390 ScenePresence presence = World.GetScenePresence(uuid);
6391 if (presence != null)
6392 {
6393 if (presence.IsChildAgent)
6394 return new LSL_Integer(0);
6395
6396 IClientAPI client = presence.ControllingClient;
6397 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6398 return new LSL_Integer(1);
6399
5925 return new LSL_Integer(0); 6400 return new LSL_Integer(0);
6401 }
6402
6403 // Handle object case
6404 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6405 if (part != null)
6406 {
6407 // This will handle both deed and non-deed and also the no
6408 // group case
6409 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6410 return new LSL_Integer(1);
6411
6412 return new LSL_Integer(0);
6413 }
6414
6415 return new LSL_Integer(0);
5926 } 6416 }
5927 6417
5928 public void llUnSit(string id) 6418 public void llUnSit(string id)
@@ -6051,7 +6541,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6051 return m_host.ParentGroup.AttachmentPoint; 6541 return m_host.ParentGroup.AttachmentPoint;
6052 } 6542 }
6053 6543
6054 public LSL_Integer llGetFreeMemory() 6544 public virtual LSL_Integer llGetFreeMemory()
6055 { 6545 {
6056 m_host.AddScriptLPS(1); 6546 m_host.AddScriptLPS(1);
6057 // Make scripts designed for LSO happy 6547 // Make scripts designed for LSO happy
@@ -6168,7 +6658,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6168 SetParticleSystem(m_host, rules); 6658 SetParticleSystem(m_host, rules);
6169 } 6659 }
6170 6660
6171 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6661 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6662 {
6172 6663
6173 6664
6174 if (rules.Length == 0) 6665 if (rules.Length == 0)
@@ -6485,7 +6976,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6485 { 6976 {
6486 // LSL quaternions can normalize to 0, normal Quaternions can't. 6977 // LSL quaternions can normalize to 0, normal Quaternions can't.
6487 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 6978 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6488 rot.z = 1; // ZERO_ROTATION = 0,0,0,1 6979 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6489 6980
6490 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 6981 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z);
6491 part.SitTargetOrientation = Rot2Quaternion(rot); 6982 part.SitTargetOrientation = Rot2Quaternion(rot);
@@ -6642,13 +7133,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6642 UUID av = new UUID(); 7133 UUID av = new UUID();
6643 if (!UUID.TryParse(avatar,out av)) 7134 if (!UUID.TryParse(avatar,out av))
6644 { 7135 {
6645 LSLError("First parameter to llDialog needs to be a key"); 7136 //LSLError("First parameter to llDialog needs to be a key");
6646 return; 7137 return;
6647 } 7138 }
6648 if (buttons.Length < 1) 7139 if (buttons.Length < 1)
6649 { 7140 {
6650 LSLError("No less than 1 button can be shown"); 7141 buttons.Add("OK");
6651 return;
6652 } 7142 }
6653 if (buttons.Length > 12) 7143 if (buttons.Length > 12)
6654 { 7144 {
@@ -6665,7 +7155,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6665 } 7155 }
6666 if (buttons.Data[i].ToString().Length > 24) 7156 if (buttons.Data[i].ToString().Length > 24)
6667 { 7157 {
6668 LSLError("button label cannot be longer than 24 characters"); 7158 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6669 return; 7159 return;
6670 } 7160 }
6671 buts[i] = buttons.Data[i].ToString(); 7161 buts[i] = buttons.Data[i].ToString();
@@ -6732,9 +7222,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6732 return; 7222 return;
6733 } 7223 }
6734 7224
6735 // the rest of the permission checks are done in RezScript, so check the pin there as well 7225 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6736 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7226 if (dest != null)
7227 {
7228 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7229 {
7230 // the rest of the permission checks are done in RezScript, so check the pin there as well
7231 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6737 7232
7233 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7234 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7235 }
7236 }
6738 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7237 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6739 ScriptSleep(3000); 7238 ScriptSleep(3000);
6740 } 7239 }
@@ -6797,19 +7296,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6797 public LSL_String llMD5String(string src, int nonce) 7296 public LSL_String llMD5String(string src, int nonce)
6798 { 7297 {
6799 m_host.AddScriptLPS(1); 7298 m_host.AddScriptLPS(1);
6800 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7299 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6801 } 7300 }
6802 7301
6803 public LSL_String llSHA1String(string src) 7302 public LSL_String llSHA1String(string src)
6804 { 7303 {
6805 m_host.AddScriptLPS(1); 7304 m_host.AddScriptLPS(1);
6806 return Util.SHA1Hash(src).ToLower(); 7305 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6807 } 7306 }
6808 7307
6809 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7308 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6810 { 7309 {
6811 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7310 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6812 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7311 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7312 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7313 return shapeBlock;
6813 7314
6814 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7315 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6815 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7316 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6914,6 +7415,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6914 // Prim type box, cylinder and prism. 7415 // Prim type box, cylinder and prism.
6915 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) 7416 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)
6916 { 7417 {
7418 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7419 return;
7420
6917 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7421 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6918 ObjectShapePacket.ObjectDataBlock shapeBlock; 7422 ObjectShapePacket.ObjectDataBlock shapeBlock;
6919 7423
@@ -6967,6 +7471,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6967 // Prim type sphere. 7471 // Prim type sphere.
6968 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7472 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6969 { 7473 {
7474 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7475 return;
7476
6970 ObjectShapePacket.ObjectDataBlock shapeBlock; 7477 ObjectShapePacket.ObjectDataBlock shapeBlock;
6971 7478
6972 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7479 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7008,6 +7515,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7008 // Prim type torus, tube and ring. 7515 // Prim type torus, tube and ring.
7009 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) 7516 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)
7010 { 7517 {
7518 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7519 return;
7520
7011 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7521 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7012 ObjectShapePacket.ObjectDataBlock shapeBlock; 7522 ObjectShapePacket.ObjectDataBlock shapeBlock;
7013 7523
@@ -7143,6 +7653,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7143 // Prim type sculpt. 7653 // Prim type sculpt.
7144 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7654 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7145 { 7655 {
7656 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7657 return;
7658
7146 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7659 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7147 UUID sculptId; 7660 UUID sculptId;
7148 7661
@@ -7167,7 +7680,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7167 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7680 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7168 { 7681 {
7169 // default 7682 // default
7170 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7683 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7171 } 7684 }
7172 7685
7173 part.Shape.SetSculptProperties((byte)type, sculptId); 7686 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7183,34 +7696,298 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7183 ScriptSleep(200); 7696 ScriptSleep(200);
7184 } 7697 }
7185 7698
7186 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7699 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7187 { 7700 {
7188 m_host.AddScriptLPS(1); 7701 m_host.AddScriptLPS(1);
7189 7702
7190 setLinkPrimParams(linknumber, rules); 7703 setLinkPrimParams(linknumber, rules);
7704 }
7191 7705
7706 private void setLinkPrimParams(int linknumber, LSL_List rules)
7707 {
7708 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7709 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7710 if (parts.Count>0)
7711 {
7712 try
7713 {
7714 parts[0].ParentGroup.areUpdatesSuspended = true;
7715 foreach (SceneObjectPart part in parts)
7716 SetPrimParams(part, rules);
7717 }
7718 finally
7719 {
7720 parts[0].ParentGroup.areUpdatesSuspended = false;
7721 }
7722 }
7723 if (avatars.Count > 0)
7724 {
7725 foreach (ScenePresence avatar in avatars)
7726 SetPrimParams(avatar, rules);
7727 }
7728 }
7729
7730 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7731 float material_density, float material_friction,
7732 float material_restitution, float material_gravity_modifier)
7733 {
7734 ExtraPhysicsData physdata = new ExtraPhysicsData();
7735 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7736 physdata.Density = part.Density;
7737 physdata.Friction = part.Friction;
7738 physdata.Bounce = part.Bounciness;
7739 physdata.GravitationModifier = part.GravityModifier;
7740
7741 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7742 physdata.Density = material_density;
7743 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7744 physdata.Friction = material_friction;
7745 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7746 physdata.Bounce = material_restitution;
7747 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7748 physdata.GravitationModifier = material_gravity_modifier;
7749
7750 part.UpdateExtraPhysics(physdata);
7751 }
7752
7753 public void llSetPhysicsMaterial(int material_bits,
7754 float material_gravity_modifier, float material_restitution,
7755 float material_friction, float material_density)
7756 {
7757 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7758 }
7759
7760 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7761 {
7762 llSetLinkPrimitiveParamsFast(linknumber, rules);
7192 ScriptSleep(200); 7763 ScriptSleep(200);
7193 } 7764 }
7194 7765
7195 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7766 // vector up using libomv (c&p from sop )
7767 // vector up rotated by r
7768 private Vector3 Zrot(Quaternion r)
7196 { 7769 {
7197 m_host.AddScriptLPS(1); 7770 double x, y, z, m;
7198 7771
7199 setLinkPrimParams(linknumber, rules); 7772 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7773 if (Math.Abs(1.0 - m) > 0.000001)
7774 {
7775 m = 1.0 / Math.Sqrt(m);
7776 r.X *= (float)m;
7777 r.Y *= (float)m;
7778 r.Z *= (float)m;
7779 r.W *= (float)m;
7780 }
7781
7782 x = 2 * (r.X * r.Z + r.Y * r.W);
7783 y = 2 * (-r.X * r.W + r.Y * r.Z);
7784 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7785
7786 return new Vector3((float)x, (float)y, (float)z);
7200 } 7787 }
7201 7788
7202 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7789 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7203 { 7790 {
7204 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7791 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7205 7792
7206 foreach (SceneObjectPart part in parts) 7793 int idx = 0;
7207 SetPrimParams(part, rules); 7794
7795 bool positionChanged = false;
7796 Vector3 finalPos = Vector3.Zero;
7797
7798 try
7799 {
7800 while (idx < rules.Length)
7801 {
7802 int code = rules.GetLSLIntegerItem(idx++);
7803
7804 int remain = rules.Length - idx;
7805
7806 switch (code)
7807 {
7808 case (int)ScriptBaseClass.PRIM_POSITION:
7809 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7810 {
7811 if (remain < 1)
7812 return;
7813
7814 LSL_Vector v;
7815 v = rules.GetVector3Item(idx++);
7816
7817 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7818 if (part == null)
7819 break;
7820
7821 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7822 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7823 if (part.LinkNum > 1)
7824 {
7825 localRot = GetPartLocalRot(part);
7826 localPos = GetPartLocalPos(part);
7827 }
7828
7829 v -= localPos;
7830 v /= localRot;
7831
7832 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7833
7834 v = v + 2 * sitOffset;
7835
7836 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7837 av.SendAvatarDataToAllAgents();
7838
7839 }
7840 break;
7841
7842 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7843 case (int)ScriptBaseClass.PRIM_ROTATION:
7844 {
7845 if (remain < 1)
7846 return;
7847
7848 LSL_Rotation r;
7849 r = rules.GetQuaternionItem(idx++);
7850
7851 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7852 if (part == null)
7853 break;
7854
7855 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7856 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7857
7858 if (part.LinkNum > 1)
7859 localRot = GetPartLocalRot(part);
7860
7861 r = r * llGetRootRotation() / localRot;
7862 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7863 av.SendAvatarDataToAllAgents();
7864 }
7865 break;
7866
7867 // parse rest doing nothing but number of parameters error check
7868 case (int)ScriptBaseClass.PRIM_SIZE:
7869 case (int)ScriptBaseClass.PRIM_MATERIAL:
7870 case (int)ScriptBaseClass.PRIM_PHANTOM:
7871 case (int)ScriptBaseClass.PRIM_PHYSICS:
7872 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7873 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7874 case (int)ScriptBaseClass.PRIM_NAME:
7875 case (int)ScriptBaseClass.PRIM_DESC:
7876 if (remain < 1)
7877 return;
7878 idx++;
7879 break;
7880
7881 case (int)ScriptBaseClass.PRIM_GLOW:
7882 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7883 case (int)ScriptBaseClass.PRIM_TEXGEN:
7884 if (remain < 2)
7885 return;
7886 idx += 2;
7887 break;
7888
7889 case (int)ScriptBaseClass.PRIM_TYPE:
7890 if (remain < 3)
7891 return;
7892 code = (int)rules.GetLSLIntegerItem(idx++);
7893 remain = rules.Length - idx;
7894 switch (code)
7895 {
7896 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7897 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7898 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7899 if (remain < 6)
7900 return;
7901 idx += 6;
7902 break;
7903
7904 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7905 if (remain < 5)
7906 return;
7907 idx += 5;
7908 break;
7909
7910 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7911 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7912 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7913 if (remain < 11)
7914 return;
7915 idx += 11;
7916 break;
7917
7918 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7919 if (remain < 2)
7920 return;
7921 idx += 2;
7922 break;
7923 }
7924 break;
7925
7926 case (int)ScriptBaseClass.PRIM_COLOR:
7927 case (int)ScriptBaseClass.PRIM_TEXT:
7928 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7929 case (int)ScriptBaseClass.PRIM_OMEGA:
7930 if (remain < 3)
7931 return;
7932 idx += 3;
7933 break;
7934
7935 case (int)ScriptBaseClass.PRIM_TEXTURE:
7936 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7937 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
7938 if (remain < 5)
7939 return;
7940 idx += 5;
7941 break;
7942
7943 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
7944 if (remain < 7)
7945 return;
7946
7947 idx += 7;
7948 break;
7949
7950 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7951 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7952 return;
7953
7954 if (positionChanged)
7955 {
7956 positionChanged = false;
7957 av.OffsetPosition = finalPos;
7958// av.SendAvatarDataToAllAgents();
7959 av.SendTerseUpdateToAllClients();
7960 }
7961
7962 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7963 LSL_List new_rules = rules.GetSublist(idx, -1);
7964 setLinkPrimParams((int)new_linknumber, new_rules);
7965 return;
7966 }
7967 }
7968 }
7969
7970 finally
7971 {
7972 if (positionChanged)
7973 {
7974 av.OffsetPosition = finalPos;
7975// av.SendAvatarDataToAllAgents();
7976 av.SendTerseUpdateToAllClients();
7977 positionChanged = false;
7978 }
7979 }
7208 } 7980 }
7209 7981
7210 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7982 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7211 { 7983 {
7984 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7985 return;
7986
7212 int idx = 0; 7987 int idx = 0;
7213 7988
7989 SceneObjectGroup parentgrp = part.ParentGroup;
7990
7214 bool positionChanged = false; 7991 bool positionChanged = false;
7215 LSL_Vector currentPosition = GetPartLocalPos(part); 7992 LSL_Vector currentPosition = GetPartLocalPos(part);
7216 7993
@@ -7233,8 +8010,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7233 return; 8010 return;
7234 8011
7235 v=rules.GetVector3Item(idx++); 8012 v=rules.GetVector3Item(idx++);
7236 positionChanged = true;
7237 currentPosition = GetSetPosTarget(part, v, currentPosition); 8013 currentPosition = GetSetPosTarget(part, v, currentPosition);
8014 positionChanged = true;
7238 8015
7239 break; 8016 break;
7240 case (int)ScriptBaseClass.PRIM_SIZE: 8017 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7250,8 +8027,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7250 return; 8027 return;
7251 8028
7252 LSL_Rotation q = rules.GetQuaternionItem(idx++); 8029 LSL_Rotation q = rules.GetQuaternionItem(idx++);
8030 SceneObjectPart rootPart = parentgrp.RootPart;
7253 // try to let this work as in SL... 8031 // try to let this work as in SL...
7254 if (part.ParentID == 0) 8032 if (rootPart == part)
7255 { 8033 {
7256 // special case: If we are root, rotate complete SOG to new rotation 8034 // special case: If we are root, rotate complete SOG to new rotation
7257 SetRot(part, Rot2Quaternion(q)); 8035 SetRot(part, Rot2Quaternion(q));
@@ -7259,7 +8037,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7259 else 8037 else
7260 { 8038 {
7261 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 8039 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7262 SceneObjectPart rootPart = part.ParentGroup.RootPart; 8040 // sounds like sl bug that we need to replicate
7263 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 8041 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7264 } 8042 }
7265 8043
@@ -7512,7 +8290,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7512 return; 8290 return;
7513 8291
7514 string ph = rules.Data[idx++].ToString(); 8292 string ph = rules.Data[idx++].ToString();
7515 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8293 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7516 8294
7517 break; 8295 break;
7518 8296
@@ -7530,12 +8308,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7530 part.ScriptSetPhysicsStatus(physics); 8308 part.ScriptSetPhysicsStatus(physics);
7531 break; 8309 break;
7532 8310
8311 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8312 if (remain < 1)
8313 return;
8314
8315 int shape_type = rules.GetLSLIntegerItem(idx++);
8316
8317 ExtraPhysicsData physdata = new ExtraPhysicsData();
8318 physdata.Density = part.Density;
8319 physdata.Bounce = part.Bounciness;
8320 physdata.GravitationModifier = part.GravityModifier;
8321 physdata.PhysShapeType = (PhysShapeType)shape_type;
8322
8323 part.UpdateExtraPhysics(physdata);
8324
8325 break;
8326
8327 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8328 if (remain < 5)
8329 return;
8330
8331 int material_bits = rules.GetLSLIntegerItem(idx++);
8332 float material_density = (float)rules.GetLSLFloatItem(idx++);
8333 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8334 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8335 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8336
8337 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8338
8339 break;
8340
7533 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8341 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7534 if (remain < 1) 8342 if (remain < 1)
7535 return; 8343 return;
7536 string temp = rules.Data[idx++].ToString(); 8344 string temp = rules.Data[idx++].ToString();
7537 8345
7538 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8346 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7539 8347
7540 break; 8348 break;
7541 8349
@@ -7574,6 +8382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7574 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8382 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7575 if (remain < 1) 8383 if (remain < 1)
7576 return; 8384 return;
8385
7577 LSL_Rotation lr = rules.GetQuaternionItem(idx++); 8386 LSL_Rotation lr = rules.GetQuaternionItem(idx++);
7578 SetRot(part, Rot2Quaternion(lr)); 8387 SetRot(part, Rot2Quaternion(lr));
7579 break; 8388 break;
@@ -7585,13 +8394,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7585 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8394 LSL_Float gain = rules.GetLSLFloatItem(idx++);
7586 TargetOmega(part, axis, (double)spinrate, (double)gain); 8395 TargetOmega(part, axis, (double)spinrate, (double)gain);
7587 break; 8396 break;
8397
7588 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8398 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7589 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 8399 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7590 return; 8400 return;
8401
8402 // do a pending position change before jumping to other part/avatar
8403 if (positionChanged)
8404 {
8405 positionChanged = false;
8406 if (parentgrp == null)
8407 return;
8408
8409 if (parentgrp.RootPart == part)
8410 {
8411
8412 Util.FireAndForget(delegate(object x)
8413 {
8414 parentgrp.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8415 });
8416 }
8417 else
8418 {
8419 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8420 parentgrp.HasGroupChanged = true;
8421 parentgrp.ScheduleGroupForTerseUpdate();
8422 }
8423 }
8424
7591 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); 8425 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7592 LSL_List new_rules = rules.GetSublist(idx, -1); 8426 LSL_List new_rules = rules.GetSublist(idx, -1);
7593 setLinkPrimParams((int)new_linknumber, new_rules); 8427 setLinkPrimParams((int)new_linknumber, new_rules);
7594
7595 return; 8428 return;
7596 } 8429 }
7597 } 8430 }
@@ -7603,7 +8436,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7603 if (part.ParentGroup.RootPart == part) 8436 if (part.ParentGroup.RootPart == part)
7604 { 8437 {
7605 SceneObjectGroup parent = part.ParentGroup; 8438 SceneObjectGroup parent = part.ParentGroup;
7606 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8439 Util.FireAndForget(delegate(object x) {
8440 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8441 });
7607 } 8442 }
7608 else 8443 else
7609 { 8444 {
@@ -7647,10 +8482,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7647 8482
7648 public LSL_String llXorBase64Strings(string str1, string str2) 8483 public LSL_String llXorBase64Strings(string str1, string str2)
7649 { 8484 {
7650 m_host.AddScriptLPS(1); 8485 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7651 Deprecated("llXorBase64Strings"); 8486
7652 ScriptSleep(300); 8487 ScriptSleep(300);
7653 return String.Empty; 8488 m_host.AddScriptLPS(1);
8489
8490 if (str1 == String.Empty)
8491 return String.Empty;
8492 if (str2 == String.Empty)
8493 return str1;
8494
8495 int len = str2.Length;
8496 if ((len % 4) != 0) // LL is EVIL!!!!
8497 {
8498 while (str2.EndsWith("="))
8499 str2 = str2.Substring(0, str2.Length - 1);
8500
8501 len = str2.Length;
8502 int mod = len % 4;
8503
8504 if (mod == 1)
8505 str2 = str2.Substring(0, str2.Length - 1);
8506 else if (mod == 2)
8507 str2 += "==";
8508 else if (mod == 3)
8509 str2 += "=";
8510 }
8511
8512 byte[] data1;
8513 byte[] data2;
8514 try
8515 {
8516 data1 = Convert.FromBase64String(str1);
8517 data2 = Convert.FromBase64String(str2);
8518 }
8519 catch (Exception)
8520 {
8521 return new LSL_String(String.Empty);
8522 }
8523
8524 // For cases where the decoded length of s2 is greater
8525 // than the decoded length of s1, simply perform a normal
8526 // decode and XOR
8527 //
8528 if (data2.Length >= data1.Length)
8529 {
8530 for (int pos = 0 ; pos < data1.Length ; pos++ )
8531 data1[pos] ^= data2[pos];
8532
8533 return Convert.ToBase64String(data1);
8534 }
8535
8536 // Remove padding
8537 while (str1.EndsWith("="))
8538 str1 = str1.Substring(0, str1.Length - 1);
8539 while (str2.EndsWith("="))
8540 str2 = str2.Substring(0, str2.Length - 1);
8541
8542 byte[] d1 = new byte[str1.Length];
8543 byte[] d2 = new byte[str2.Length];
8544
8545 for (int i = 0 ; i < str1.Length ; i++)
8546 {
8547 int idx = b64.IndexOf(str1.Substring(i, 1));
8548 if (idx == -1)
8549 idx = 0;
8550 d1[i] = (byte)idx;
8551 }
8552
8553 for (int i = 0 ; i < str2.Length ; i++)
8554 {
8555 int idx = b64.IndexOf(str2.Substring(i, 1));
8556 if (idx == -1)
8557 idx = 0;
8558 d2[i] = (byte)idx;
8559 }
8560
8561 string output = String.Empty;
8562
8563 for (int pos = 0 ; pos < d1.Length ; pos++)
8564 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8565
8566 while (output.Length % 3 > 0)
8567 output += "=";
8568
8569 return output;
7654 } 8570 }
7655 8571
7656 public void llRemoteDataSetRegion() 8572 public void llRemoteDataSetRegion()
@@ -7774,13 +8690,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7774 public LSL_Integer llGetNumberOfPrims() 8690 public LSL_Integer llGetNumberOfPrims()
7775 { 8691 {
7776 m_host.AddScriptLPS(1); 8692 m_host.AddScriptLPS(1);
7777 int avatarCount = 0; 8693 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7778 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8694
7779 {
7780 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7781 avatarCount++;
7782 });
7783
7784 return m_host.ParentGroup.PrimCount + avatarCount; 8695 return m_host.ParentGroup.PrimCount + avatarCount;
7785 } 8696 }
7786 8697
@@ -7796,55 +8707,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7796 m_host.AddScriptLPS(1); 8707 m_host.AddScriptLPS(1);
7797 UUID objID = UUID.Zero; 8708 UUID objID = UUID.Zero;
7798 LSL_List result = new LSL_List(); 8709 LSL_List result = new LSL_List();
8710
8711 // If the ID is not valid, return null result
7799 if (!UUID.TryParse(obj, out objID)) 8712 if (!UUID.TryParse(obj, out objID))
7800 { 8713 {
7801 result.Add(new LSL_Vector()); 8714 result.Add(new LSL_Vector());
7802 result.Add(new LSL_Vector()); 8715 result.Add(new LSL_Vector());
7803 return result; 8716 return result;
7804 } 8717 }
8718
8719 // Check if this is an attached prim. If so, replace
8720 // the UUID with the avatar UUID and report it's bounding box
8721 SceneObjectPart part = World.GetSceneObjectPart(objID);
8722 if (part != null && part.ParentGroup.IsAttachment)
8723 objID = part.ParentGroup.AttachedAvatar;
8724
8725 // Find out if this is an avatar ID. If so, return it's box
7805 ScenePresence presence = World.GetScenePresence(objID); 8726 ScenePresence presence = World.GetScenePresence(objID);
7806 if (presence != null) 8727 if (presence != null)
7807 { 8728 {
7808 if (presence.ParentID == 0) // not sat on an object 8729 // As per LSL Wiki, there is no difference between sitting
8730 // and standing avatar since server 1.36
8731 LSL_Vector lower;
8732 LSL_Vector upper;
8733 if (presence.Animator.Animations.DefaultAnimation.AnimID
8734 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7809 { 8735 {
7810 LSL_Vector lower; 8736 // This is for ground sitting avatars
7811 LSL_Vector upper; 8737 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7812 if (presence.Animator.Animations.DefaultAnimation.AnimID 8738 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7813 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8739 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7814 {
7815 // This is for ground sitting avatars
7816 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7817 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7818 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7819 }
7820 else
7821 {
7822 // This is for standing/flying avatars
7823 float height = presence.Appearance.AvatarHeight / 2.0f;
7824 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7825 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7826 }
7827 result.Add(lower);
7828 result.Add(upper);
7829 return result;
7830 } 8740 }
7831 else 8741 else
7832 { 8742 {
7833 // sitting on an object so we need the bounding box of that 8743 // This is for standing/flying avatars
7834 // which should include the avatar so set the UUID to the 8744 float height = presence.Appearance.AvatarHeight / 2.0f;
7835 // UUID of the object the avatar is sat on and allow it to fall through 8745 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7836 // to processing an object 8746 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7837 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7838 objID = p.UUID;
7839 } 8747 }
8748
8749 // Adjust to the documented error offsets (see LSL Wiki)
8750 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8751 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8752
8753 if (lower.x > upper.x)
8754 lower.x = upper.x;
8755 if (lower.y > upper.y)
8756 lower.y = upper.y;
8757 if (lower.z > upper.z)
8758 lower.z = upper.z;
8759
8760 result.Add(lower);
8761 result.Add(upper);
8762 return result;
7840 } 8763 }
7841 SceneObjectPart part = World.GetSceneObjectPart(objID); 8764
8765 part = World.GetSceneObjectPart(objID);
7842 // Currently only works for single prims without a sitting avatar 8766 // Currently only works for single prims without a sitting avatar
7843 if (part != null) 8767 if (part != null)
7844 { 8768 {
7845 Vector3 halfSize = part.Scale / 2.0f; 8769 float minX;
7846 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8770 float maxX;
7847 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8771 float minY;
8772 float maxY;
8773 float minZ;
8774 float maxZ;
8775
8776 // This BBox is in sim coordinates, with the offset being
8777 // a contained point.
8778 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8779 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8780
8781 minX -= offsets[0].X;
8782 maxX -= offsets[0].X;
8783 minY -= offsets[0].Y;
8784 maxY -= offsets[0].Y;
8785 minZ -= offsets[0].Z;
8786 maxZ -= offsets[0].Z;
8787
8788 LSL_Vector lower;
8789 LSL_Vector upper;
8790
8791 // Adjust to the documented error offsets (see LSL Wiki)
8792 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8793 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8794
8795 if (lower.x > upper.x)
8796 lower.x = upper.x;
8797 if (lower.y > upper.y)
8798 lower.y = upper.y;
8799 if (lower.z > upper.z)
8800 lower.z = upper.z;
8801
7848 result.Add(lower); 8802 result.Add(lower);
7849 result.Add(upper); 8803 result.Add(upper);
7850 return result; 8804 return result;
@@ -7858,7 +8812,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7858 8812
7859 public LSL_Vector llGetGeometricCenter() 8813 public LSL_Vector llGetGeometricCenter()
7860 { 8814 {
7861 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8815 Vector3 tmp = m_host.GetGeometricCenter();
8816 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7862 } 8817 }
7863 8818
7864 public LSL_List llGetPrimitiveParams(LSL_List rules) 8819 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7871,16 +8826,291 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7871 { 8826 {
7872 m_host.AddScriptLPS(1); 8827 m_host.AddScriptLPS(1);
7873 8828
8829 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8830 // keep other options as before
8831
7874 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8832 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8833 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7875 8834
7876 LSL_List res = new LSL_List(); 8835 LSL_List res = new LSL_List();
7877 8836
7878 foreach (var part in parts) 8837 if (parts.Count > 0)
7879 { 8838 {
7880 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8839 foreach (var part in parts)
7881 res += partRes; 8840 {
8841 LSL_List partRes = GetLinkPrimitiveParams(part, rules);
8842 res += partRes;
8843 }
8844 }
8845 if (avatars.Count > 0)
8846 {
8847 foreach (ScenePresence avatar in avatars)
8848 {
8849 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules);
8850 res += avaRes;
8851 }
7882 } 8852 }
8853 return res;
8854 }
8855
8856 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8857 {
8858 // avatars case
8859 // replies as SL wiki
8860
8861 LSL_List res = new LSL_List();
8862// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8863 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8864
8865 int idx = 0;
8866 while (idx < rules.Length)
8867 {
8868 int code = (int)rules.GetLSLIntegerItem(idx++);
8869 int remain = rules.Length - idx;
8870
8871 switch (code)
8872 {
8873 case (int)ScriptBaseClass.PRIM_MATERIAL:
8874 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
8875 break;
7883 8876
8877 case (int)ScriptBaseClass.PRIM_PHYSICS:
8878 res.Add(new LSL_Integer(0));
8879 break;
8880
8881 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8882 res.Add(new LSL_Integer(0));
8883 break;
8884
8885 case (int)ScriptBaseClass.PRIM_PHANTOM:
8886 res.Add(new LSL_Integer(0));
8887 break;
8888
8889 case (int)ScriptBaseClass.PRIM_POSITION:
8890
8891 Vector3 pos = avatar.OffsetPosition;
8892
8893 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8894 pos -= sitOffset;
8895
8896 if( sitPart != null)
8897 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8898
8899 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8900 break;
8901
8902 case (int)ScriptBaseClass.PRIM_SIZE:
8903 // as in llGetAgentSize above
8904 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8905 break;
8906
8907 case (int)ScriptBaseClass.PRIM_ROTATION:
8908 Quaternion rot = avatar.Rotation;
8909 if (sitPart != null)
8910 {
8911 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8912 }
8913
8914 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8915 break;
8916
8917 case (int)ScriptBaseClass.PRIM_TYPE:
8918 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8919 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8920 res.Add(new LSL_Vector(0f,1.0f,0f));
8921 res.Add(new LSL_Float(0.0f));
8922 res.Add(new LSL_Vector(0, 0, 0));
8923 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8924 res.Add(new LSL_Vector(0, 0, 0));
8925 break;
8926
8927 case (int)ScriptBaseClass.PRIM_TEXTURE:
8928 if (remain < 1)
8929 return res;
8930
8931 int face = (int)rules.GetLSLIntegerItem(idx++);
8932 if (face == ScriptBaseClass.ALL_SIDES)
8933 {
8934 for (face = 0; face < 21; face++)
8935 {
8936 res.Add(new LSL_String(""));
8937 res.Add(new LSL_Vector(0,0,0));
8938 res.Add(new LSL_Vector(0,0,0));
8939 res.Add(new LSL_Float(0.0));
8940 }
8941 }
8942 else
8943 {
8944 if (face >= 0 && face < 21)
8945 {
8946 res.Add(new LSL_String(""));
8947 res.Add(new LSL_Vector(0,0,0));
8948 res.Add(new LSL_Vector(0,0,0));
8949 res.Add(new LSL_Float(0.0));
8950 }
8951 }
8952 break;
8953
8954 case (int)ScriptBaseClass.PRIM_COLOR:
8955 if (remain < 1)
8956 return res;
8957
8958 face = (int)rules.GetLSLIntegerItem(idx++);
8959
8960 if (face == ScriptBaseClass.ALL_SIDES)
8961 {
8962 for (face = 0; face < 21; face++)
8963 {
8964 res.Add(new LSL_Vector(0,0,0));
8965 res.Add(new LSL_Float(0));
8966 }
8967 }
8968 else
8969 {
8970 res.Add(new LSL_Vector(0,0,0));
8971 res.Add(new LSL_Float(0));
8972 }
8973 break;
8974
8975 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8976 if (remain < 1)
8977 return res;
8978 face = (int)rules.GetLSLIntegerItem(idx++);
8979
8980 if (face == ScriptBaseClass.ALL_SIDES)
8981 {
8982 for (face = 0; face < 21; face++)
8983 {
8984 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8985 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8986 }
8987 }
8988 else
8989 {
8990 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8991 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8992 }
8993 break;
8994
8995 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8996 if (remain < 1)
8997 return res;
8998 face = (int)rules.GetLSLIntegerItem(idx++);
8999
9000 if (face == ScriptBaseClass.ALL_SIDES)
9001 {
9002 for (face = 0; face < 21; face++)
9003 {
9004 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9005 }
9006 }
9007 else
9008 {
9009 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9010 }
9011 break;
9012
9013 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
9014 res.Add(new LSL_Integer(0));
9015 res.Add(new LSL_Integer(0));// softness
9016 res.Add(new LSL_Float(0.0f)); // gravity
9017 res.Add(new LSL_Float(0.0f)); // friction
9018 res.Add(new LSL_Float(0.0f)); // wind
9019 res.Add(new LSL_Float(0.0f)); // tension
9020 res.Add(new LSL_Vector(0f,0f,0f));
9021 break;
9022
9023 case (int)ScriptBaseClass.PRIM_TEXGEN:
9024 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9025 if (remain < 1)
9026 return res;
9027 face = (int)rules.GetLSLIntegerItem(idx++);
9028
9029 if (face == ScriptBaseClass.ALL_SIDES)
9030 {
9031 for (face = 0; face < 21; face++)
9032 {
9033 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9034 }
9035 }
9036 else
9037 {
9038 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9039 }
9040 break;
9041
9042 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
9043 res.Add(new LSL_Integer(0));
9044 res.Add(new LSL_Vector(0f,0f,0f));
9045 res.Add(new LSL_Float(0f)); // intensity
9046 res.Add(new LSL_Float(0f)); // radius
9047 res.Add(new LSL_Float(0f)); // falloff
9048 break;
9049
9050 case (int)ScriptBaseClass.PRIM_GLOW:
9051 if (remain < 1)
9052 return res;
9053 face = (int)rules.GetLSLIntegerItem(idx++);
9054
9055 if (face == ScriptBaseClass.ALL_SIDES)
9056 {
9057 for (face = 0; face < 21; face++)
9058 {
9059 res.Add(new LSL_Float(0f));
9060 }
9061 }
9062 else
9063 {
9064 res.Add(new LSL_Float(0f));
9065 }
9066 break;
9067
9068 case (int)ScriptBaseClass.PRIM_TEXT:
9069 res.Add(new LSL_String(""));
9070 res.Add(new LSL_Vector(0f,0f,0f));
9071 res.Add(new LSL_Float(1.0f));
9072 break;
9073
9074 case (int)ScriptBaseClass.PRIM_NAME:
9075 res.Add(new LSL_String(avatar.Name));
9076 break;
9077
9078 case (int)ScriptBaseClass.PRIM_DESC:
9079 res.Add(new LSL_String(""));
9080 break;
9081
9082 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9083 Quaternion lrot = avatar.Rotation;
9084
9085 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9086 {
9087 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9088 }
9089 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9090 break;
9091
9092 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9093 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9094 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9095 lpos -= lsitOffset;
9096
9097 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9098 {
9099 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9100 }
9101 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9102 break;
9103
9104 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9105 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9106 return res;
9107 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9108 LSL_List new_rules = rules.GetSublist(idx, -1);
9109
9110 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9111 return res;
9112 }
9113 }
7884 return res; 9114 return res;
7885 } 9115 }
7886 9116
@@ -7924,13 +9154,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7924 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 9154 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7925 part.AbsolutePosition.Y, 9155 part.AbsolutePosition.Y,
7926 part.AbsolutePosition.Z); 9156 part.AbsolutePosition.Z);
7927 // For some reason, the part.AbsolutePosition.* values do not change if the
7928 // linkset is rotated; they always reflect the child prim's world position
7929 // as though the linkset is unrotated. This is incompatible behavior with SL's
7930 // implementation, so will break scripts imported from there (not to mention it
7931 // makes it more difficult to determine a child prim's actual inworld position).
7932 if (part.ParentID != 0)
7933 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7934 res.Add(v); 9157 res.Add(v);
7935 break; 9158 break;
7936 9159
@@ -8101,56 +9324,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8101 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 9324 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8102 if (remain < 1) 9325 if (remain < 1)
8103 return res; 9326 return res;
8104 9327 face = (int)rules.GetLSLIntegerItem(idx++);
8105 face=(int)rules.GetLSLIntegerItem(idx++);
8106 9328
8107 tex = part.Shape.Textures; 9329 tex = part.Shape.Textures;
9330 int shiny;
8108 if (face == ScriptBaseClass.ALL_SIDES) 9331 if (face == ScriptBaseClass.ALL_SIDES)
8109 { 9332 {
8110 for (face = 0; face < GetNumberOfSides(part); face++) 9333 for (face = 0; face < GetNumberOfSides(part); face++)
8111 { 9334 {
8112 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9335 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8113 // Convert Shininess to PRIM_SHINY_* 9336 if (shinyness == Shininess.High)
8114 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9337 {
8115 // PRIM_BUMP_* 9338 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8116 res.Add(new LSL_Integer((int)texface.Bump)); 9339 }
9340 else if (shinyness == Shininess.Medium)
9341 {
9342 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9343 }
9344 else if (shinyness == Shininess.Low)
9345 {
9346 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9347 }
9348 else
9349 {
9350 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9351 }
9352 res.Add(new LSL_Integer(shiny));
9353 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8117 } 9354 }
8118 } 9355 }
8119 else 9356 else
8120 { 9357 {
8121 if (face >= 0 && face < GetNumberOfSides(part)) 9358 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9359 if (shinyness == Shininess.High)
8122 { 9360 {
8123 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9361 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8124 // Convert Shininess to PRIM_SHINY_* 9362 }
8125 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9363 else if (shinyness == Shininess.Medium)
8126 // PRIM_BUMP_* 9364 {
8127 res.Add(new LSL_Integer((int)texface.Bump)); 9365 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8128 } 9366 }
9367 else if (shinyness == Shininess.Low)
9368 {
9369 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9370 }
9371 else
9372 {
9373 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9374 }
9375 res.Add(new LSL_Integer(shiny));
9376 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8129 } 9377 }
8130 break; 9378 break;
8131 9379
8132 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 9380 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8133 if (remain < 1) 9381 if (remain < 1)
8134 return res; 9382 return res;
8135 9383 face = (int)rules.GetLSLIntegerItem(idx++);
8136 face=(int)rules.GetLSLIntegerItem(idx++);
8137 9384
8138 tex = part.Shape.Textures; 9385 tex = part.Shape.Textures;
9386 int fullbright;
8139 if (face == ScriptBaseClass.ALL_SIDES) 9387 if (face == ScriptBaseClass.ALL_SIDES)
8140 { 9388 {
8141 for (face = 0; face < GetNumberOfSides(part); face++) 9389 for (face = 0; face < GetNumberOfSides(part); face++)
8142 { 9390 {
8143 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9391 if (tex.GetFace((uint)face).Fullbright == true)
8144 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9392 {
9393 fullbright = ScriptBaseClass.TRUE;
9394 }
9395 else
9396 {
9397 fullbright = ScriptBaseClass.FALSE;
9398 }
9399 res.Add(new LSL_Integer(fullbright));
8145 } 9400 }
8146 } 9401 }
8147 else 9402 else
8148 { 9403 {
8149 if (face >= 0 && face < GetNumberOfSides(part)) 9404 if (tex.GetFace((uint)face).Fullbright == true)
8150 { 9405 {
8151 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9406 fullbright = ScriptBaseClass.TRUE;
8152 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9407 }
9408 else
9409 {
9410 fullbright = ScriptBaseClass.FALSE;
8153 } 9411 }
9412 res.Add(new LSL_Integer(fullbright));
8154 } 9413 }
8155 break; 9414 break;
8156 9415
@@ -8172,27 +9431,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8172 break; 9431 break;
8173 9432
8174 case (int)ScriptBaseClass.PRIM_TEXGEN: 9433 case (int)ScriptBaseClass.PRIM_TEXGEN:
9434 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8175 if (remain < 1) 9435 if (remain < 1)
8176 return res; 9436 return res;
8177 9437 face = (int)rules.GetLSLIntegerItem(idx++);
8178 face=(int)rules.GetLSLIntegerItem(idx++);
8179 9438
8180 tex = part.Shape.Textures; 9439 tex = part.Shape.Textures;
8181 if (face == ScriptBaseClass.ALL_SIDES) 9440 if (face == ScriptBaseClass.ALL_SIDES)
8182 { 9441 {
8183 for (face = 0; face < GetNumberOfSides(part); face++) 9442 for (face = 0; face < GetNumberOfSides(part); face++)
8184 { 9443 {
8185 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9444 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8186 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9445 {
8187 res.Add(new LSL_Integer((uint)texgen >> 1)); 9446 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9447 }
9448 else
9449 {
9450 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9451 }
8188 } 9452 }
8189 } 9453 }
8190 else 9454 else
8191 { 9455 {
8192 if (face >= 0 && face < GetNumberOfSides(part)) 9456 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8193 { 9457 {
8194 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9458 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8195 res.Add(new LSL_Integer((uint)texgen >> 1)); 9459 }
9460 else
9461 {
9462 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8196 } 9463 }
8197 } 9464 }
8198 break; 9465 break;
@@ -8215,25 +9482,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8215 case (int)ScriptBaseClass.PRIM_GLOW: 9482 case (int)ScriptBaseClass.PRIM_GLOW:
8216 if (remain < 1) 9483 if (remain < 1)
8217 return res; 9484 return res;
8218 9485 face = (int)rules.GetLSLIntegerItem(idx++);
8219 face=(int)rules.GetLSLIntegerItem(idx++);
8220 9486
8221 tex = part.Shape.Textures; 9487 tex = part.Shape.Textures;
9488 float primglow;
8222 if (face == ScriptBaseClass.ALL_SIDES) 9489 if (face == ScriptBaseClass.ALL_SIDES)
8223 { 9490 {
8224 for (face = 0; face < GetNumberOfSides(part); face++) 9491 for (face = 0; face < GetNumberOfSides(part); face++)
8225 { 9492 {
8226 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9493 primglow = tex.GetFace((uint)face).Glow;
8227 res.Add(new LSL_Float(texface.Glow)); 9494 res.Add(new LSL_Float(primglow));
8228 } 9495 }
8229 } 9496 }
8230 else 9497 else
8231 { 9498 {
8232 if (face >= 0 && face < GetNumberOfSides(part)) 9499 primglow = tex.GetFace((uint)face).Glow;
8233 { 9500 res.Add(new LSL_Float(primglow));
8234 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8235 res.Add(new LSL_Float(texface.Glow));
8236 }
8237 } 9501 }
8238 break; 9502 break;
8239 9503
@@ -8245,18 +9509,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8245 textColor.B)); 9509 textColor.B));
8246 res.Add(new LSL_Float(textColor.A)); 9510 res.Add(new LSL_Float(textColor.A));
8247 break; 9511 break;
9512
8248 case (int)ScriptBaseClass.PRIM_NAME: 9513 case (int)ScriptBaseClass.PRIM_NAME:
8249 res.Add(new LSL_String(part.Name)); 9514 res.Add(new LSL_String(part.Name));
8250 break; 9515 break;
9516
8251 case (int)ScriptBaseClass.PRIM_DESC: 9517 case (int)ScriptBaseClass.PRIM_DESC:
8252 res.Add(new LSL_String(part.Description)); 9518 res.Add(new LSL_String(part.Description));
8253 break; 9519 break;
9520
8254 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9521 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8255 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9522 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8256 break; 9523 break;
9524
8257 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9525 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8258 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9526 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8259 break; 9527 break;
9528
9529 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9530 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9531 return res;
9532 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9533 LSL_List new_rules = rules.GetSublist(idx, -1);
9534 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9535 res += tres;
9536 return res;
8260 } 9537 }
8261 } 9538 }
8262 return res; 9539 return res;
@@ -8849,8 +10126,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8849 // The function returns an ordered list 10126 // The function returns an ordered list
8850 // representing the tokens found in the supplied 10127 // representing the tokens found in the supplied
8851 // sources string. If two successive tokenizers 10128 // sources string. If two successive tokenizers
8852 // are encountered, then a NULL entry is added 10129 // are encountered, then a null-string entry is
8853 // to the list. 10130 // added to the list.
8854 // 10131 //
8855 // It is a precondition that the source and 10132 // It is a precondition that the source and
8856 // toekizer lisst are non-null. If they are null, 10133 // toekizer lisst are non-null. If they are null,
@@ -8858,7 +10135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8858 // while their lengths are being determined. 10135 // while their lengths are being determined.
8859 // 10136 //
8860 // A small amount of working memoryis required 10137 // A small amount of working memoryis required
8861 // of approximately 8*#tokenizers. 10138 // of approximately 8*#tokenizers + 8*srcstrlen.
8862 // 10139 //
8863 // There are many ways in which this function 10140 // There are many ways in which this function
8864 // can be implemented, this implementation is 10141 // can be implemented, this implementation is
@@ -8874,155 +10151,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8874 // and eliminates redundant tokenizers as soon 10151 // and eliminates redundant tokenizers as soon
8875 // as is possible. 10152 // as is possible.
8876 // 10153 //
8877 // The implementation tries to avoid any copying 10154 // The implementation tries to minimize temporary
8878 // of arrays or other objects. 10155 // garbage generation.
8879 // </remarks> 10156 // </remarks>
8880 10157
8881 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 10158 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8882 { 10159 {
8883 int beginning = 0; 10160 return ParseString2List(src, separators, spacers, true);
8884 int srclen = src.Length; 10161 }
8885 int seplen = separators.Length;
8886 object[] separray = separators.Data;
8887 int spclen = spacers.Length;
8888 object[] spcarray = spacers.Data;
8889 int mlen = seplen+spclen;
8890
8891 int[] offset = new int[mlen+1];
8892 bool[] active = new bool[mlen];
8893
8894 int best;
8895 int j;
8896
8897 // Initial capacity reduces resize cost
8898 10162
8899 LSL_List tokens = new LSL_List(); 10163 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
10164 {
10165 int srclen = src.Length;
10166 int seplen = separators.Length;
10167 object[] separray = separators.Data;
10168 int spclen = spacers.Length;
10169 object[] spcarray = spacers.Data;
10170 int dellen = 0;
10171 string[] delarray = new string[seplen+spclen];
8900 10172
8901 // All entries are initially valid 10173 int outlen = 0;
10174 string[] outarray = new string[srclen*2+1];
8902 10175
8903 for (int i = 0; i < mlen; i++) 10176 int i, j;
8904 active[i] = true; 10177 string d;
8905 10178
8906 offset[mlen] = srclen; 10179 m_host.AddScriptLPS(1);
8907 10180
8908 while (beginning < srclen) 10181 /*
10182 * Convert separator and spacer lists to C# strings.
10183 * Also filter out null strings so we don't hang.
10184 */
10185 for (i = 0; i < seplen; i ++)
8909 { 10186 {
10187 d = separray[i].ToString();
10188 if (d.Length > 0)
10189 {
10190 delarray[dellen++] = d;
10191 }
10192 }
10193 seplen = dellen;
8910 10194
8911 best = mlen; // as bad as it gets 10195 for (i = 0; i < spclen; i ++)
10196 {
10197 d = spcarray[i].ToString();
10198 if (d.Length > 0)
10199 {
10200 delarray[dellen++] = d;
10201 }
10202 }
8912 10203
8913 // Scan for separators 10204 /*
10205 * Scan through source string from beginning to end.
10206 */
10207 for (i = 0;;)
10208 {
8914 10209
8915 for (j = 0; j < seplen; j++) 10210 /*
10211 * Find earliest delimeter in src starting at i (if any).
10212 */
10213 int earliestDel = -1;
10214 int earliestSrc = srclen;
10215 string earliestStr = null;
10216 for (j = 0; j < dellen; j ++)
8916 { 10217 {
8917 if (separray[j].ToString() == String.Empty) 10218 d = delarray[j];
8918 active[j] = false; 10219 if (d != null)
8919
8920 if (active[j])
8921 { 10220 {
8922 // scan all of the markers 10221 int index = src.IndexOf(d, i);
8923 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10222 if (index < 0)
8924 { 10223 {
8925 // not present at all 10224 delarray[j] = null; // delim nowhere in src, don't check it anymore
8926 active[j] = false;
8927 } 10225 }
8928 else 10226 else if (index < earliestSrc)
8929 { 10227 {
8930 // present and correct 10228 earliestSrc = index; // where delimeter starts in source string
8931 if (offset[j] < offset[best]) 10229 earliestDel = j; // where delimeter is in delarray[]
8932 { 10230 earliestStr = d; // the delimeter string from delarray[]
8933 // closest so far 10231 if (index == i) break; // can't do any better than found at beg of string
8934 best = j;
8935 if (offset[best] == beginning)
8936 break;
8937 }
8938 } 10232 }
8939 } 10233 }
8940 } 10234 }
8941 10235
8942 // Scan for spacers 10236 /*
8943 10237 * Output source string starting at i through start of earliest delimeter.
8944 if (offset[best] != beginning) 10238 */
10239 if (keepNulls || (earliestSrc > i))
8945 { 10240 {
8946 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10241 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8947 {
8948 if (spcarray[j-seplen].ToString() == String.Empty)
8949 active[j] = false;
8950
8951 if (active[j])
8952 {
8953 // scan all of the markers
8954 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8955 {
8956 // not present at all
8957 active[j] = false;
8958 }
8959 else
8960 {
8961 // present and correct
8962 if (offset[j] < offset[best])
8963 {
8964 // closest so far
8965 best = j;
8966 }
8967 }
8968 }
8969 }
8970 } 10242 }
8971 10243
8972 // This is the normal exit from the scanning loop 10244 /*
10245 * If no delimeter found at or after i, we're done scanning.
10246 */
10247 if (earliestDel < 0) break;
8973 10248
8974 if (best == mlen) 10249 /*
10250 * If delimeter was a spacer, output the spacer.
10251 */
10252 if (earliestDel >= seplen)
8975 { 10253 {
8976 // no markers were found on this pass 10254 outarray[outlen++] = earliestStr;
8977 // so we're pretty much done
8978 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8979 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8980 break;
8981 } 10255 }
8982 10256
8983 // Otherwise we just add the newly delimited token 10257 /*
8984 // and recalculate where the search should continue. 10258 * Look at rest of src string following delimeter.
8985 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10259 */
8986 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10260 i = earliestSrc + earliestStr.Length;
8987
8988 if (best < seplen)
8989 {
8990 beginning = offset[best] + (separray[best].ToString()).Length;
8991 }
8992 else
8993 {
8994 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8995 string str = spcarray[best - seplen].ToString();
8996 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8997 tokens.Add(new LSL_String(str));
8998 }
8999 } 10261 }
9000 10262
9001 // This an awkward an not very intuitive boundary case. If the 10263 /*
9002 // last substring is a tokenizer, then there is an implied trailing 10264 * Make up an exact-sized output array suitable for an LSL_List object.
9003 // null list entry. Hopefully the single comparison will not be too 10265 */
9004 // arduous. Alternatively the 'break' could be replced with a return 10266 object[] outlist = new object[outlen];
9005 // but that's shabby programming. 10267 for (i = 0; i < outlen; i ++)
9006
9007 if ((beginning == srclen) && (keepNulls))
9008 { 10268 {
9009 if (srclen != 0) 10269 outlist[i] = new LSL_String(outarray[i]);
9010 tokens.Add(new LSL_String(""));
9011 } 10270 }
9012 10271 return new LSL_List(outlist);
9013 return tokens;
9014 }
9015
9016 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9017 {
9018 m_host.AddScriptLPS(1);
9019 return this.ParseString(src, separators, spacers, false);
9020 }
9021
9022 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9023 {
9024 m_host.AddScriptLPS(1);
9025 return this.ParseString(src, separators, spacers, true);
9026 } 10272 }
9027 10273
9028 public LSL_Integer llGetObjectPermMask(int mask) 10274 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9117,6 +10363,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9117 case 4: 10363 case 4:
9118 return (int)item.NextPermissions; 10364 return (int)item.NextPermissions;
9119 } 10365 }
10366 m_host.TaskInventory.LockItemsForRead(false);
9120 10367
9121 return -1; 10368 return -1;
9122 } 10369 }
@@ -9307,9 +10554,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9307 { 10554 {
9308 try 10555 try
9309 { 10556 {
10557 /*
9310 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10558 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9311 if (obj != null) 10559 if (obj != null)
9312 return (double)obj.GetMass(); 10560 return (double)obj.GetMass();
10561 */
10562 // return total object mass
10563 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10564 if (obj != null)
10565 return obj.GetMass();
10566
9313 // the object is null so the key is for an avatar 10567 // the object is null so the key is for an avatar
9314 ScenePresence avatar = World.GetScenePresence(key); 10568 ScenePresence avatar = World.GetScenePresence(key);
9315 if (avatar != null) 10569 if (avatar != null)
@@ -9329,7 +10583,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9329 } 10583 }
9330 10584
9331 /// <summary> 10585 /// <summary>
9332 /// illListReplaceList removes the sub-list defined by the inclusive indices 10586 /// llListReplaceList removes the sub-list defined by the inclusive indices
9333 /// start and end and inserts the src list in its place. The inclusive 10587 /// start and end and inserts the src list in its place. The inclusive
9334 /// nature of the indices means that at least one element must be deleted 10588 /// nature of the indices means that at least one element must be deleted
9335 /// if the indices are within the bounds of the existing list. I.e. 2,2 10589 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9386,16 +10640,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9386 // based upon end. Note that if end exceeds the upper 10640 // based upon end. Note that if end exceeds the upper
9387 // bound in this case, the entire destination list 10641 // bound in this case, the entire destination list
9388 // is removed. 10642 // is removed.
9389 else 10643 else if (start == 0)
9390 { 10644 {
9391 if (end + 1 < dest.Length) 10645 if (end + 1 < dest.Length)
9392 {
9393 return src + dest.GetSublist(end + 1, -1); 10646 return src + dest.GetSublist(end + 1, -1);
9394 }
9395 else 10647 else
9396 {
9397 return src; 10648 return src;
9398 } 10649 }
10650 else // Start < 0
10651 {
10652 if (end + 1 < dest.Length)
10653 return dest.GetSublist(end + 1, -1);
10654 else
10655 return new LSL_List();
9399 } 10656 }
9400 } 10657 }
9401 // Finally, if start > end, we strip away a prefix and 10658 // Finally, if start > end, we strip away a prefix and
@@ -9446,17 +10703,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9446 int width = 0; 10703 int width = 0;
9447 int height = 0; 10704 int height = 0;
9448 10705
9449 ParcelMediaCommandEnum? commandToSend = null; 10706 uint commandToSend = 0;
9450 float time = 0.0f; // default is from start 10707 float time = 0.0f; // default is from start
9451 10708
9452 ScenePresence presence = null; 10709 ScenePresence presence = null;
9453 10710
9454 for (int i = 0; i < commandList.Data.Length; i++) 10711 for (int i = 0; i < commandList.Data.Length; i++)
9455 { 10712 {
9456 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10713 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9457 switch (command) 10714 switch (command)
9458 { 10715 {
9459 case ParcelMediaCommandEnum.Agent: 10716 case (uint)ParcelMediaCommandEnum.Agent:
9460 // we send only to one agent 10717 // we send only to one agent
9461 if ((i + 1) < commandList.Length) 10718 if ((i + 1) < commandList.Length)
9462 { 10719 {
@@ -9473,25 +10730,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9473 } 10730 }
9474 break; 10731 break;
9475 10732
9476 case ParcelMediaCommandEnum.Loop: 10733 case (uint)ParcelMediaCommandEnum.Loop:
9477 loop = 1; 10734 loop = 1;
9478 commandToSend = command; 10735 commandToSend = command;
9479 update = true; //need to send the media update packet to set looping 10736 update = true; //need to send the media update packet to set looping
9480 break; 10737 break;
9481 10738
9482 case ParcelMediaCommandEnum.Play: 10739 case (uint)ParcelMediaCommandEnum.Play:
9483 loop = 0; 10740 loop = 0;
9484 commandToSend = command; 10741 commandToSend = command;
9485 update = true; //need to send the media update packet to make sure it doesn't loop 10742 update = true; //need to send the media update packet to make sure it doesn't loop
9486 break; 10743 break;
9487 10744
9488 case ParcelMediaCommandEnum.Pause: 10745 case (uint)ParcelMediaCommandEnum.Pause:
9489 case ParcelMediaCommandEnum.Stop: 10746 case (uint)ParcelMediaCommandEnum.Stop:
9490 case ParcelMediaCommandEnum.Unload: 10747 case (uint)ParcelMediaCommandEnum.Unload:
9491 commandToSend = command; 10748 commandToSend = command;
9492 break; 10749 break;
9493 10750
9494 case ParcelMediaCommandEnum.Url: 10751 case (uint)ParcelMediaCommandEnum.Url:
9495 if ((i + 1) < commandList.Length) 10752 if ((i + 1) < commandList.Length)
9496 { 10753 {
9497 if (commandList.Data[i + 1] is LSL_String) 10754 if (commandList.Data[i + 1] is LSL_String)
@@ -9504,7 +10761,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9504 } 10761 }
9505 break; 10762 break;
9506 10763
9507 case ParcelMediaCommandEnum.Texture: 10764 case (uint)ParcelMediaCommandEnum.Texture:
9508 if ((i + 1) < commandList.Length) 10765 if ((i + 1) < commandList.Length)
9509 { 10766 {
9510 if (commandList.Data[i + 1] is LSL_String) 10767 if (commandList.Data[i + 1] is LSL_String)
@@ -9517,7 +10774,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9517 } 10774 }
9518 break; 10775 break;
9519 10776
9520 case ParcelMediaCommandEnum.Time: 10777 case (uint)ParcelMediaCommandEnum.Time:
9521 if ((i + 1) < commandList.Length) 10778 if ((i + 1) < commandList.Length)
9522 { 10779 {
9523 if (commandList.Data[i + 1] is LSL_Float) 10780 if (commandList.Data[i + 1] is LSL_Float)
@@ -9529,7 +10786,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9529 } 10786 }
9530 break; 10787 break;
9531 10788
9532 case ParcelMediaCommandEnum.AutoAlign: 10789 case (uint)ParcelMediaCommandEnum.AutoAlign:
9533 if ((i + 1) < commandList.Length) 10790 if ((i + 1) < commandList.Length)
9534 { 10791 {
9535 if (commandList.Data[i + 1] is LSL_Integer) 10792 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9543,7 +10800,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9543 } 10800 }
9544 break; 10801 break;
9545 10802
9546 case ParcelMediaCommandEnum.Type: 10803 case (uint)ParcelMediaCommandEnum.Type:
9547 if ((i + 1) < commandList.Length) 10804 if ((i + 1) < commandList.Length)
9548 { 10805 {
9549 if (commandList.Data[i + 1] is LSL_String) 10806 if (commandList.Data[i + 1] is LSL_String)
@@ -9556,7 +10813,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9556 } 10813 }
9557 break; 10814 break;
9558 10815
9559 case ParcelMediaCommandEnum.Desc: 10816 case (uint)ParcelMediaCommandEnum.Desc:
9560 if ((i + 1) < commandList.Length) 10817 if ((i + 1) < commandList.Length)
9561 { 10818 {
9562 if (commandList.Data[i + 1] is LSL_String) 10819 if (commandList.Data[i + 1] is LSL_String)
@@ -9569,7 +10826,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9569 } 10826 }
9570 break; 10827 break;
9571 10828
9572 case ParcelMediaCommandEnum.Size: 10829 case (uint)ParcelMediaCommandEnum.Size:
9573 if ((i + 2) < commandList.Length) 10830 if ((i + 2) < commandList.Length)
9574 { 10831 {
9575 if (commandList.Data[i + 1] is LSL_Integer) 10832 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9639,7 +10896,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9639 } 10896 }
9640 } 10897 }
9641 10898
9642 if (commandToSend != null) 10899 if (commandToSend != 0)
9643 { 10900 {
9644 // the commandList contained a start/stop/... command, too 10901 // the commandList contained a start/stop/... command, too
9645 if (presence == null) 10902 if (presence == null)
@@ -9676,7 +10933,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9676 10933
9677 if (aList.Data[i] != null) 10934 if (aList.Data[i] != null)
9678 { 10935 {
9679 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10936 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9680 { 10937 {
9681 case ParcelMediaCommandEnum.Url: 10938 case ParcelMediaCommandEnum.Url:
9682 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10939 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9733,15 +10990,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9733 10990
9734 if (quick_pay_buttons.Data.Length < 4) 10991 if (quick_pay_buttons.Data.Length < 4)
9735 { 10992 {
9736 LSLError("List must have at least 4 elements"); 10993 int x;
9737 return; 10994 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10995 {
10996 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10997 }
9738 } 10998 }
9739 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10999 int[] nPrice = new int[5];
9740 11000 nPrice[0] = price;
9741 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 11001 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9742 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 11002 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9743 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 11003 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9744 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 11004 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
11005 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9745 m_host.ParentGroup.HasGroupChanged = true; 11006 m_host.ParentGroup.HasGroupChanged = true;
9746 } 11007 }
9747 11008
@@ -9758,7 +11019,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9758 return new LSL_Vector(); 11019 return new LSL_Vector();
9759 } 11020 }
9760 11021
9761 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11022// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11023 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9762 if (presence != null) 11024 if (presence != null)
9763 { 11025 {
9764 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 11026 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9780,7 +11042,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9780 return new LSL_Rotation(); 11042 return new LSL_Rotation();
9781 } 11043 }
9782 11044
9783 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11045// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11046 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9784 if (presence != null) 11047 if (presence != null)
9785 { 11048 {
9786 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 11049 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9840,8 +11103,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9840 { 11103 {
9841 m_host.AddScriptLPS(1); 11104 m_host.AddScriptLPS(1);
9842 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 11105 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9843 if (detectedParams == null) return; // only works on the first detected avatar 11106 if (detectedParams == null)
9844 11107 {
11108 if (m_host.ParentGroup.IsAttachment == true)
11109 {
11110 detectedParams = new DetectParams();
11111 detectedParams.Key = m_host.OwnerID;
11112 }
11113 else
11114 {
11115 return;
11116 }
11117 }
11118
9845 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 11119 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9846 if (avatar != null) 11120 if (avatar != null)
9847 { 11121 {
@@ -9849,6 +11123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9849 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 11123 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9850 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 11124 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9851 } 11125 }
11126
9852 ScriptSleep(1000); 11127 ScriptSleep(1000);
9853 } 11128 }
9854 11129
@@ -9972,12 +11247,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9972 11247
9973 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11248 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9974 object[] data = rules.Data; 11249 object[] data = rules.Data;
9975 for (int i = 0; i < data.Length; ++i) { 11250 for (int i = 0; i < data.Length; ++i)
11251 {
9976 int type = Convert.ToInt32(data[i++].ToString()); 11252 int type = Convert.ToInt32(data[i++].ToString());
9977 if (i >= data.Length) break; // odd number of entries => ignore the last 11253 if (i >= data.Length) break; // odd number of entries => ignore the last
9978 11254
9979 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11255 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9980 switch (type) { 11256 switch (type)
11257 {
9981 case ScriptBaseClass.CAMERA_FOCUS: 11258 case ScriptBaseClass.CAMERA_FOCUS:
9982 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11259 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9983 case ScriptBaseClass.CAMERA_POSITION: 11260 case ScriptBaseClass.CAMERA_POSITION:
@@ -10083,19 +11360,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10083 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11360 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10084 { 11361 {
10085 m_host.AddScriptLPS(1); 11362 m_host.AddScriptLPS(1);
10086 string ret = String.Empty; 11363
10087 string src1 = llBase64ToString(str1); 11364 if (str1 == String.Empty)
10088 string src2 = llBase64ToString(str2); 11365 return String.Empty;
10089 int c = 0; 11366 if (str2 == String.Empty)
10090 for (int i = 0; i < src1.Length; i++) 11367 return str1;
11368
11369 int len = str2.Length;
11370 if ((len % 4) != 0) // LL is EVIL!!!!
10091 { 11371 {
10092 ret += (char) (src1[i] ^ src2[c]); 11372 while (str2.EndsWith("="))
11373 str2 = str2.Substring(0, str2.Length - 1);
11374
11375 len = str2.Length;
11376 int mod = len % 4;
11377
11378 if (mod == 1)
11379 str2 = str2.Substring(0, str2.Length - 1);
11380 else if (mod == 2)
11381 str2 += "==";
11382 else if (mod == 3)
11383 str2 += "=";
11384 }
10093 11385
10094 c++; 11386 byte[] data1;
10095 if (c >= src2.Length) 11387 byte[] data2;
10096 c = 0; 11388 try
11389 {
11390 data1 = Convert.FromBase64String(str1);
11391 data2 = Convert.FromBase64String(str2);
10097 } 11392 }
10098 return llStringToBase64(ret); 11393 catch (Exception)
11394 {
11395 return new LSL_String(String.Empty);
11396 }
11397
11398 byte[] d2 = new Byte[data1.Length];
11399 int pos = 0;
11400
11401 if (data1.Length <= data2.Length)
11402 {
11403 Array.Copy(data2, 0, d2, 0, data1.Length);
11404 }
11405 else
11406 {
11407 while (pos < data1.Length)
11408 {
11409 len = data1.Length - pos;
11410 if (len > data2.Length)
11411 len = data2.Length;
11412
11413 Array.Copy(data2, 0, d2, pos, len);
11414 pos += len;
11415 }
11416 }
11417
11418 for (pos = 0 ; pos < data1.Length ; pos++ )
11419 data1[pos] ^= d2[pos];
11420
11421 return Convert.ToBase64String(data1);
10099 } 11422 }
10100 11423
10101 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11424 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10152,12 +11475,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10152 Regex r = new Regex(authregex); 11475 Regex r = new Regex(authregex);
10153 int[] gnums = r.GetGroupNumbers(); 11476 int[] gnums = r.GetGroupNumbers();
10154 Match m = r.Match(url); 11477 Match m = r.Match(url);
10155 if (m.Success) { 11478 if (m.Success)
10156 for (int i = 1; i < gnums.Length; i++) { 11479 {
11480 for (int i = 1; i < gnums.Length; i++)
11481 {
10157 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11482 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10158 //CaptureCollection cc = g.Captures; 11483 //CaptureCollection cc = g.Captures;
10159 } 11484 }
10160 if (m.Groups.Count == 5) { 11485 if (m.Groups.Count == 5)
11486 {
10161 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11487 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10162 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11488 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10163 } 11489 }
@@ -10360,6 +11686,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10360 11686
10361 LSL_List ret = new LSL_List(); 11687 LSL_List ret = new LSL_List();
10362 UUID key = new UUID(); 11688 UUID key = new UUID();
11689
11690
10363 if (UUID.TryParse(id, out key)) 11691 if (UUID.TryParse(id, out key))
10364 { 11692 {
10365 ScenePresence av = World.GetScenePresence(key); 11693 ScenePresence av = World.GetScenePresence(key);
@@ -10377,13 +11705,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10377 ret.Add(new LSL_String("")); 11705 ret.Add(new LSL_String(""));
10378 break; 11706 break;
10379 case ScriptBaseClass.OBJECT_POS: 11707 case ScriptBaseClass.OBJECT_POS:
10380 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11708 Vector3 avpos;
11709
11710 if (av.ParentID != 0 && av.ParentPart != null)
11711 {
11712 avpos = av.OffsetPosition;
11713
11714 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11715 avpos -= sitOffset;
11716
11717 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11718 }
11719 else
11720 avpos = av.AbsolutePosition;
11721
11722 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10381 break; 11723 break;
10382 case ScriptBaseClass.OBJECT_ROT: 11724 case ScriptBaseClass.OBJECT_ROT:
10383 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11725 Quaternion avrot = av.Rotation;
11726 if (av.ParentID != 0 && av.ParentPart != null)
11727 {
11728 avrot = av.ParentPart.GetWorldRotation() * avrot;
11729 }
11730 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10384 break; 11731 break;
10385 case ScriptBaseClass.OBJECT_VELOCITY: 11732 case ScriptBaseClass.OBJECT_VELOCITY:
10386 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11733 Vector3 avvel = av.Velocity;
11734 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10387 break; 11735 break;
10388 case ScriptBaseClass.OBJECT_OWNER: 11736 case ScriptBaseClass.OBJECT_OWNER:
10389 ret.Add(new LSL_String(id)); 11737 ret.Add(new LSL_String(id));
@@ -10439,17 +11787,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10439 case ScriptBaseClass.OBJECT_NAME: 11787 case ScriptBaseClass.OBJECT_NAME:
10440 ret.Add(new LSL_String(obj.Name)); 11788 ret.Add(new LSL_String(obj.Name));
10441 break; 11789 break;
10442 case ScriptBaseClass.OBJECT_DESC: 11790 case ScriptBaseClass.OBJECT_DESC:
10443 ret.Add(new LSL_String(obj.Description)); 11791 ret.Add(new LSL_String(obj.Description));
10444 break; 11792 break;
10445 case ScriptBaseClass.OBJECT_POS: 11793 case ScriptBaseClass.OBJECT_POS:
10446 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11794 Vector3 opos = obj.AbsolutePosition;
11795 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10447 break; 11796 break;
10448 case ScriptBaseClass.OBJECT_ROT: 11797 case ScriptBaseClass.OBJECT_ROT:
10449 ret.Add(new LSL_Rotation(obj.RotationOffset.X, obj.RotationOffset.Y, obj.RotationOffset.Z, obj.RotationOffset.W)); 11798// Quaternion orot = obj.RotationOffset;
11799// ret.Add(new LSL_Rotation(orot.X, orot.Y, orot.Z, orot.W));
11800
11801 LSL_Rotation objrot = GetPartRot(obj);
11802 ret.Add(objrot);
10450 break; 11803 break;
10451 case ScriptBaseClass.OBJECT_VELOCITY: 11804 case ScriptBaseClass.OBJECT_VELOCITY:
10452 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); 11805 Vector3 ovel = obj.Velocity;
11806 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
10453 break; 11807 break;
10454 case ScriptBaseClass.OBJECT_OWNER: 11808 case ScriptBaseClass.OBJECT_OWNER:
10455 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11809 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -10483,9 +11837,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10483 // The value returned in SL for normal prims is prim count 11837 // The value returned in SL for normal prims is prim count
10484 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11838 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10485 break; 11839 break;
10486 // The following 3 costs I have intentionaly coded to return zero. They are part of 11840
10487 // "Land Impact" calculations. These calculations are probably not applicable 11841 // costs below may need to be diferent for root parts, need to check
10488 // to OpenSim and are not yet complete in SL
10489 case ScriptBaseClass.OBJECT_SERVER_COST: 11842 case ScriptBaseClass.OBJECT_SERVER_COST:
10490 // The linden calculation is here 11843 // The linden calculation is here
10491 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11844 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10493,16 +11846,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10493 ret.Add(new LSL_Float(0)); 11846 ret.Add(new LSL_Float(0));
10494 break; 11847 break;
10495 case ScriptBaseClass.OBJECT_STREAMING_COST: 11848 case ScriptBaseClass.OBJECT_STREAMING_COST:
10496 // The linden calculation is here 11849 // The value returned in SL for normal prims is prim count * 0.06
10497 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11850 ret.Add(new LSL_Float(obj.StreamingCost));
10498 // The value returned in SL for normal prims looks like the prim count * 0.06
10499 ret.Add(new LSL_Float(0));
10500 break; 11851 break;
10501 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11852 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10502 // The linden calculation is here 11853 // The value returned in SL for normal prims is prim count
10503 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11854 ret.Add(new LSL_Float(obj.PhysicsCost));
10504 // The value returned in SL for normal prims looks like the prim count
10505 ret.Add(new LSL_Float(0));
10506 break; 11855 break;
10507 default: 11856 default:
10508 // Invalid or unhandled constant. 11857 // Invalid or unhandled constant.
@@ -10691,15 +12040,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10691 return GetLinkPrimitiveParams(obj, rules); 12040 return GetLinkPrimitiveParams(obj, rules);
10692 } 12041 }
10693 12042
10694 public void print(string str) 12043 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10695 { 12044 {
10696 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 12045 List<SceneObjectPart> parts = GetLinkParts(link);
10697 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 12046 if (parts.Count < 1)
10698 if (ossl != null) 12047 return 0;
10699 { 12048
10700 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12049 return GetNumberOfSides(parts[0]);
10701 m_log.Info("LSL print():" + str);
10702 }
10703 } 12050 }
10704 12051
10705 private string Name2Username(string name) 12052 private string Name2Username(string name)
@@ -10744,7 +12091,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10744 12091
10745 return rq.ToString(); 12092 return rq.ToString();
10746 } 12093 }
10747 12094/*
12095 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12096 {
12097 m_SayShoutCount = 0;
12098 }
12099*/
10748 private struct Tri 12100 private struct Tri
10749 { 12101 {
10750 public Vector3 p1; 12102 public Vector3 p1;
@@ -10884,9 +12236,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10884 12236
10885 ContactResult result = new ContactResult (); 12237 ContactResult result = new ContactResult ();
10886 result.ConsumerID = group.LocalId; 12238 result.ConsumerID = group.LocalId;
10887 result.Depth = intersection.distance; 12239// result.Depth = intersection.distance;
10888 result.Normal = intersection.normal; 12240 result.Normal = intersection.normal;
10889 result.Pos = intersection.ipoint; 12241 result.Pos = intersection.ipoint;
12242 result.Depth = Vector3.Mag(rayStart - result.Pos);
10890 12243
10891 contacts.Add(result); 12244 contacts.Add(result);
10892 }); 12245 });
@@ -11019,6 +12372,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11019 12372
11020 return contacts[0]; 12373 return contacts[0];
11021 } 12374 }
12375/*
12376 // not done:
12377 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12378 {
12379 ContactResult[] contacts = null;
12380 World.ForEachSOG(delegate(SceneObjectGroup group)
12381 {
12382 if (m_host.ParentGroup == group)
12383 return;
12384
12385 if (group.IsAttachment)
12386 return;
12387
12388 if(group.RootPart.PhysActor != null)
12389 return;
12390
12391 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12392 });
12393 return contacts;
12394 }
12395*/
11022 12396
11023 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12397 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11024 { 12398 {
@@ -11060,32 +12434,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11060 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12434 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11061 12435
11062 12436
11063 if (checkTerrain) 12437 if (World.SuportsRayCastFiltered())
11064 { 12438 {
11065 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12439 if (dist == 0)
11066 if (groundContact != null) 12440 return list;
11067 results.Add((ContactResult)groundContact);
11068 }
11069 12441
11070 if (checkAgents) 12442 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11071 { 12443 if (checkTerrain)
11072 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12444 rayfilter |= RayFilterFlags.land;
11073 foreach (ContactResult r in agentHits) 12445// if (checkAgents)
11074 results.Add(r); 12446// rayfilter |= RayFilterFlags.agent;
11075 } 12447 if (checkPhysical)
12448 rayfilter |= RayFilterFlags.physical;
12449 if (checkNonPhysical)
12450 rayfilter |= RayFilterFlags.nonphysical;
12451 if (detectPhantom)
12452 rayfilter |= RayFilterFlags.LSLPhanton;
12453
12454 Vector3 direction = dir * ( 1/dist);
12455
12456 if(rayfilter == 0)
12457 {
12458 list.Add(new LSL_Integer(0));
12459 return list;
12460 }
12461
12462 // get some more contacts to sort ???
12463 int physcount = 4 * count;
12464 if (physcount > 20)
12465 physcount = 20;
12466
12467 object physresults;
12468 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
11076 12469
11077 if (checkPhysical || checkNonPhysical || detectPhantom) 12470 if (physresults == null)
12471 {
12472 list.Add(new LSL_Integer(-3)); // timeout error
12473 return list;
12474 }
12475
12476 results = (List<ContactResult>)physresults;
12477
12478 // for now physics doesn't detect sitted avatars so do it outside physics
12479 if (checkAgents)
12480 {
12481 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12482 foreach (ContactResult r in agentHits)
12483 results.Add(r);
12484 }
12485
12486 // TODO: Replace this with a better solution. ObjectIntersection can only
12487 // detect nonphysical phantoms. They are detected by virtue of being
12488 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12489 // physicsl phantoms as done by the physics scene
12490 // We don't want anything else but phantoms here.
12491 if (detectPhantom)
12492 {
12493 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12494 foreach (ContactResult r in objectHits)
12495 results.Add(r);
12496 }
12497 }
12498 else
11078 { 12499 {
11079 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12500 if (checkTerrain)
11080 foreach (ContactResult r in objectHits) 12501 {
11081 results.Add(r); 12502 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12503 if (groundContact != null)
12504 results.Add((ContactResult)groundContact);
12505 }
12506
12507 if (checkAgents)
12508 {
12509 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12510 foreach (ContactResult r in agentHits)
12511 results.Add(r);
12512 }
12513
12514 if (checkPhysical || checkNonPhysical || detectPhantom)
12515 {
12516 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12517 foreach (ContactResult r in objectHits)
12518 results.Add(r);
12519 }
11082 } 12520 }
11083 12521
11084 results.Sort(delegate(ContactResult a, ContactResult b) 12522 results.Sort(delegate(ContactResult a, ContactResult b)
11085 { 12523 {
11086 return a.Depth.CompareTo(b.Depth); 12524 return a.Depth.CompareTo(b.Depth);
11087 }); 12525 });
11088 12526
11089 int values = 0; 12527 int values = 0;
11090 SceneObjectGroup thisgrp = m_host.ParentGroup; 12528 SceneObjectGroup thisgrp = m_host.ParentGroup;
11091 12529
@@ -11178,7 +12616,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11178 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12616 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11179 if (!isAccount) return 0; 12617 if (!isAccount) return 0;
11180 if (estate.HasAccess(id)) return 1; 12618 if (estate.HasAccess(id)) return 1;
11181 if (estate.IsBanned(id)) 12619 if (estate.IsBanned(id, World.GetUserFlags(id)))
11182 estate.RemoveBan(id); 12620 estate.RemoveBan(id);
11183 estate.AddEstateUser(id); 12621 estate.AddEstateUser(id);
11184 break; 12622 break;
@@ -11197,14 +12635,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11197 break; 12635 break;
11198 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12636 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11199 if (!isAccount) return 0; 12637 if (!isAccount) return 0;
11200 if (estate.IsBanned(id)) return 1; 12638 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11201 EstateBan ban = new EstateBan(); 12639 EstateBan ban = new EstateBan();
11202 ban.EstateID = estate.EstateID; 12640 ban.EstateID = estate.EstateID;
11203 ban.BannedUserID = id; 12641 ban.BannedUserID = id;
11204 estate.AddBan(ban); 12642 estate.AddBan(ban);
11205 break; 12643 break;
11206 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12644 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11207 if (!isAccount || !estate.IsBanned(id)) return 0; 12645 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11208 estate.RemoveBan(id); 12646 estate.RemoveBan(id);
11209 break; 12647 break;
11210 default: return 0; 12648 default: return 0;
@@ -11233,7 +12671,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11233 return 16384; 12671 return 16384;
11234 } 12672 }
11235 12673
11236 public LSL_Integer llGetUsedMemory() 12674 public virtual LSL_Integer llGetUsedMemory()
11237 { 12675 {
11238 m_host.AddScriptLPS(1); 12676 m_host.AddScriptLPS(1);
11239 // The value returned for LSO scripts in SL 12677 // The value returned for LSO scripts in SL
@@ -11261,7 +12699,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11261 public void llSetSoundQueueing(int queue) 12699 public void llSetSoundQueueing(int queue)
11262 { 12700 {
11263 m_host.AddScriptLPS(1); 12701 m_host.AddScriptLPS(1);
11264 NotImplemented("llSetSoundQueueing");
11265 } 12702 }
11266 12703
11267 public void llCollisionSprite(string impact_sprite) 12704 public void llCollisionSprite(string impact_sprite)
@@ -11273,10 +12710,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11273 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12710 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11274 { 12711 {
11275 m_host.AddScriptLPS(1); 12712 m_host.AddScriptLPS(1);
11276 NotImplemented("llGodLikeRezObject"); 12713
12714 if (!World.Permissions.IsGod(m_host.OwnerID))
12715 NotImplemented("llGodLikeRezObject");
12716
12717 AssetBase rezAsset = World.AssetService.Get(inventory);
12718 if (rezAsset == null)
12719 {
12720 llSay(0, "Asset not found");
12721 return;
12722 }
12723
12724 SceneObjectGroup group = null;
12725
12726 try
12727 {
12728 string xmlData = Utils.BytesToString(rezAsset.Data);
12729 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12730 }
12731 catch
12732 {
12733 llSay(0, "Asset not found");
12734 return;
12735 }
12736
12737 if (group == null)
12738 {
12739 llSay(0, "Asset not found");
12740 return;
12741 }
12742
12743 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12744 group.RootPart.AttachOffset = group.AbsolutePosition;
12745
12746 group.ResetIDs();
12747
12748 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12749 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12750 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12751 group.ScheduleGroupForFullUpdate();
12752
12753 // objects rezzed with this method are die_at_edge by default.
12754 group.RootPart.SetDieAtEdge(true);
12755
12756 group.ResumeScripts();
12757
12758 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12759 "object_rez", new Object[] {
12760 new LSL_String(
12761 group.RootPart.UUID.ToString()) },
12762 new DetectParams[0]));
12763 }
12764
12765 public LSL_String llTransferLindenDollars(string destination, int amount)
12766 {
12767 UUID txn = UUID.Random();
12768
12769 Util.FireAndForget(delegate(object x)
12770 {
12771 int replycode = 0;
12772 string replydata = destination + "," + amount.ToString();
12773
12774 try
12775 {
12776 TaskInventoryItem item = m_item;
12777 if (item == null)
12778 {
12779 replydata = "SERVICE_ERROR";
12780 return;
12781 }
12782
12783 m_host.AddScriptLPS(1);
12784
12785 if (item.PermsGranter == UUID.Zero)
12786 {
12787 replydata = "MISSING_PERMISSION_DEBIT";
12788 return;
12789 }
12790
12791 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12792 {
12793 replydata = "MISSING_PERMISSION_DEBIT";
12794 return;
12795 }
12796
12797 UUID toID = new UUID();
12798
12799 if (!UUID.TryParse(destination, out toID))
12800 {
12801 replydata = "INVALID_AGENT";
12802 return;
12803 }
12804
12805 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12806
12807 if (money == null)
12808 {
12809 replydata = "TRANSFERS_DISABLED";
12810 return;
12811 }
12812
12813 bool result = money.ObjectGiveMoney(
12814 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12815
12816 if (result)
12817 {
12818 replycode = 1;
12819 return;
12820 }
12821
12822 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12823 }
12824 finally
12825 {
12826 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12827 "transaction_result", new Object[] {
12828 new LSL_String(txn.ToString()),
12829 new LSL_Integer(replycode),
12830 new LSL_String(replydata) },
12831 new DetectParams[0]));
12832 }
12833 });
12834
12835 return txn.ToString();
11277 } 12836 }
11278 12837
11279 #endregion 12838 #endregion
12839
12840 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12841 {
12842 SceneObjectGroup group = m_host.ParentGroup;
12843
12844 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12845 return;
12846 if (group.IsAttachment)
12847 return;
12848
12849 if (frames.Data.Length > 0) // We are getting a new motion
12850 {
12851 if (group.RootPart.KeyframeMotion != null)
12852 group.RootPart.KeyframeMotion.Stop();
12853 group.RootPart.KeyframeMotion = null;
12854
12855 int idx = 0;
12856
12857 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12858 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12859
12860 while (idx < options.Data.Length)
12861 {
12862 int option = (int)options.GetLSLIntegerItem(idx++);
12863 int remain = options.Data.Length - idx;
12864
12865 switch (option)
12866 {
12867 case ScriptBaseClass.KFM_MODE:
12868 if (remain < 1)
12869 break;
12870 int modeval = (int)options.GetLSLIntegerItem(idx++);
12871 switch(modeval)
12872 {
12873 case ScriptBaseClass.KFM_FORWARD:
12874 mode = KeyframeMotion.PlayMode.Forward;
12875 break;
12876 case ScriptBaseClass.KFM_REVERSE:
12877 mode = KeyframeMotion.PlayMode.Reverse;
12878 break;
12879 case ScriptBaseClass.KFM_LOOP:
12880 mode = KeyframeMotion.PlayMode.Loop;
12881 break;
12882 case ScriptBaseClass.KFM_PING_PONG:
12883 mode = KeyframeMotion.PlayMode.PingPong;
12884 break;
12885 }
12886 break;
12887 case ScriptBaseClass.KFM_DATA:
12888 if (remain < 1)
12889 break;
12890 int dataval = (int)options.GetLSLIntegerItem(idx++);
12891 data = (KeyframeMotion.DataFormat)dataval;
12892 break;
12893 }
12894 }
12895
12896 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12897
12898 idx = 0;
12899
12900 int elemLength = 2;
12901 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12902 elemLength = 3;
12903
12904 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12905 while (idx < frames.Data.Length)
12906 {
12907 int remain = frames.Data.Length - idx;
12908
12909 if (remain < elemLength)
12910 break;
12911
12912 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12913 frame.Position = null;
12914 frame.Rotation = null;
12915
12916 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12917 {
12918 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12919 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12920 }
12921 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12922 {
12923 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12924 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12925 }
12926
12927 float tempf = (float)frames.GetLSLFloatItem(idx++);
12928 frame.TimeMS = (int)(tempf * 1000.0f);
12929
12930 keyframes.Add(frame);
12931 }
12932
12933 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12934 group.RootPart.KeyframeMotion.Start();
12935 }
12936 else
12937 {
12938 if (group.RootPart.KeyframeMotion == null)
12939 return;
12940
12941 if (options.Data.Length == 0)
12942 {
12943 group.RootPart.KeyframeMotion.Stop();
12944 return;
12945 }
12946
12947 int code = (int)options.GetLSLIntegerItem(0);
12948
12949 int idx = 0;
12950
12951 while (idx < options.Data.Length)
12952 {
12953 int option = (int)options.GetLSLIntegerItem(idx++);
12954 int remain = options.Data.Length - idx;
12955
12956 switch (option)
12957 {
12958 case ScriptBaseClass.KFM_COMMAND:
12959 int cmd = (int)options.GetLSLIntegerItem(idx++);
12960 switch (cmd)
12961 {
12962 case ScriptBaseClass.KFM_CMD_PLAY:
12963 group.RootPart.KeyframeMotion.Start();
12964 break;
12965 case ScriptBaseClass.KFM_CMD_STOP:
12966 group.RootPart.KeyframeMotion.Stop();
12967 break;
12968 case ScriptBaseClass.KFM_CMD_PAUSE:
12969 group.RootPart.KeyframeMotion.Pause();
12970 break;
12971 }
12972 break;
12973 }
12974 }
12975 }
12976 }
11280 } 12977 }
11281 12978
11282 public class NotecardCache 12979 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 4137397..29d0342 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
@@ -2626,16 +2658,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2626 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2658 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2627 m_host.AddScriptLPS(1); 2659 m_host.AddScriptLPS(1);
2628 2660
2629 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2661 ManualResetEvent ev = new ManualResetEvent(false);
2630 if (module != null)
2631 {
2632 UUID npcId = new UUID(npc.m_string);
2633 2662
2634 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2663 Util.FireAndForget(delegate(object x) {
2635 return; 2664 try
2665 {
2666 INPCModule module = World.RequestModuleInterface<INPCModule>();
2667 if (module != null)
2668 {
2669 UUID npcId = new UUID(npc.m_string);
2636 2670
2637 module.DeleteNPC(npcId, World); 2671 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2638 } 2672 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2673 {
2674 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2675 return;
2676 }
2677
2678 module.DeleteNPC(npcId, World);
2679 }
2680 }
2681 finally
2682 {
2683 ev.Set();
2684 }
2685 });
2686 ev.WaitOne();
2639 } 2687 }
2640 2688
2641 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2689 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3275,4 +3323,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3275 ((LSL_Api)m_LSL_Api).DetachFromAvatar(); 3323 ((LSL_Api)m_LSL_Api).DetachFromAvatar();
3276 } 3324 }
3277 } 3325 }
3278} \ No newline at end of file 3326}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 3844753..19f3ce1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -319,7 +319,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
319 float dy; 319 float dy;
320 float dz; 320 float dz;
321 321
322 Quaternion q = SensePoint.GetWorldRotation(); 322// Quaternion q = SensePoint.RotationOffset;
323 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
323 if (SensePoint.ParentGroup.IsAttachment) 324 if (SensePoint.ParentGroup.IsAttachment)
324 { 325 {
325 // In attachments, rotate the sensor cone with the 326 // In attachments, rotate the sensor cone with the
@@ -333,7 +334,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
333 // Position of a sensor in a child prim attached to an avatar 334 // Position of a sensor in a child prim attached to an avatar
334 // will be still wrong. 335 // will be still wrong.
335 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 336 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
336 q = avatar.Rotation * q; 337 fromRegionPos = avatar.AbsolutePosition;
338 q = avatar.Rotation;
337 } 339 }
338 340
339 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 341 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -463,7 +465,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
463 // Position of a sensor in a child prim attached to an avatar 465 // Position of a sensor in a child prim attached to an avatar
464 // will be still wrong. 466 // will be still wrong.
465 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 467 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
466 q = avatar.Rotation * q; 468 if (avatar == null)
469 return sensedEntities;
470 fromRegionPos = avatar.AbsolutePosition;
471 q = avatar.Rotation;
467 } 472 }
468 473
469 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 474 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
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 b5416c8..1facc96 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 b6c21e6..a08cc42 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -94,6 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
94 public const int AGENT_CROUCHING = 1024; 94 public const int AGENT_CROUCHING = 1024;
95 public const int AGENT_BUSY = 2048; 95 public const int AGENT_BUSY = 2048;
96 public const int AGENT_ALWAYS_RUN = 4096; 96 public const int AGENT_ALWAYS_RUN = 4096;
97 public const int AGENT_MALE = 8192;
97 98
98 //Particle Systems 99 //Particle Systems
99 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 100 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -282,6 +283,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
282 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 283 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
283 public const int CHANGED_MEDIA = 2048; 284 public const int CHANGED_MEDIA = 2048;
284 public const int CHANGED_ANIMATION = 16384; 285 public const int CHANGED_ANIMATION = 16384;
286 public const int CHANGED_POSITION = 32768;
285 public const int TYPE_INVALID = 0; 287 public const int TYPE_INVALID = 0;
286 public const int TYPE_INTEGER = 1; 288 public const int TYPE_INTEGER = 1;
287 public const int TYPE_FLOAT = 2; 289 public const int TYPE_FLOAT = 2;
@@ -586,6 +588,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
586 public const int PRIM_MEDIA_PERM_OWNER = 1; 588 public const int PRIM_MEDIA_PERM_OWNER = 1;
587 public const int PRIM_MEDIA_PERM_GROUP = 2; 589 public const int PRIM_MEDIA_PERM_GROUP = 2;
588 public const int PRIM_MEDIA_PERM_ANYONE = 4; 590 public const int PRIM_MEDIA_PERM_ANYONE = 4;
591
592 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
593 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
594 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
595 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
596
597 public const int PRIM_PHYSICS_MATERIAL = 31;
598 public const int DENSITY = 1;
599 public const int FRICTION = 2;
600 public const int RESTITUTION = 4;
601 public const int GRAVITY_MULTIPLIER = 8;
589 602
590 // extra constants for llSetPrimMediaParams 603 // extra constants for llSetPrimMediaParams
591 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 604 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -658,6 +671,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
658 671
659 public static readonly LSLInteger RCERR_UNKNOWN = -1; 672 public static readonly LSLInteger RCERR_UNKNOWN = -1;
660 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 673 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
661 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 674 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
675
676 public const int KFM_MODE = 1;
677 public const int KFM_LOOP = 1;
678 public const int KFM_REVERSE = 3;
679 public const int KFM_FORWARD = 0;
680 public const int KFM_PING_PONG = 2;
681 public const int KFM_DATA = 2;
682 public const int KFM_TRANSLATION = 2;
683 public const int KFM_ROTATION = 1;
684 public const int KFM_COMMAND = 0;
685 public const int KFM_CMD_PLAY = 0;
686 public const int KFM_CMD_STOP = 1;
687 public const int KFM_CMD_PAUSE = 2;
662 } 688 }
663} 689}
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);