aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs23
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs117
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3310
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs157
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs18
-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.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs3
-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.cs22
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs55
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs45
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs172
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs363
21 files changed, 3256 insertions, 1266 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 47a9cdc..6879ebb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -305,6 +305,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
305 return null; 305 return null;
306 } 306 }
307 307
308 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
309 {
310 // Remove a specific script
311
312 // Remove dataserver events
313 m_Dataserver[engine].RemoveEvents(localID, itemID);
314
315 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
316 if (comms != null)
317 comms.DeleteListener(itemID);
318
319 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
320 if (xmlrpc != null)
321 {
322 xmlrpc.DeleteChannels(itemID);
323 xmlrpc.CancelSRDRequests(itemID);
324 }
325
326 // Remove Sensors
327 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
328
329 }
330
308 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 331 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
309 { 332 {
310 List<Object> data = new List<Object>(); 333 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..fce8ff8
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,117 @@
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.Threading;
30using System.Reflection;
31using System.Collections;
32using System.Collections.Generic;
33using System.Runtime.Remoting.Lifetime;
34using OpenMetaverse;
35using Nini.Config;
36using OpenSim;
37using OpenSim.Framework;
38using OpenSim.Region.CoreModules.World.LightShare;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.ScriptEngine.Shared;
42using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
43using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
44using OpenSim.Region.ScriptEngine.Interfaces;
45using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
46using OpenSim.Services.Interfaces;
47
48using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
49using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
50using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
51using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
52using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
53using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
54using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
55
56namespace OpenSim.Region.ScriptEngine.Shared.Api
57{
58 [Serializable]
59 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
60 {
61 internal IScriptEngine m_ScriptEngine;
62 internal SceneObjectPart m_host;
63 internal TaskInventoryItem m_item;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_item = item;
71
72 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
73 m_CMFunctionsEnabled = true;
74 }
75
76 public override Object InitializeLifetimeService()
77 {
78 ILease lease = (ILease)base.InitializeLifetimeService();
79
80 if (lease.CurrentState == LeaseState.Initial)
81 {
82 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
83 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
84 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
85 }
86 return lease;
87 }
88
89 public Scene World
90 {
91 get { return m_ScriptEngine.World; }
92 }
93
94 public string cmDetectedCountry(int number)
95 {
96 m_host.AddScriptLPS(1);
97 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
98 if (detectedParams == null)
99 return String.Empty;
100 return detectedParams.Country;
101 }
102
103 public string cmGetAgentCountry(LSL_Key key)
104 {
105 if (!World.Permissions.IsGod(m_host.OwnerID))
106 return String.Empty;
107
108 UUID uuid;
109
110 if (!UUID.TryParse(key, out uuid))
111 return String.Empty;
112
113 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
114 return account.UserCountry;
115 }
116 }
117}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index bf84b16..f677cdf 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,14 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Framework.Scenes.Scripting; 51using OpenSim.Region.Framework.Scenes.Scripting;
49using OpenSim.Region.Physics.Manager; 52using OpenSim.Region.Physics.Manager;
@@ -67,6 +70,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
67using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 70using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
68using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 71using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
69using System.Reflection; 72using System.Reflection;
73using Timer = System.Timers.Timer;
70using PermissionMask = OpenSim.Framework.PermissionMask; 74using PermissionMask = OpenSim.Framework.PermissionMask;
71 75
72namespace OpenSim.Region.ScriptEngine.Shared.Api 76namespace OpenSim.Region.ScriptEngine.Shared.Api
@@ -114,17 +118,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
114 protected int m_notecardLineReadCharsMax = 255; 118 protected int m_notecardLineReadCharsMax = 255;
115 protected int m_scriptConsoleChannel = 0; 119 protected int m_scriptConsoleChannel = 0;
116 protected bool m_scriptConsoleChannelEnabled = false; 120 protected bool m_scriptConsoleChannelEnabled = false;
121 protected bool m_debuggerSafe = false;
117 protected IUrlModule m_UrlModule = null; 122 protected IUrlModule m_UrlModule = null;
118 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 123 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
119 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 124 new Dictionary<UUID, UserInfoCacheEntry>();
125 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
120 protected ISoundModule m_SoundModule = null; 126 protected ISoundModule m_SoundModule = null;
121 127
128// protected Timer m_ShoutSayTimer;
129 protected int m_SayShoutCount = 0;
130 DateTime m_lastSayShoutCheck;
131
132 private Dictionary<string, string> MovementAnimationsForLSL =
133 new Dictionary<string, string> {
134 {"FLY", "Flying"},
135 {"FLYSLOW", "FlyingSlow"},
136 {"HOVER_UP", "Hovering Up"},
137 {"HOVER_DOWN", "Hovering Down"},
138 {"HOVER", "Hovering"},
139 {"LAND", "Landing"},
140 {"FALLDOWN", "Falling Down"},
141 {"PREJUMP", "PreJumping"},
142 {"JUMP", "Jumping"},
143 {"STANDUP", "Standing Up"},
144 {"SOFT_LAND", "Soft Landing"},
145 {"STAND", "Standing"},
146 {"CROUCHWALK", "CrouchWalking"},
147 {"RUN", "Running"},
148 {"WALK", "Walking"},
149 {"CROUCH", "Crouching"},
150 {"TURNLEFT", "Turning Left"},
151 {"TURNRIGHT", "Turning Right"}
152 };
153
122 public void Initialize( 154 public void Initialize(
123 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) 155 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
124 { 156 {
157 m_lastSayShoutCheck = DateTime.UtcNow;
158
125 m_ScriptEngine = scriptEngine; 159 m_ScriptEngine = scriptEngine;
126 m_host = host; 160 m_host = host;
127 m_item = item; 161 m_item = item;
162 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
128 m_coopSleepHandle = coopSleepHandle; 163 m_coopSleepHandle = coopSleepHandle;
129 164
130 LoadConfig(); 165 LoadConfig();
@@ -213,6 +248,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
213 get { return m_ScriptEngine.World; } 248 get { return m_ScriptEngine.World; }
214 } 249 }
215 250
251 [DebuggerNonUserCode]
216 public void state(string newState) 252 public void state(string newState)
217 { 253 {
218 m_ScriptEngine.SetState(m_item.ItemID, newState); 254 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -222,6 +258,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
222 /// Reset the named script. The script must be present 258 /// Reset the named script. The script must be present
223 /// in the same prim. 259 /// in the same prim.
224 /// </summary> 260 /// </summary>
261 [DebuggerNonUserCode]
225 public void llResetScript() 262 public void llResetScript()
226 { 263 {
227 m_host.AddScriptLPS(1); 264 m_host.AddScriptLPS(1);
@@ -284,6 +321,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
284 } 321 }
285 } 322 }
286 323
324 public List<ScenePresence> GetLinkAvatars(int linkType)
325 {
326 List<ScenePresence> ret = new List<ScenePresence>();
327 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
328 return ret;
329
330 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
331
332 switch (linkType)
333 {
334 case ScriptBaseClass.LINK_SET:
335 return avs;
336
337 case ScriptBaseClass.LINK_ROOT:
338 return ret;
339
340 case ScriptBaseClass.LINK_ALL_OTHERS:
341 return avs;
342
343 case ScriptBaseClass.LINK_ALL_CHILDREN:
344 return avs;
345
346 case ScriptBaseClass.LINK_THIS:
347 return ret;
348
349 default:
350 if (linkType < 0)
351 return ret;
352
353 int partCount = m_host.ParentGroup.GetPartCount();
354
355 if (linkType <= partCount)
356 {
357 return ret;
358 }
359 else
360 {
361 linkType = linkType - partCount;
362 if (linkType > avs.Count)
363 {
364 return ret;
365 }
366 else
367 {
368 ret.Add(avs[linkType-1]);
369 return ret;
370 }
371 }
372 }
373 }
374
287 /// <summary> 375 /// <summary>
288 /// Get a given link entity from a linkset (linked objects and any sitting avatars). 376 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
289 /// </summary> 377 /// </summary>
@@ -366,6 +454,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
366 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 454 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
367 { 455 {
368 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 456 List<SceneObjectPart> ret = new List<SceneObjectPart>();
457 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
458 return ret;
369 ret.Add(part); 459 ret.Add(part);
370 460
371 switch (linkType) 461 switch (linkType)
@@ -519,31 +609,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
519 609
520 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 610 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
521 611
522 /// <summary> 612 // Utility function for llRot2Euler
523 /// Convert an LSL rotation to a Euler vector. 613
524 /// </summary> 614 // normalize an angle between -PI and PI (-180 to +180 degrees)
525 /// <remarks> 615 protected double NormalizeAngle(double angle)
526 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
527 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
528 /// </remarks>
529 /// <param name="r"></param>
530 /// <returns></returns>
531 public LSL_Vector llRot2Euler(LSL_Rotation r)
532 { 616 {
533 m_host.AddScriptLPS(1); 617 if (angle > -Math.PI && angle < Math.PI)
618 return angle;
534 619
535 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 620 int numPis = (int)(Math.PI / angle);
536 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 621 double remainder = angle - Math.PI * numPis;
537 if (m == 0.0) return new LSL_Vector(); 622 if (numPis % 2 == 1)
538 double x = Math.Atan2(-v.y, v.z); 623 return Math.PI - angle;
539 double sin = v.x / m; 624 return remainder;
540 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 625 }
541 double y = Math.Asin(sin); 626
542 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation 627 public LSL_Vector llRot2Euler(LSL_Rotation q1)
543 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))); 628 {
544 double z = Math.Atan2(v.y, v.x); 629 m_host.AddScriptLPS(1);
630 LSL_Vector eul = new LSL_Vector();
545 631
546 return new LSL_Vector(x, y, z); 632 double sqw = q1.s*q1.s;
633 double sqx = q1.x*q1.x;
634 double sqy = q1.z*q1.z;
635 double sqz = q1.y*q1.y;
636 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
637 double test = q1.x*q1.z + q1.y*q1.s;
638 if (test > 0.4999*unit) { // singularity at north pole
639 eul.z = 2 * Math.Atan2(q1.x,q1.s);
640 eul.y = Math.PI/2;
641 eul.x = 0;
642 return eul;
643 }
644 if (test < -0.4999*unit) { // singularity at south pole
645 eul.z = -2 * Math.Atan2(q1.x,q1.s);
646 eul.y = -Math.PI/2;
647 eul.x = 0;
648 return eul;
649 }
650 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
651 eul.y = Math.Asin(2*test/unit);
652 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
653 return eul;
547 } 654 }
548 655
549 /* From wiki: 656 /* From wiki:
@@ -596,18 +703,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
596 m_host.AddScriptLPS(1); 703 m_host.AddScriptLPS(1);
597 704
598 double x,y,z,s; 705 double x,y,z,s;
599 706 v.x *= 0.5;
600 double c1 = Math.Cos(v.x * 0.5); 707 v.y *= 0.5;
601 double c2 = Math.Cos(v.y * 0.5); 708 v.z *= 0.5;
602 double c3 = Math.Cos(v.z * 0.5); 709 double c1 = Math.Cos(v.x);
603 double s1 = Math.Sin(v.x * 0.5); 710 double c2 = Math.Cos(v.y);
604 double s2 = Math.Sin(v.y * 0.5); 711 double c1c2 = c1 * c2;
605 double s3 = Math.Sin(v.z * 0.5); 712 double s1 = Math.Sin(v.x);
606 713 double s2 = Math.Sin(v.y);
607 x = s1 * c2 * c3 + c1 * s2 * s3; 714 double s1s2 = s1 * s2;
608 y = c1 * s2 * c3 - s1 * c2 * s3; 715 double c1s2 = c1 * s2;
609 z = s1 * s2 * c3 + c1 * c2 * s3; 716 double s1c2 = s1 * c2;
610 s = c1 * c2 * c3 - s1 * s2 * s3; 717 double c3 = Math.Cos(v.z);
718 double s3 = Math.Sin(v.z);
719
720 x = s1c2 * c3 + c1s2 * s3;
721 y = c1s2 * c3 - s1c2 * s3;
722 z = s1s2 * c3 + c1c2 * s3;
723 s = c1c2 * c3 - s1s2 * s3;
611 724
612 return new LSL_Rotation(x, y, z, s); 725 return new LSL_Rotation(x, y, z, s);
613 } 726 }
@@ -745,77 +858,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
745 { 858 {
746 //A and B should both be normalized 859 //A and B should both be normalized
747 m_host.AddScriptLPS(1); 860 m_host.AddScriptLPS(1);
748 LSL_Rotation rotBetween; 861 /* This method is more accurate than the SL one, and thus causes problems
749 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 862 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
750 // continue calculation. 863
751 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 864 double dotProduct = LSL_Vector.Dot(a, b);
865 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
866 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
867 double angle = Math.Acos(dotProduct / magProduct);
868 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
869 double s = Math.Sin(angle / 2);
870
871 double x = axis.x * s;
872 double y = axis.y * s;
873 double z = axis.z * s;
874 double w = Math.Cos(angle / 2);
875
876 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
877 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
878
879 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
880 */
881
882 // This method mimics the 180 errors found in SL
883 // See www.euclideanspace.com... angleBetween
884 LSL_Vector vec_a = a;
885 LSL_Vector vec_b = b;
886
887 // Eliminate zero length
888 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
889 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
890 if (vec_a_mag < 0.00001 ||
891 vec_b_mag < 0.00001)
752 { 892 {
753 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 893 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
754 } 894 }
755 else 895
896 // Normalize
897 vec_a = llVecNorm(vec_a);
898 vec_b = llVecNorm(vec_b);
899
900 // Calculate axis and rotation angle
901 LSL_Vector axis = vec_a % vec_b;
902 LSL_Float cos_theta = vec_a * vec_b;
903
904 // Check if parallel
905 if (cos_theta > 0.99999)
756 { 906 {
757 a = LSL_Vector.Norm(a); 907 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
758 b = LSL_Vector.Norm(b); 908 }
759 double dotProduct = LSL_Vector.Dot(a, b); 909
760 // There are two degenerate cases possible. These are for vectors 180 or 910 // Check if anti-parallel
761 // 0 degrees apart. These have to be detected and handled individually. 911 else if (cos_theta < -0.99999)
762 // 912 {
763 // Check for vectors 180 degrees apart. 913 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
764 // A dot product of -1 would mean the angle between vectors is 180 degrees. 914 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
765 if (dotProduct < -0.9999999f) 915 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
766 { 916 }
767 // First assume X axis is orthogonal to the vectors. 917 else // other rotation
768 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 918 {
769 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 919 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
770 // Check for near zero vector. A very small non-zero number here will create 920 axis = llVecNorm(axis);
771 // a rotation in an undesired direction. 921 double x, y, z, s, t;
772 if (LSL_Vector.Mag(orthoVector) > 0.0001) 922 s = Math.Cos(theta);
773 { 923 t = Math.Sin(theta);
774 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 924 x = axis.x * t;
775 } 925 y = axis.y * t;
776 // If the magnitude of the vector was near zero, then assume the X axis is not 926 z = axis.z * t;
777 // orthogonal and use the Z axis instead. 927 return new LSL_Rotation(x,y,z,s);
778 else
779 {
780 // Set 180 z rotation.
781 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
782 }
783 }
784 // Check for parallel vectors.
785 // A dot product of 1 would mean the angle between vectors is 0 degrees.
786 else if (dotProduct > 0.9999999f)
787 {
788 // Set zero rotation.
789 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
790 }
791 else
792 {
793 // All special checks have been performed so get the axis of rotation.
794 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
795 // Quarternion s value is the length of the unit vector + dot product.
796 double qs = 1.0 + dotProduct;
797 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
798 // Normalize the rotation.
799 double mag = LSL_Rotation.Mag(rotBetween);
800 // We shouldn't have to worry about a divide by zero here. The qs value will be
801 // non-zero because we already know if we're here, then the dotProduct is not -1 so
802 // qs will not be zero. Also, we've already handled the input vectors being zero so the
803 // crossProduct vector should also not be zero.
804 rotBetween.x = rotBetween.x / mag;
805 rotBetween.y = rotBetween.y / mag;
806 rotBetween.z = rotBetween.z / mag;
807 rotBetween.s = rotBetween.s / mag;
808 // Check for undefined values and set zero rotation if any found. This code might not actually be required
809 // any longer since zero vectors are checked for at the top.
810 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
811 {
812 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
813 }
814 }
815 } 928 }
816 return rotBetween;
817 } 929 }
818 930
819 public void llWhisper(int channelID, string text) 931 public void llWhisper(int channelID, string text)
820 { 932 {
821 m_host.AddScriptLPS(1); 933 m_host.AddScriptLPS(1);
@@ -831,10 +943,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
831 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 943 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
832 } 944 }
833 945
946 private void CheckSayShoutTime()
947 {
948 DateTime now = DateTime.UtcNow;
949 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
950 {
951 m_lastSayShoutCheck = now;
952 m_SayShoutCount = 0;
953 }
954 else
955 m_SayShoutCount++;
956 }
957
834 public void llSay(int channelID, string text) 958 public void llSay(int channelID, string text)
835 { 959 {
836 m_host.AddScriptLPS(1); 960 m_host.AddScriptLPS(1);
837 961
962 if (channelID == 0)
963// m_SayShoutCount++;
964 CheckSayShoutTime();
965
966 if (m_SayShoutCount >= 11)
967 ScriptSleep(2000);
968
838 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 969 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
839 { 970 {
840 Console.WriteLine(text); 971 Console.WriteLine(text);
@@ -857,6 +988,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
857 { 988 {
858 m_host.AddScriptLPS(1); 989 m_host.AddScriptLPS(1);
859 990
991 if (channelID == 0)
992// m_SayShoutCount++;
993 CheckSayShoutTime();
994
995 if (m_SayShoutCount >= 11)
996 ScriptSleep(2000);
997
860 if (text.Length > 1023) 998 if (text.Length > 1023)
861 text = text.Substring(0, 1023); 999 text = text.Substring(0, 1023);
862 1000
@@ -888,22 +1026,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
888 1026
889 public void llRegionSayTo(string target, int channel, string msg) 1027 public void llRegionSayTo(string target, int channel, string msg)
890 { 1028 {
1029 string error = String.Empty;
1030
891 if (msg.Length > 1023) 1031 if (msg.Length > 1023)
892 msg = msg.Substring(0, 1023); 1032 msg = msg.Substring(0, 1023);
893 1033
894 m_host.AddScriptLPS(1); 1034 m_host.AddScriptLPS(1);
895 1035
896 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
897 {
898 return;
899 }
900
901 UUID TargetID; 1036 UUID TargetID;
902 UUID.TryParse(target, out TargetID); 1037 UUID.TryParse(target, out TargetID);
903 1038
904 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1039 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
905 if (wComm != null) 1040 if (wComm != null)
906 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1041 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1042 LSLError(error);
907 } 1043 }
908 1044
909 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1045 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1159,10 +1295,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1159 return detectedParams.TouchUV; 1295 return detectedParams.TouchUV;
1160 } 1296 }
1161 1297
1298 [DebuggerNonUserCode]
1162 public virtual void llDie() 1299 public virtual void llDie()
1163 { 1300 {
1164 m_host.AddScriptLPS(1); 1301 m_host.AddScriptLPS(1);
1165 throw new SelfDeleteException(); 1302 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1166 } 1303 }
1167 1304
1168 public LSL_Float llGround(LSL_Vector offset) 1305 public LSL_Float llGround(LSL_Vector offset)
@@ -1233,6 +1370,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1233 1370
1234 public void llSetStatus(int status, int value) 1371 public void llSetStatus(int status, int value)
1235 { 1372 {
1373 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1374 return;
1236 m_host.AddScriptLPS(1); 1375 m_host.AddScriptLPS(1);
1237 1376
1238 int statusrotationaxis = 0; 1377 int statusrotationaxis = 0;
@@ -1256,6 +1395,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1256 if (!allow) 1395 if (!allow)
1257 return; 1396 return;
1258 1397
1398 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1399 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1400 return;
1401
1259 m_host.ScriptSetPhysicsStatus(true); 1402 m_host.ScriptSetPhysicsStatus(true);
1260 } 1403 }
1261 else 1404 else
@@ -1456,6 +1599,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1456 { 1599 {
1457 m_host.AddScriptLPS(1); 1600 m_host.AddScriptLPS(1);
1458 1601
1602 SetColor(m_host, color, face);
1603 }
1604
1605 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1606 {
1607 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1608 return;
1609
1610 Primitive.TextureEntry tex = part.Shape.Textures;
1611 Color4 texcolor;
1612 if (face >= 0 && face < GetNumberOfSides(part))
1613 {
1614 texcolor = tex.CreateFace((uint)face).RGBA;
1615 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1616 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1617 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1618 tex.FaceTextures[face].RGBA = texcolor;
1619 part.UpdateTextureEntry(tex.GetBytes());
1620 return;
1621 }
1622 else if (face == ScriptBaseClass.ALL_SIDES)
1623 {
1624 for (uint i = 0; i < GetNumberOfSides(part); i++)
1625 {
1626 if (tex.FaceTextures[i] != null)
1627 {
1628 texcolor = tex.FaceTextures[i].RGBA;
1629 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1630 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1631 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1632 tex.FaceTextures[i].RGBA = texcolor;
1633 }
1634 texcolor = tex.DefaultTexture.RGBA;
1635 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1636 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1637 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1638 tex.DefaultTexture.RGBA = texcolor;
1639 }
1640 part.UpdateTextureEntry(tex.GetBytes());
1641 return;
1642 }
1643
1459 if (face == ScriptBaseClass.ALL_SIDES) 1644 if (face == ScriptBaseClass.ALL_SIDES)
1460 face = SceneObjectPart.ALL_SIDES; 1645 face = SceneObjectPart.ALL_SIDES;
1461 1646
@@ -1464,6 +1649,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1464 1649
1465 public void SetTexGen(SceneObjectPart part, int face,int style) 1650 public void SetTexGen(SceneObjectPart part, int face,int style)
1466 { 1651 {
1652 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1653 return;
1654
1467 Primitive.TextureEntry tex = part.Shape.Textures; 1655 Primitive.TextureEntry tex = part.Shape.Textures;
1468 MappingType textype; 1656 MappingType textype;
1469 textype = MappingType.Default; 1657 textype = MappingType.Default;
@@ -1494,6 +1682,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1494 1682
1495 public void SetGlow(SceneObjectPart part, int face, float glow) 1683 public void SetGlow(SceneObjectPart part, int face, float glow)
1496 { 1684 {
1685 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1686 return;
1687
1497 Primitive.TextureEntry tex = part.Shape.Textures; 1688 Primitive.TextureEntry tex = part.Shape.Textures;
1498 if (face >= 0 && face < GetNumberOfSides(part)) 1689 if (face >= 0 && face < GetNumberOfSides(part))
1499 { 1690 {
@@ -1519,6 +1710,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1519 1710
1520 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1711 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1521 { 1712 {
1713 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1714 return;
1522 1715
1523 Shininess sval = new Shininess(); 1716 Shininess sval = new Shininess();
1524 1717
@@ -1569,6 +1762,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1569 1762
1570 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1763 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1571 { 1764 {
1765 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1766 return;
1767
1572 Primitive.TextureEntry tex = part.Shape.Textures; 1768 Primitive.TextureEntry tex = part.Shape.Textures;
1573 if (face >= 0 && face < GetNumberOfSides(part)) 1769 if (face >= 0 && face < GetNumberOfSides(part))
1574 { 1770 {
@@ -1629,13 +1825,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1629 m_host.AddScriptLPS(1); 1825 m_host.AddScriptLPS(1);
1630 1826
1631 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1827 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1632 1828 if (parts.Count > 0)
1633 foreach (SceneObjectPart part in parts) 1829 {
1634 SetAlpha(part, alpha, face); 1830 try
1831 {
1832 foreach (SceneObjectPart part in parts)
1833 SetAlpha(part, alpha, face);
1834 }
1835 finally
1836 {
1837 }
1838 }
1635 } 1839 }
1636 1840
1637 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1841 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1638 { 1842 {
1843 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1844 return;
1845
1639 Primitive.TextureEntry tex = part.Shape.Textures; 1846 Primitive.TextureEntry tex = part.Shape.Textures;
1640 Color4 texcolor; 1847 Color4 texcolor;
1641 if (face >= 0 && face < GetNumberOfSides(part)) 1848 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1688,7 +1895,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1688 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1895 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1689 float wind, float tension, LSL_Vector Force) 1896 float wind, float tension, LSL_Vector Force)
1690 { 1897 {
1691 if (part == null) 1898 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1692 return; 1899 return;
1693 1900
1694 if (flexi) 1901 if (flexi)
@@ -1729,7 +1936,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1729 /// <param name="falloff"></param> 1936 /// <param name="falloff"></param>
1730 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1937 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1731 { 1938 {
1732 if (part == null) 1939 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1733 return; 1940 return;
1734 1941
1735 if (light) 1942 if (light)
@@ -1762,11 +1969,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1762 Primitive.TextureEntry tex = part.Shape.Textures; 1969 Primitive.TextureEntry tex = part.Shape.Textures;
1763 Color4 texcolor; 1970 Color4 texcolor;
1764 LSL_Vector rgb = new LSL_Vector(); 1971 LSL_Vector rgb = new LSL_Vector();
1972 int nsides = GetNumberOfSides(part);
1973
1765 if (face == ScriptBaseClass.ALL_SIDES) 1974 if (face == ScriptBaseClass.ALL_SIDES)
1766 { 1975 {
1767 int i; 1976 int i;
1768 1977 for (i = 0; i < nsides; i++)
1769 for (i = 0 ; i < GetNumberOfSides(part); i++)
1770 { 1978 {
1771 texcolor = tex.GetFace((uint)i).RGBA; 1979 texcolor = tex.GetFace((uint)i).RGBA;
1772 rgb.x += texcolor.R; 1980 rgb.x += texcolor.R;
@@ -1774,14 +1982,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1774 rgb.z += texcolor.B; 1982 rgb.z += texcolor.B;
1775 } 1983 }
1776 1984
1777 rgb.x /= (float)GetNumberOfSides(part); 1985 float invnsides = 1.0f / (float)nsides;
1778 rgb.y /= (float)GetNumberOfSides(part); 1986
1779 rgb.z /= (float)GetNumberOfSides(part); 1987 rgb.x *= invnsides;
1988 rgb.y *= invnsides;
1989 rgb.z *= invnsides;
1780 1990
1781 return rgb; 1991 return rgb;
1782 } 1992 }
1783 1993 if (face >= 0 && face < nsides)
1784 if (face >= 0 && face < GetNumberOfSides(part))
1785 { 1994 {
1786 texcolor = tex.GetFace((uint)face).RGBA; 1995 texcolor = tex.GetFace((uint)face).RGBA;
1787 rgb.x = texcolor.R; 1996 rgb.x = texcolor.R;
@@ -1808,15 +2017,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1808 m_host.AddScriptLPS(1); 2017 m_host.AddScriptLPS(1);
1809 2018
1810 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2019 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1811 2020 if (parts.Count > 0)
1812 foreach (SceneObjectPart part in parts) 2021 {
1813 SetTexture(part, texture, face); 2022 try
1814 2023 {
2024 foreach (SceneObjectPart part in parts)
2025 SetTexture(part, texture, face);
2026 }
2027 finally
2028 {
2029 }
2030 }
1815 ScriptSleep(200); 2031 ScriptSleep(200);
1816 } 2032 }
1817 2033
1818 protected void SetTexture(SceneObjectPart part, string texture, int face) 2034 protected void SetTexture(SceneObjectPart part, string texture, int face)
1819 { 2035 {
2036 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2037 return;
2038
1820 UUID textureID = new UUID(); 2039 UUID textureID = new UUID();
1821 2040
1822 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 2041 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
@@ -1861,6 +2080,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1861 2080
1862 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2081 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1863 { 2082 {
2083 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2084 return;
2085
1864 Primitive.TextureEntry tex = part.Shape.Textures; 2086 Primitive.TextureEntry tex = part.Shape.Textures;
1865 if (face >= 0 && face < GetNumberOfSides(part)) 2087 if (face >= 0 && face < GetNumberOfSides(part))
1866 { 2088 {
@@ -1897,6 +2119,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1897 2119
1898 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2120 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1899 { 2121 {
2122 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2123 return;
2124
1900 Primitive.TextureEntry tex = part.Shape.Textures; 2125 Primitive.TextureEntry tex = part.Shape.Textures;
1901 if (face >= 0 && face < GetNumberOfSides(part)) 2126 if (face >= 0 && face < GetNumberOfSides(part))
1902 { 2127 {
@@ -1933,6 +2158,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1933 2158
1934 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2159 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1935 { 2160 {
2161 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2162 return;
2163
1936 Primitive.TextureEntry tex = part.Shape.Textures; 2164 Primitive.TextureEntry tex = part.Shape.Textures;
1937 if (face >= 0 && face < GetNumberOfSides(part)) 2165 if (face >= 0 && face < GetNumberOfSides(part))
1938 { 2166 {
@@ -2074,7 +2302,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2074 return end; 2302 return end;
2075 } 2303 }
2076 2304
2077 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2305 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2078 { 2306 {
2079 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2307 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2080 return fromPos; 2308 return fromPos;
@@ -2090,9 +2318,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2090 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2318 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2091 targetPos.z = ground; 2319 targetPos.z = ground;
2092 } 2320 }
2093 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2321 if (adjust)
2322 return SetPosAdjust(fromPos, targetPos);
2094 2323
2095 return real_vec; 2324 return targetPos;
2096 } 2325 }
2097 2326
2098 /// <summary> 2327 /// <summary>
@@ -2103,27 +2332,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2103 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2332 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2104 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2333 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2105 { 2334 {
2106 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2335 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2336 return;
2337
2107 LSL_Vector currentPos = GetPartLocalPos(part); 2338 LSL_Vector currentPos = GetPartLocalPos(part);
2339 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2108 2340
2109 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2110 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2111 2341
2112 if (part.ParentGroup.RootPart == part) 2342 if (part.ParentGroup.RootPart == part)
2113 { 2343 {
2114 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2115 targetPos.z = ground;
2116 SceneObjectGroup parent = part.ParentGroup; 2344 SceneObjectGroup parent = part.ParentGroup;
2117 parent.UpdateGroupPosition(!adjust ? targetPos : 2345 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2118 SetPosAdjust(currentPos, targetPos)); 2346 return;
2347 Util.FireAndForget(delegate(object x) {
2348 parent.UpdateGroupPosition((Vector3)toPos);
2349 });
2119 } 2350 }
2120 else 2351 else
2121 { 2352 {
2122 part.OffsetPosition = !adjust ? targetPos : 2353 part.OffsetPosition = (Vector3)toPos;
2123 SetPosAdjust(currentPos, targetPos); 2354// SceneObjectGroup parent = part.ParentGroup;
2124 SceneObjectGroup parent = part.ParentGroup; 2355// parent.HasGroupChanged = true;
2125 parent.HasGroupChanged = true; 2356// parent.ScheduleGroupForTerseUpdate();
2126 parent.ScheduleGroupForTerseUpdate(); 2357 part.ScheduleTerseUpdate();
2127 } 2358 }
2128 } 2359 }
2129 2360
@@ -2152,13 +2383,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2152 else 2383 else
2153 { 2384 {
2154 if (part.ParentGroup.IsAttachment) 2385 if (part.ParentGroup.IsAttachment)
2155 {
2156 pos = part.AttachedPos; 2386 pos = part.AttachedPos;
2157 }
2158 else 2387 else
2159 {
2160 pos = part.AbsolutePosition; 2388 pos = part.AbsolutePosition;
2161 }
2162 } 2389 }
2163 2390
2164// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2391// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2170,8 +2397,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2170 { 2397 {
2171 m_host.AddScriptLPS(1); 2398 m_host.AddScriptLPS(1);
2172 2399
2400
2401 // Teravus: if (m_host.ParentID == 0) is bug code because the ParentID for the Avatar will cause this to be nonzero for root prim attachments
2402 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2403 // to fix the scripted rotations we also have to check to see if the root part localid is the same as the host's localid.
2404 // RootPart != null should shortcircuit
2405
2173 // try to let this work as in SL... 2406 // try to let this work as in SL...
2174 if (m_host.ParentID == 0) 2407 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2175 { 2408 {
2176 // special case: If we are root, rotate complete SOG to new rotation 2409 // special case: If we are root, rotate complete SOG to new rotation
2177 SetRot(m_host, rot); 2410 SetRot(m_host, rot);
@@ -2198,25 +2431,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2198 2431
2199 protected void SetRot(SceneObjectPart part, Quaternion rot) 2432 protected void SetRot(SceneObjectPart part, Quaternion rot)
2200 { 2433 {
2201 part.UpdateRotation(rot); 2434 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2202 // Update rotation does not move the object in the physics scene if it's a linkset. 2435 return;
2203 2436
2204//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2437 bool isroot = (part == part.ParentGroup.RootPart);
2205// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2438 bool isphys;
2206 2439
2207 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2208 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2209 // It's perfectly okay when the object is not an active physical body though.
2210 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2211 // but only if the object is not physial and active. This is important for rotating doors.
2212 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2213 // scene
2214 PhysicsActor pa = part.PhysActor; 2440 PhysicsActor pa = part.PhysActor;
2215 2441
2216 if (pa != null && !pa.IsPhysical) 2442 // keep using physactor ideia of isphysical
2443 // it should be SOP ideia of that
2444 // not much of a issue with ubitODE
2445 if (pa != null && pa.IsPhysical)
2446 isphys = true;
2447 else
2448 isphys = false;
2449
2450 // SL doesn't let scripts rotate root of physical linksets
2451 if (isroot && isphys)
2452 return;
2453
2454 part.UpdateRotation(rot);
2455
2456 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2457 // so do a nasty update of parts positions if is a root part rotation
2458 if (isroot && pa != null) // with if above implies non physical root part
2217 { 2459 {
2218 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2460 part.ParentGroup.ResetChildPrimPhysicsPositions();
2219 } 2461 }
2462 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2463 {
2464 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2465 if (sittingavas.Count > 0)
2466 {
2467 foreach (ScenePresence av in sittingavas)
2468 {
2469 if (isroot || part.LocalId == av.ParentID)
2470 av.SendTerseUpdateToAllClients();
2471 }
2472 }
2473 }
2220 } 2474 }
2221 2475
2222 /// <summary> 2476 /// <summary>
@@ -2233,6 +2487,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2233 2487
2234 m_host.AddScriptLPS(1); 2488 m_host.AddScriptLPS(1);
2235 Quaternion q = m_host.GetWorldRotation(); 2489 Quaternion q = m_host.GetWorldRotation();
2490
2491 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2492 {
2493 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2494 if (avatar != null)
2495 {
2496 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2497 q = avatar.CameraRotation * q; // Mouselook
2498 else
2499 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2500 }
2501 }
2502
2236 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2503 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2237 } 2504 }
2238 2505
@@ -2260,14 +2527,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2260 return new LSL_Rotation(q); 2527 return new LSL_Rotation(q);
2261 } 2528 }
2262 2529
2263 return new LSL_Rotation(part.GetWorldRotation()); 2530 q = part.GetWorldRotation();
2531 if (part.ParentGroup.AttachmentPoint != 0)
2532 {
2533 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2534 if (avatar != null)
2535 {
2536 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2537 q = avatar.CameraRotation * q; // Mouselook
2538 else
2539 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2540 }
2541 }
2542
2543 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2264 } 2544 }
2265 2545
2266 public LSL_Rotation llGetLocalRot() 2546 public LSL_Rotation llGetLocalRot()
2267 { 2547 {
2268 m_host.AddScriptLPS(1); 2548 return GetPartLocalRot(m_host);
2549 }
2269 2550
2270 return new LSL_Rotation(m_host.RotationOffset); 2551 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2552 {
2553 m_host.AddScriptLPS(1);
2554 Quaternion rot = part.RotationOffset;
2555 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2271 } 2556 }
2272 2557
2273 public void llSetForce(LSL_Vector force, int local) 2558 public void llSetForce(LSL_Vector force, int local)
@@ -2347,16 +2632,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2347 m_host.ApplyImpulse(v, local != 0); 2632 m_host.ApplyImpulse(v, local != 0);
2348 } 2633 }
2349 2634
2635
2350 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2636 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2351 { 2637 {
2352 m_host.AddScriptLPS(1); 2638 m_host.AddScriptLPS(1);
2353 m_host.ApplyAngularImpulse(force, local != 0); 2639 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2354 } 2640 }
2355 2641
2356 public void llSetTorque(LSL_Vector torque, int local) 2642 public void llSetTorque(LSL_Vector torque, int local)
2357 { 2643 {
2358 m_host.AddScriptLPS(1); 2644 m_host.AddScriptLPS(1);
2359 m_host.SetAngularImpulse(torque, local != 0); 2645 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2360 } 2646 }
2361 2647
2362 public LSL_Vector llGetTorque() 2648 public LSL_Vector llGetTorque()
@@ -2373,20 +2659,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2373 llSetTorque(torque, local); 2659 llSetTorque(torque, local);
2374 } 2660 }
2375 2661
2662 public void llSetVelocity(LSL_Vector vel, int local)
2663 {
2664 m_host.AddScriptLPS(1);
2665 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2666 }
2667
2376 public LSL_Vector llGetVel() 2668 public LSL_Vector llGetVel()
2377 { 2669 {
2378 m_host.AddScriptLPS(1); 2670 m_host.AddScriptLPS(1);
2379 2671
2380 Vector3 vel; 2672 Vector3 vel = Vector3.Zero;
2381 2673
2382 if (m_host.ParentGroup.IsAttachment) 2674 if (m_host.ParentGroup.IsAttachment)
2383 { 2675 {
2384 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2676 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2385 vel = avatar.Velocity; 2677 if (avatar != null)
2678 vel = avatar.Velocity;
2386 } 2679 }
2387 else 2680 else
2388 { 2681 {
2389 vel = m_host.Velocity; 2682 vel = m_host.ParentGroup.RootPart.Velocity;
2390 } 2683 }
2391 2684
2392 return new LSL_Vector(vel); 2685 return new LSL_Vector(vel);
@@ -2399,11 +2692,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2399 return new LSL_Vector(m_host.Acceleration); 2692 return new LSL_Vector(m_host.Acceleration);
2400 } 2693 }
2401 2694
2402 public LSL_Vector llGetOmega() 2695 public void llSetAngularVelocity(LSL_Vector avel, int local)
2403 { 2696 {
2404 m_host.AddScriptLPS(1); 2697 m_host.AddScriptLPS(1);
2698 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2699 }
2405 2700
2406 return new LSL_Vector(m_host.AngularVelocity); 2701 public LSL_Vector llGetOmega()
2702 {
2703 m_host.AddScriptLPS(1);
2704 Vector3 avel = m_host.AngularVelocity;
2705 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2407 } 2706 }
2408 2707
2409 public LSL_Float llGetTimeOfDay() 2708 public LSL_Float llGetTimeOfDay()
@@ -2762,7 +3061,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2762 return src.ToLower(); 3061 return src.ToLower();
2763 } 3062 }
2764 3063
2765 public void llGiveMoney(string destination, int amount) 3064 public LSL_Integer llGiveMoney(string destination, int amount)
2766 { 3065 {
2767 Util.FireAndForget(x => 3066 Util.FireAndForget(x =>
2768 { 3067 {
@@ -2794,8 +3093,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2794 } 3093 }
2795 3094
2796 money.ObjectGiveMoney( 3095 money.ObjectGiveMoney(
2797 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3096 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2798 }); 3097 });
3098
3099 return 0;
2799 } 3100 }
2800 3101
2801 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3102 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -2874,13 +3175,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2874 new_group.RootPart.UUID.ToString()) }, 3175 new_group.RootPart.UUID.ToString()) },
2875 new DetectParams[0])); 3176 new DetectParams[0]));
2876 3177
2877 float groupmass = new_group.GetMass(); 3178 // do recoil
3179 SceneObjectGroup hostgrp = m_host.ParentGroup;
3180 if (hostgrp == null)
3181 return;
3182
3183 if (hostgrp.IsAttachment) // don't recoil avatars
3184 return;
2878 3185
2879 PhysicsActor pa = new_group.RootPart.PhysActor; 3186 PhysicsActor pa = new_group.RootPart.PhysActor;
2880 3187
2881 //Recoil. 3188 //Recoil.
2882 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3189 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2883 { 3190 {
3191 float groupmass = new_group.GetMass();
2884 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3192 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2885 if (recoil != Vector3.Zero) 3193 if (recoil != Vector3.Zero)
2886 { 3194 {
@@ -2888,6 +3196,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2888 } 3196 }
2889 } 3197 }
2890 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3198 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3199 return;
3200
2891 }); 3201 });
2892 3202
2893 //ScriptSleep((int)((groupmass * velmag) / 10)); 3203 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2902,35 +3212,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2902 public void llLookAt(LSL_Vector target, double strength, double damping) 3212 public void llLookAt(LSL_Vector target, double strength, double damping)
2903 { 3213 {
2904 m_host.AddScriptLPS(1); 3214 m_host.AddScriptLPS(1);
2905 // Determine where we are looking from
2906 LSL_Vector from = llGetPos();
2907 3215
2908 // Work out the normalised vector from the source to the target 3216 // Get the normalized vector to the target
2909 LSL_Vector delta = llVecNorm(target - from); 3217 LSL_Vector d1 = llVecNorm(target - llGetPos());
2910 LSL_Vector angle = new LSL_Vector(0,0,0);
2911 3218
2912 // Calculate the yaw 3219 // Get the bearing (yaw)
2913 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3220 LSL_Vector a1 = new LSL_Vector(0,0,0);
2914 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3221 a1.z = llAtan2(d1.y, d1.x);
2915 3222
2916 // Calculate pitch 3223 // Get the elevation (pitch)
2917 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3224 LSL_Vector a2 = new LSL_Vector(0,0,0);
3225 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2918 3226
2919 // we need to convert from a vector describing 3227 LSL_Rotation r1 = llEuler2Rot(a1);
2920 // the angles of rotation in radians into rotation value 3228 LSL_Rotation r2 = llEuler2Rot(a2);
2921 LSL_Rotation rot = llEuler2Rot(angle); 3229 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2922
2923 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2924 // set the rotation of the object, copy that behavior
2925 PhysicsActor pa = m_host.PhysActor;
2926 3230
2927 if (strength == 0 || pa == null || !pa.IsPhysical) 3231 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2928 { 3232 {
2929 llSetRot(rot); 3233 // Do nothing if either value is 0 (this has been checked in SL)
3234 if (strength <= 0.0 || damping <= 0.0)
3235 return;
3236
3237 llSetRot(r3 * r2 * r1);
2930 } 3238 }
2931 else 3239 else
2932 { 3240 {
2933 m_host.StartLookAt(rot, (float)strength, (float)damping); 3241 if (strength == 0)
3242 {
3243 llSetRot(r3 * r2 * r1);
3244 return;
3245 }
3246
3247 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2934 } 3248 }
2935 } 3249 }
2936 3250
@@ -2977,17 +3291,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2977 } 3291 }
2978 else 3292 else
2979 { 3293 {
2980 if (m_host.IsRoot) 3294 // new SL always returns object mass
2981 { 3295// if (m_host.IsRoot)
3296// {
2982 return m_host.ParentGroup.GetMass(); 3297 return m_host.ParentGroup.GetMass();
2983 } 3298// }
2984 else 3299// else
2985 { 3300// {
2986 return m_host.GetMass(); 3301// return m_host.GetMass();
2987 } 3302// }
2988 } 3303 }
2989 } 3304 }
2990 3305
3306
3307 public LSL_Float llGetMassMKS()
3308 {
3309 return 100f * llGetMass();
3310 }
3311
2991 public void llCollisionFilter(string name, string id, int accept) 3312 public void llCollisionFilter(string name, string id, int accept)
2992 { 3313 {
2993 m_host.AddScriptLPS(1); 3314 m_host.AddScriptLPS(1);
@@ -3035,8 +3356,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3035 { 3356 {
3036 // Unregister controls from Presence 3357 // Unregister controls from Presence
3037 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3358 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3038 // Remove Take Control permission.
3039 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3040 } 3359 }
3041 } 3360 }
3042 } 3361 }
@@ -3064,7 +3383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3064 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3383 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3065 3384
3066 if (attachmentsModule != null) 3385 if (attachmentsModule != null)
3067 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true); 3386 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3068 else 3387 else
3069 return false; 3388 return false;
3070 } 3389 }
@@ -3094,9 +3413,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3094 { 3413 {
3095 m_host.AddScriptLPS(1); 3414 m_host.AddScriptLPS(1);
3096 3415
3097// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3098// return;
3099
3100 if (m_item.PermsGranter != m_host.OwnerID) 3416 if (m_item.PermsGranter != m_host.OwnerID)
3101 return; 3417 return;
3102 3418
@@ -3139,6 +3455,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3139 3455
3140 public void llInstantMessage(string user, string message) 3456 public void llInstantMessage(string user, string message)
3141 { 3457 {
3458 UUID result;
3459 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3460 {
3461 ShoutError("An invalid key was passed to llInstantMessage");
3462 ScriptSleep(2000);
3463 return;
3464 }
3465
3466
3142 m_host.AddScriptLPS(1); 3467 m_host.AddScriptLPS(1);
3143 3468
3144 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3469 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3153,14 +3478,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3153 UUID friendTransactionID = UUID.Random(); 3478 UUID friendTransactionID = UUID.Random();
3154 3479
3155 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3480 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3156 3481
3157 GridInstantMessage msg = new GridInstantMessage(); 3482 GridInstantMessage msg = new GridInstantMessage();
3158 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3483 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3159 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3484 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3160 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3485 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3161// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3486// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3162// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3487// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3163 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3488// DateTime dt = DateTime.UtcNow;
3489//
3490// // Ticks from UtcNow, but make it look like local. Evil, huh?
3491// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3492//
3493// try
3494// {
3495// // Convert that to the PST timezone
3496// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3497// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3498// }
3499// catch
3500// {
3501// // No logging here, as it could be VERY spammy
3502// }
3503//
3504// // And make it look local again to fool the unix time util
3505// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3506
3507 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3508
3164 //if (client != null) 3509 //if (client != null)
3165 //{ 3510 //{
3166 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3511 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3174,10 +3519,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3174 msg.message = message.Substring(0, 1024); 3519 msg.message = message.Substring(0, 1024);
3175 else 3520 else
3176 msg.message = message; 3521 msg.message = message;
3177 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3522 msg.dialog = (byte)19; // MessageFromObject
3178 msg.fromGroup = false;// fromGroup; 3523 msg.fromGroup = false;// fromGroup;
3179 msg.offline = (byte)0; //offline; 3524 msg.offline = (byte)0; //offline;
3180 msg.ParentEstateID = 0; //ParentEstateID; 3525 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3181 msg.Position = new Vector3(m_host.AbsolutePosition); 3526 msg.Position = new Vector3(m_host.AbsolutePosition);
3182 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3527 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3183 3528
@@ -3209,7 +3554,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3209 } 3554 }
3210 3555
3211 emailModule.SendEmail(m_host.UUID, address, subject, message); 3556 emailModule.SendEmail(m_host.UUID, address, subject, message);
3212 llSleep(EMAIL_PAUSE_TIME); 3557 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3213 } 3558 }
3214 3559
3215 public void llGetNextEmail(string address, string subject) 3560 public void llGetNextEmail(string address, string subject)
@@ -3455,7 +3800,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3455 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3800 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3456 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3801 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3457 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3802 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3803 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3458 ScriptBaseClass.PERMISSION_ATTACH; 3804 ScriptBaseClass.PERMISSION_ATTACH;
3805
3459 } 3806 }
3460 else 3807 else
3461 { 3808 {
@@ -3472,15 +3819,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3472 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3819 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3473 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3820 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3474 } 3821 }
3822 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3823 {
3824 implicitPerms = perm;
3825 }
3475 } 3826 }
3476 3827
3477 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3828 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3478 { 3829 {
3479 lock (m_host.TaskInventory) 3830 m_host.TaskInventory.LockItemsForWrite(true);
3480 { 3831 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3481 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3832 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3482 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3833 m_host.TaskInventory.LockItemsForWrite(false);
3483 }
3484 3834
3485 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3835 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3486 "run_time_permissions", new Object[] { 3836 "run_time_permissions", new Object[] {
@@ -3523,11 +3873,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3523 3873
3524 if (!m_waitingForScriptAnswer) 3874 if (!m_waitingForScriptAnswer)
3525 { 3875 {
3526 lock (m_host.TaskInventory) 3876 m_host.TaskInventory.LockItemsForWrite(true);
3527 { 3877 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3528 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3878 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3529 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3879 m_host.TaskInventory.LockItemsForWrite(false);
3530 }
3531 3880
3532 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3881 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3533 m_waitingForScriptAnswer=true; 3882 m_waitingForScriptAnswer=true;
@@ -3556,14 +3905,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3556 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3905 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3557 llReleaseControls(); 3906 llReleaseControls();
3558 3907
3559 lock (m_host.TaskInventory) 3908 m_host.TaskInventory.LockItemsForWrite(true);
3560 { 3909 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3561 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3910 m_host.TaskInventory.LockItemsForWrite(false);
3562 } 3911
3563 3912 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3564 m_ScriptEngine.PostScriptEvent( 3913 "run_time_permissions", new Object[] {
3565 m_item.ItemID, 3914 new LSL_Integer(answer) },
3566 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3915 new DetectParams[0]));
3567 } 3916 }
3568 3917
3569 public LSL_String llGetPermissionsKey() 3918 public LSL_String llGetPermissionsKey()
@@ -3602,14 +3951,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3602 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3951 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3603 { 3952 {
3604 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3953 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3605 3954 if (parts.Count > 0)
3606 foreach (SceneObjectPart part in parts) 3955 {
3607 part.SetFaceColorAlpha(face, color, null); 3956 try
3957 {
3958 foreach (SceneObjectPart part in parts)
3959 part.SetFaceColorAlpha(face, color, null);
3960 }
3961 finally
3962 {
3963 }
3964 }
3608 } 3965 }
3609 3966
3610 public void llCreateLink(string target, int parent) 3967 public void llCreateLink(string target, int parent)
3611 { 3968 {
3612 m_host.AddScriptLPS(1); 3969 m_host.AddScriptLPS(1);
3970
3613 UUID targetID; 3971 UUID targetID;
3614 3972
3615 if (!UUID.TryParse(target, out targetID)) 3973 if (!UUID.TryParse(target, out targetID))
@@ -3715,10 +4073,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3715 // Restructuring Multiple Prims. 4073 // Restructuring Multiple Prims.
3716 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4074 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3717 parts.Remove(parentPrim.RootPart); 4075 parts.Remove(parentPrim.RootPart);
3718 foreach (SceneObjectPart part in parts) 4076 if (parts.Count > 0)
3719 { 4077 {
3720 parentPrim.DelinkFromGroup(part.LocalId, true); 4078 try
4079 {
4080 foreach (SceneObjectPart part in parts)
4081 {
4082 parentPrim.DelinkFromGroup(part.LocalId, true);
4083 }
4084 }
4085 finally
4086 {
4087 }
3721 } 4088 }
4089
3722 parentPrim.HasGroupChanged = true; 4090 parentPrim.HasGroupChanged = true;
3723 parentPrim.ScheduleGroupForFullUpdate(); 4091 parentPrim.ScheduleGroupForFullUpdate();
3724 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4092 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3727,12 +4095,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3727 { 4095 {
3728 SceneObjectPart newRoot = parts[0]; 4096 SceneObjectPart newRoot = parts[0];
3729 parts.Remove(newRoot); 4097 parts.Remove(newRoot);
3730 foreach (SceneObjectPart part in parts) 4098
4099 try
3731 { 4100 {
3732 // Required for linking 4101 foreach (SceneObjectPart part in parts)
3733 part.ClearUpdateSchedule(); 4102 {
3734 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4103 part.ClearUpdateSchedule();
4104 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4105 }
3735 } 4106 }
4107 finally
4108 {
4109 }
4110
4111
3736 newRoot.ParentGroup.HasGroupChanged = true; 4112 newRoot.ParentGroup.HasGroupChanged = true;
3737 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4113 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3738 } 4114 }
@@ -3752,6 +4128,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3752 public void llBreakAllLinks() 4128 public void llBreakAllLinks()
3753 { 4129 {
3754 m_host.AddScriptLPS(1); 4130 m_host.AddScriptLPS(1);
4131
4132 TaskInventoryItem item = m_item;
4133
4134 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4135 && !m_automaticLinkPermission)
4136 {
4137 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4138 return;
4139 }
4140
3755 SceneObjectGroup parentPrim = m_host.ParentGroup; 4141 SceneObjectGroup parentPrim = m_host.ParentGroup;
3756 if (parentPrim.AttachmentPoint != 0) 4142 if (parentPrim.AttachmentPoint != 0)
3757 return; // Fail silently if attached 4143 return; // Fail silently if attached
@@ -3771,13 +4157,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3771 public LSL_String llGetLinkKey(int linknum) 4157 public LSL_String llGetLinkKey(int linknum)
3772 { 4158 {
3773 m_host.AddScriptLPS(1); 4159 m_host.AddScriptLPS(1);
4160 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
4161 if (part != null)
4162 {
4163 return part.UUID.ToString();
4164 }
4165 else
4166 {
4167 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4168 {
4169 linknum -= (m_host.ParentGroup.PrimCount) + 1;
3774 4170
3775 ISceneEntity entity = GetLinkEntity(linknum); 4171 if (linknum < 0)
4172 return UUID.Zero.ToString();
3776 4173
3777 if (entity != null) 4174 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
3778 return entity.UUID.ToString(); 4175 if (avatars.Count > linknum)
3779 else 4176 {
3780 return ScriptBaseClass.NULL_KEY; 4177 return avatars[linknum].UUID.ToString();
4178 }
4179 }
4180 return UUID.Zero.ToString();
4181 }
3781 } 4182 }
3782 4183
3783 /// <summary> 4184 /// <summary>
@@ -3836,17 +4237,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3836 m_host.AddScriptLPS(1); 4237 m_host.AddScriptLPS(1);
3837 int count = 0; 4238 int count = 0;
3838 4239
3839 lock (m_host.TaskInventory) 4240 m_host.TaskInventory.LockItemsForRead(true);
4241 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3840 { 4242 {
3841 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4243 if (inv.Value.Type == type || type == -1)
3842 { 4244 {
3843 if (inv.Value.Type == type || type == -1) 4245 count = count + 1;
3844 {
3845 count = count + 1;
3846 }
3847 } 4246 }
3848 } 4247 }
3849 4248
4249 m_host.TaskInventory.LockItemsForRead(false);
3850 return count; 4250 return count;
3851 } 4251 }
3852 4252
@@ -3855,16 +4255,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3855 m_host.AddScriptLPS(1); 4255 m_host.AddScriptLPS(1);
3856 ArrayList keys = new ArrayList(); 4256 ArrayList keys = new ArrayList();
3857 4257
3858 lock (m_host.TaskInventory) 4258 m_host.TaskInventory.LockItemsForRead(true);
4259 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3859 { 4260 {
3860 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4261 if (inv.Value.Type == type || type == -1)
3861 { 4262 {
3862 if (inv.Value.Type == type || type == -1) 4263 keys.Add(inv.Value.Name);
3863 {
3864 keys.Add(inv.Value.Name);
3865 }
3866 } 4264 }
3867 } 4265 }
4266 m_host.TaskInventory.LockItemsForRead(false);
3868 4267
3869 if (keys.Count == 0) 4268 if (keys.Count == 0)
3870 { 4269 {
@@ -3902,7 +4301,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3902 if (item == null) 4301 if (item == null)
3903 { 4302 {
3904 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4303 llSay(0, String.Format("Could not find object '{0}'", inventory));
3905 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4304 return;
4305// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3906 } 4306 }
3907 4307
3908 UUID objId = item.ItemID; 4308 UUID objId = item.ItemID;
@@ -3930,33 +4330,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3930 return; 4330 return;
3931 } 4331 }
3932 } 4332 }
4333
3933 // destination is an avatar 4334 // destination is an avatar
3934 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4335 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3935 4336
3936 if (agentItem == null) 4337 if (agentItem == null)
3937 return; 4338 return;
3938 4339
3939 if (m_TransferModule != null) 4340 byte[] bucket = new byte[1];
3940 { 4341 bucket[0] = (byte)item.Type;
3941 byte[] bucket = new byte[1]; 4342 //byte[] objBytes = agentItem.ID.GetBytes();
3942 bucket[0] = (byte)item.Type; 4343 //Array.Copy(objBytes, 0, bucket, 1, 16);
3943 4344
3944 GridInstantMessage msg = new GridInstantMessage(World, 4345 GridInstantMessage msg = new GridInstantMessage(World,
3945 m_host.OwnerID, m_host.Name, destId, 4346 m_host.OwnerID, m_host.Name, destId,
3946 (byte)InstantMessageDialog.TaskInventoryOffered, 4347 (byte)InstantMessageDialog.TaskInventoryOffered,
3947 false, item.Name+". "+m_host.Name+" is located at "+ 4348 false, item.Name+". "+m_host.Name+" is located at "+
3948 World.RegionInfo.RegionName+" "+ 4349 World.RegionInfo.RegionName+" "+
3949 m_host.AbsolutePosition.ToString(), 4350 m_host.AbsolutePosition.ToString(),
3950 agentItem.ID, true, m_host.AbsolutePosition, 4351 agentItem.ID, true, m_host.AbsolutePosition,
3951 bucket, true); 4352 bucket, true);
3952 4353
3953 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4354 ScenePresence sp;
3954 }
3955 4355
4356 if (World.TryGetScenePresence(destId, out sp))
4357 {
4358 sp.ControllingClient.SendInstantMessage(msg);
4359 }
4360 else
4361 {
4362 if (m_TransferModule != null)
4363 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4364 }
4365
4366 //This delay should only occur when giving inventory to avatars.
3956 ScriptSleep(3000); 4367 ScriptSleep(3000);
3957 } 4368 }
3958 } 4369 }
3959 4370
4371 [DebuggerNonUserCode]
3960 public void llRemoveInventory(string name) 4372 public void llRemoveInventory(string name)
3961 { 4373 {
3962 m_host.AddScriptLPS(1); 4374 m_host.AddScriptLPS(1);
@@ -4011,109 +4423,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4011 { 4423 {
4012 m_host.AddScriptLPS(1); 4424 m_host.AddScriptLPS(1);
4013 4425
4014 UUID uuid = (UUID)id; 4426 UUID uuid;
4015 PresenceInfo pinfo = null; 4427 if (UUID.TryParse(id, out uuid))
4016 UserAccount account;
4017
4018 UserInfoCacheEntry ce;
4019 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4020 { 4428 {
4021 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4429 PresenceInfo pinfo = null;
4022 if (account == null) 4430 UserAccount account;
4431
4432 UserInfoCacheEntry ce;
4433 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4023 { 4434 {
4024 m_userInfoCache[uuid] = null; // Cache negative 4435 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4025 return UUID.Zero.ToString(); 4436 if (account == null)
4026 } 4437 {
4438 m_userInfoCache[uuid] = null; // Cache negative
4439 return UUID.Zero.ToString();
4440 }
4027 4441
4028 4442
4029 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4443 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4030 if (pinfos != null && pinfos.Length > 0) 4444 if (pinfos != null && pinfos.Length > 0)
4031 {
4032 foreach (PresenceInfo p in pinfos)
4033 { 4445 {
4034 if (p.RegionID != UUID.Zero) 4446 foreach (PresenceInfo p in pinfos)
4035 { 4447 {
4036 pinfo = p; 4448 if (p.RegionID != UUID.Zero)
4449 {
4450 pinfo = p;
4451 }
4037 } 4452 }
4038 } 4453 }
4039 }
4040 4454
4041 ce = new UserInfoCacheEntry(); 4455 ce = new UserInfoCacheEntry();
4042 ce.time = Util.EnvironmentTickCount(); 4456 ce.time = Util.EnvironmentTickCount();
4043 ce.account = account; 4457 ce.account = account;
4044 ce.pinfo = pinfo; 4458 ce.pinfo = pinfo;
4045 } 4459 m_userInfoCache[uuid] = ce;
4046 else 4460 }
4047 { 4461 else
4048 if (ce == null) 4462 {
4049 return UUID.Zero.ToString(); 4463 if (ce == null)
4464 return UUID.Zero.ToString();
4050 4465
4051 account = ce.account; 4466 account = ce.account;
4052 pinfo = ce.pinfo; 4467 pinfo = ce.pinfo;
4053 } 4468 }
4054 4469
4055 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4470 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4056 {
4057 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4058 if (pinfos != null && pinfos.Length > 0)
4059 { 4471 {
4060 foreach (PresenceInfo p in pinfos) 4472 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4473 if (pinfos != null && pinfos.Length > 0)
4061 { 4474 {
4062 if (p.RegionID != UUID.Zero) 4475 foreach (PresenceInfo p in pinfos)
4063 { 4476 {
4064 pinfo = p; 4477 if (p.RegionID != UUID.Zero)
4478 {
4479 pinfo = p;
4480 }
4065 } 4481 }
4066 } 4482 }
4067 } 4483 else
4068 else 4484 pinfo = null;
4069 pinfo = null;
4070 4485
4071 ce.time = Util.EnvironmentTickCount(); 4486 ce.time = Util.EnvironmentTickCount();
4072 ce.pinfo = pinfo; 4487 ce.pinfo = pinfo;
4073 } 4488 }
4074 4489
4075 string reply = String.Empty; 4490 string reply = String.Empty;
4076 4491
4077 switch (data) 4492 switch (data)
4078 { 4493 {
4079 case 1: // DATA_ONLINE (0|1) 4494 case 1: // DATA_ONLINE (0|1)
4080 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4495 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4081 reply = "1"; 4496 reply = "1";
4082 else 4497 else
4083 reply = "0"; 4498 reply = "0";
4084 break; 4499 break;
4085 case 2: // DATA_NAME (First Last) 4500 case 2: // DATA_NAME (First Last)
4086 reply = account.FirstName + " " + account.LastName; 4501 reply = account.FirstName + " " + account.LastName;
4087 break; 4502 break;
4088 case 3: // DATA_BORN (YYYY-MM-DD) 4503 case 3: // DATA_BORN (YYYY-MM-DD)
4089 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4504 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4090 born = born.AddSeconds(account.Created); 4505 born = born.AddSeconds(account.Created);
4091 reply = born.ToString("yyyy-MM-dd"); 4506 reply = born.ToString("yyyy-MM-dd");
4092 break; 4507 break;
4093 case 4: // DATA_RATING (0,0,0,0,0,0) 4508 case 4: // DATA_RATING (0,0,0,0,0,0)
4094 reply = "0,0,0,0,0,0"; 4509 reply = "0,0,0,0,0,0";
4095 break; 4510 break;
4096 case 7: // DATA_USERLEVEL (integer) 4511 case 8: // DATA_PAYINFO (0|1|2|3)
4097 reply = account.UserLevel.ToString(); 4512 reply = "0";
4098 break; 4513 break;
4099 case 8: // DATA_PAYINFO (0|1|2|3) 4514 default:
4100 reply = "0"; 4515 return UUID.Zero.ToString(); // Raise no event
4101 break; 4516 }
4102 default:
4103 return UUID.Zero.ToString(); // Raise no event
4104 }
4105 4517
4106 UUID rq = UUID.Random(); 4518 UUID rq = UUID.Random();
4107 4519
4108 UUID tid = AsyncCommands. 4520 UUID tid = AsyncCommands.
4109 DataserverPlugin.RegisterRequest(m_host.LocalId, 4521 DataserverPlugin.RegisterRequest(m_host.LocalId,
4110 m_item.ItemID, rq.ToString()); 4522 m_item.ItemID, rq.ToString());
4111 4523
4112 AsyncCommands. 4524 AsyncCommands.
4113 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4525 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4114 4526
4115 ScriptSleep(100); 4527 ScriptSleep(100);
4116 return tid.ToString(); 4528 return tid.ToString();
4529 }
4530 else
4531 {
4532 ShoutError("Invalid UUID passed to llRequestAgentData.");
4533 }
4534 return "";
4117 } 4535 }
4118 4536
4119 public LSL_String llRequestInventoryData(string name) 4537 public LSL_String llRequestInventoryData(string name)
@@ -4170,12 +4588,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4170 if (UUID.TryParse(agent, out agentId)) 4588 if (UUID.TryParse(agent, out agentId))
4171 { 4589 {
4172 ScenePresence presence = World.GetScenePresence(agentId); 4590 ScenePresence presence = World.GetScenePresence(agentId);
4173 if (presence != null) 4591 if (presence != null && presence.PresenceType != PresenceType.Npc)
4174 { 4592 {
4593 // agent must not be a god
4594 if (presence.UserLevel >= 200) return;
4595
4175 // agent must be over the owners land 4596 // agent must be over the owners land
4176 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4597 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4177 { 4598 {
4178 World.TeleportClientHome(agentId, presence.ControllingClient); 4599 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4600 {
4601 // They can't be teleported home for some reason
4602 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4603 if (regionInfo != null)
4604 {
4605 World.RequestTeleportLocation(
4606 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4607 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4608 }
4609 }
4179 } 4610 }
4180 } 4611 }
4181 } 4612 }
@@ -4281,7 +4712,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4281 UUID av = new UUID(); 4712 UUID av = new UUID();
4282 if (!UUID.TryParse(agent,out av)) 4713 if (!UUID.TryParse(agent,out av))
4283 { 4714 {
4284 LSLError("First parameter to llDialog needs to be a key");
4285 return; 4715 return;
4286 } 4716 }
4287 4717
@@ -4313,10 +4743,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4313 public void llCollisionSound(string impact_sound, double impact_volume) 4743 public void llCollisionSound(string impact_sound, double impact_volume)
4314 { 4744 {
4315 m_host.AddScriptLPS(1); 4745 m_host.AddScriptLPS(1);
4316 4746
4747 if(impact_sound == "")
4748 {
4749 m_host.CollisionSoundVolume = (float)impact_volume;
4750 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4751 m_host.CollisionSoundType = 0;
4752 return;
4753 }
4317 // TODO: Parameter check logic required. 4754 // TODO: Parameter check logic required.
4318 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 4755 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4319 m_host.CollisionSoundVolume = (float)impact_volume; 4756 m_host.CollisionSoundVolume = (float)impact_volume;
4757 m_host.CollisionSoundType = 1;
4320 } 4758 }
4321 4759
4322 public LSL_String llGetAnimation(string id) 4760 public LSL_String llGetAnimation(string id)
@@ -4330,14 +4768,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4330 4768
4331 if (m_host.RegionHandle == presence.RegionHandle) 4769 if (m_host.RegionHandle == presence.RegionHandle)
4332 { 4770 {
4333 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4334
4335 if (presence != null) 4771 if (presence != null)
4336 { 4772 {
4337 AnimationSet currentAnims = presence.Animator.Animations; 4773 if (presence.SitGround)
4338 string currentAnimationState = String.Empty; 4774 return "Sitting on Ground";
4339 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4775 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4340 return currentAnimationState; 4776 return "Sitting";
4777
4778 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4779 string lslMovementAnimation;
4780
4781 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4782 return lslMovementAnimation;
4341 } 4783 }
4342 } 4784 }
4343 4785
@@ -4485,7 +4927,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4485 { 4927 {
4486 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4928 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4487 float distance_term = distance * distance * distance; // Script Energy 4929 float distance_term = distance * distance * distance; // Script Energy
4488 float pusher_mass = m_host.GetMass(); 4930 // use total object mass and not part
4931 float pusher_mass = m_host.ParentGroup.GetMass();
4489 4932
4490 float PUSH_ATTENUATION_DISTANCE = 17f; 4933 float PUSH_ATTENUATION_DISTANCE = 17f;
4491 float PUSH_ATTENUATION_SCALE = 5f; 4934 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4739,6 +5182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4739 { 5182 {
4740 return item.AssetID.ToString(); 5183 return item.AssetID.ToString();
4741 } 5184 }
5185 m_host.TaskInventory.LockItemsForRead(false);
4742 5186
4743 return UUID.Zero.ToString(); 5187 return UUID.Zero.ToString();
4744 } 5188 }
@@ -4891,14 +5335,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4891 { 5335 {
4892 m_host.AddScriptLPS(1); 5336 m_host.AddScriptLPS(1);
4893 5337
4894 if (src == null) 5338 return src.Length;
4895 {
4896 return 0;
4897 }
4898 else
4899 {
4900 return src.Length;
4901 }
4902 } 5339 }
4903 5340
4904 public LSL_Integer llList2Integer(LSL_List src, int index) 5341 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4969,7 +5406,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4969 else if (src.Data[index] is LSL_Float) 5406 else if (src.Data[index] is LSL_Float)
4970 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5407 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4971 else if (src.Data[index] is LSL_String) 5408 else if (src.Data[index] is LSL_String)
4972 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5409 {
5410 string str = ((LSL_String) src.Data[index]).m_string;
5411 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5412 if (m != Match.Empty)
5413 {
5414 str = m.Value;
5415 double d = 0.0;
5416 if (!Double.TryParse(str, out d))
5417 return 0.0;
5418
5419 return d;
5420 }
5421 return 0.0;
5422 }
4973 return Convert.ToDouble(src.Data[index]); 5423 return Convert.ToDouble(src.Data[index]);
4974 } 5424 }
4975 catch (FormatException) 5425 catch (FormatException)
@@ -5011,7 +5461,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5011 // for completion and should LSL_Key ever be implemented 5461 // for completion and should LSL_Key ever be implemented
5012 // as it's own struct 5462 // as it's own struct
5013 else if (!(src.Data[index] is LSL_String || 5463 else if (!(src.Data[index] is LSL_String ||
5014 src.Data[index] is LSL_Key)) 5464 src.Data[index] is LSL_Key ||
5465 src.Data[index] is String))
5015 { 5466 {
5016 return ""; 5467 return "";
5017 } 5468 }
@@ -5269,7 +5720,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5269 } 5720 }
5270 } 5721 }
5271 } 5722 }
5272 else { 5723 else
5724 {
5273 object[] array = new object[src.Length]; 5725 object[] array = new object[src.Length];
5274 Array.Copy(src.Data, 0, array, 0, src.Length); 5726 Array.Copy(src.Data, 0, array, 0, src.Length);
5275 result = new LSL_List(array); 5727 result = new LSL_List(array);
@@ -5376,7 +5828,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5376 public LSL_Integer llGetRegionAgentCount() 5828 public LSL_Integer llGetRegionAgentCount()
5377 { 5829 {
5378 m_host.AddScriptLPS(1); 5830 m_host.AddScriptLPS(1);
5379 return new LSL_Integer(World.GetRootAgentCount()); 5831
5832 int count = 0;
5833 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5834 count++;
5835 });
5836
5837 return new LSL_Integer(count);
5380 } 5838 }
5381 5839
5382 public LSL_Vector llGetRegionCorner() 5840 public LSL_Vector llGetRegionCorner()
@@ -5617,6 +6075,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5617 flags |= ScriptBaseClass.AGENT_AWAY; 6075 flags |= ScriptBaseClass.AGENT_AWAY;
5618 } 6076 }
5619 6077
6078 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6079 UUID[] anims = agent.Animator.GetAnimationArray();
6080 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6081 {
6082 flags |= ScriptBaseClass.AGENT_BUSY;
6083 }
6084
5620 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6085 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5621 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6086 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5622 { 6087 {
@@ -5664,6 +6129,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5664 flags |= ScriptBaseClass.AGENT_SITTING; 6129 flags |= ScriptBaseClass.AGENT_SITTING;
5665 } 6130 }
5666 6131
6132 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6133 {
6134 flags |= ScriptBaseClass.AGENT_MALE;
6135 }
6136
5667 return flags; 6137 return flags;
5668 } 6138 }
5669 6139
@@ -5809,9 +6279,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5809 6279
5810 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6280 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5811 6281
5812 foreach (SceneObjectPart part in parts) 6282 try
6283 {
6284 foreach (SceneObjectPart part in parts)
6285 {
6286 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6287 }
6288 }
6289 finally
5813 { 6290 {
5814 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5815 } 6291 }
5816 } 6292 }
5817 6293
@@ -5865,13 +6341,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5865 6341
5866 if (m_host.OwnerID == land.LandData.OwnerID) 6342 if (m_host.OwnerID == land.LandData.OwnerID)
5867 { 6343 {
5868 World.TeleportClientHome(agentID, presence.ControllingClient); 6344 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6345 presence.TeleportWithMomentum(p, null);
6346 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5869 } 6347 }
5870 } 6348 }
5871 } 6349 }
5872 ScriptSleep(5000); 6350 ScriptSleep(5000);
5873 } 6351 }
5874 6352
6353 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6354 {
6355 return ParseString2List(str, separators, in_spacers, false);
6356 }
6357
5875 public LSL_Integer llOverMyLand(string id) 6358 public LSL_Integer llOverMyLand(string id)
5876 { 6359 {
5877 m_host.AddScriptLPS(1); 6360 m_host.AddScriptLPS(1);
@@ -5924,26 +6407,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5924 } 6407 }
5925 else 6408 else
5926 { 6409 {
5927 agentSize = GetAgentSize(avatar); 6410// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6411 Vector3 s = avatar.Appearance.AvatarSize;
6412 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5928 } 6413 }
5929
5930 return agentSize; 6414 return agentSize;
5931 } 6415 }
5932 6416
5933 public LSL_Integer llSameGroup(string agent) 6417 public LSL_Integer llSameGroup(string id)
5934 { 6418 {
5935 m_host.AddScriptLPS(1); 6419 m_host.AddScriptLPS(1);
5936 UUID agentId = new UUID(); 6420 UUID uuid = new UUID();
5937 if (!UUID.TryParse(agent, out agentId)) 6421 if (!UUID.TryParse(id, out uuid))
5938 return new LSL_Integer(0);
5939 ScenePresence presence = World.GetScenePresence(agentId);
5940 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5941 return new LSL_Integer(0); 6422 return new LSL_Integer(0);
5942 IClientAPI client = presence.ControllingClient; 6423
5943 if (m_host.GroupID == client.ActiveGroupId) 6424 // Check if it's a group key
6425 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5944 return new LSL_Integer(1); 6426 return new LSL_Integer(1);
5945 else 6427
6428 // We got passed a UUID.Zero
6429 if (uuid == UUID.Zero)
5946 return new LSL_Integer(0); 6430 return new LSL_Integer(0);
6431
6432 // Handle the case where id names an avatar
6433 ScenePresence presence = World.GetScenePresence(uuid);
6434 if (presence != null)
6435 {
6436 if (presence.IsChildAgent)
6437 return new LSL_Integer(0);
6438
6439 IClientAPI client = presence.ControllingClient;
6440 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6441 return new LSL_Integer(1);
6442
6443 return new LSL_Integer(0);
6444 }
6445
6446 // Handle object case
6447 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6448 if (part != null)
6449 {
6450 // This will handle both deed and non-deed and also the no
6451 // group case
6452 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6453 return new LSL_Integer(1);
6454
6455 return new LSL_Integer(0);
6456 }
6457
6458 return new LSL_Integer(0);
5947 } 6459 }
5948 6460
5949 public void llUnSit(string id) 6461 public void llUnSit(string id)
@@ -6502,6 +7014,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6502 7014
6503 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7015 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6504 { 7016 {
7017 // LSL quaternions can normalize to 0, normal Quaternions can't.
7018 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7019 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7020
6505 part.SitTargetPosition = offset; 7021 part.SitTargetPosition = offset;
6506 part.SitTargetOrientation = rot; 7022 part.SitTargetOrientation = rot;
6507 part.ParentGroup.HasGroupChanged = true; 7023 part.ParentGroup.HasGroupChanged = true;
@@ -6688,30 +7204,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6688 UUID av = new UUID(); 7204 UUID av = new UUID();
6689 if (!UUID.TryParse(avatar,out av)) 7205 if (!UUID.TryParse(avatar,out av))
6690 { 7206 {
6691 LSLError("First parameter to llDialog needs to be a key"); 7207 //LSLError("First parameter to llDialog needs to be a key");
6692 return; 7208 return;
6693 } 7209 }
6694 if (buttons.Length < 1) 7210 if (buttons.Length < 1)
6695 { 7211 {
6696 LSLError("No less than 1 button can be shown"); 7212 buttons.Add("OK");
6697 return;
6698 } 7213 }
6699 if (buttons.Length > 12) 7214 if (buttons.Length > 12)
6700 { 7215 {
6701 LSLError("No more than 12 buttons can be shown"); 7216 ShoutError("button list too long, must be 12 or fewer entries");
6702 return;
6703 } 7217 }
6704 string[] buts = new string[buttons.Length]; 7218 int length = buttons.Length;
6705 for (int i = 0; i < buttons.Length; i++) 7219 if (length > 12)
7220 length = 12;
7221
7222 string[] buts = new string[length];
7223 for (int i = 0; i < length; i++)
6706 { 7224 {
6707 if (buttons.Data[i].ToString() == String.Empty) 7225 if (buttons.Data[i].ToString() == String.Empty)
6708 { 7226 {
6709 LSLError("button label cannot be blank"); 7227 ShoutError("button label cannot be blank");
6710 return; 7228 return;
6711 } 7229 }
6712 if (buttons.Data[i].ToString().Length > 24) 7230 if (buttons.Data[i].ToString().Length > 24)
6713 { 7231 {
6714 LSLError("button label cannot be longer than 24 characters"); 7232 ShoutError("button label cannot be longer than 24 characters");
6715 return; 7233 return;
6716 } 7234 }
6717 buts[i] = buttons.Data[i].ToString(); 7235 buts[i] = buttons.Data[i].ToString();
@@ -6778,9 +7296,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6778 return; 7296 return;
6779 } 7297 }
6780 7298
6781 // the rest of the permission checks are done in RezScript, so check the pin there as well 7299 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6782 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7300 if (dest != null)
7301 {
7302 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7303 {
7304 // the rest of the permission checks are done in RezScript, so check the pin there as well
7305 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6783 7306
7307 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7308 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7309 }
7310 }
6784 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7311 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6785 ScriptSleep(3000); 7312 ScriptSleep(3000);
6786 } 7313 }
@@ -6854,19 +7381,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6854 public LSL_String llMD5String(string src, int nonce) 7381 public LSL_String llMD5String(string src, int nonce)
6855 { 7382 {
6856 m_host.AddScriptLPS(1); 7383 m_host.AddScriptLPS(1);
6857 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7384 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6858 } 7385 }
6859 7386
6860 public LSL_String llSHA1String(string src) 7387 public LSL_String llSHA1String(string src)
6861 { 7388 {
6862 m_host.AddScriptLPS(1); 7389 m_host.AddScriptLPS(1);
6863 return Util.SHA1Hash(src).ToLower(); 7390 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6864 } 7391 }
6865 7392
6866 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7393 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6867 { 7394 {
6868 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7395 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6869 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7396 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7397 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7398 return shapeBlock;
6870 7399
6871 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7400 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6872 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7401 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6971,6 +7500,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6971 // Prim type box, cylinder and prism. 7500 // Prim type box, cylinder and prism.
6972 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) 7501 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)
6973 { 7502 {
7503 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7504 return;
7505
6974 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7506 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6975 ObjectShapePacket.ObjectDataBlock shapeBlock; 7507 ObjectShapePacket.ObjectDataBlock shapeBlock;
6976 7508
@@ -7024,6 +7556,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7024 // Prim type sphere. 7556 // Prim type sphere.
7025 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7557 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7026 { 7558 {
7559 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7560 return;
7561
7027 ObjectShapePacket.ObjectDataBlock shapeBlock; 7562 ObjectShapePacket.ObjectDataBlock shapeBlock;
7028 7563
7029 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7564 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7065,6 +7600,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7065 // Prim type torus, tube and ring. 7600 // Prim type torus, tube and ring.
7066 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) 7601 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)
7067 { 7602 {
7603 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7604 return;
7605
7068 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7606 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7069 ObjectShapePacket.ObjectDataBlock shapeBlock; 7607 ObjectShapePacket.ObjectDataBlock shapeBlock;
7070 7608
@@ -7200,6 +7738,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7200 // Prim type sculpt. 7738 // Prim type sculpt.
7201 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7739 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7202 { 7740 {
7741 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7742 return;
7743
7203 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7744 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7204 UUID sculptId; 7745 UUID sculptId;
7205 7746
@@ -7222,7 +7763,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7222 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7763 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7223 { 7764 {
7224 // default 7765 // default
7225 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7766 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7226 } 7767 }
7227 7768
7228 part.Shape.SetSculptProperties((byte)type, sculptId); 7769 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7239,48 +7780,130 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7239 ScriptSleep(200); 7780 ScriptSleep(200);
7240 } 7781 }
7241 7782
7242 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7783 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7243 { 7784 {
7244 m_host.AddScriptLPS(1); 7785 m_host.AddScriptLPS(1);
7245 7786
7246 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7787 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7788 }
7247 7789
7248 ScriptSleep(200); 7790 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7791 {
7792 List<object> parts = new List<object>();
7793 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7794 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7795 foreach (SceneObjectPart p in prims)
7796 parts.Add(p);
7797 foreach (ScenePresence p in avatars)
7798 parts.Add(p);
7799
7800 LSL_List remaining = null;
7801 uint rulesParsed = 0;
7802
7803 if (parts.Count > 0)
7804 {
7805 foreach (object part in parts)
7806 {
7807 if (part is SceneObjectPart)
7808 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7809 else
7810 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7811 }
7812
7813 while ((object)remaining != null && remaining.Length > 2)
7814 {
7815 linknumber = remaining.GetLSLIntegerItem(0);
7816 rules = remaining.GetSublist(1, -1);
7817 parts.Clear();
7818 prims = GetLinkParts(linknumber);
7819 avatars = GetLinkAvatars(linknumber);
7820 foreach (SceneObjectPart p in prims)
7821 parts.Add(p);
7822 foreach (ScenePresence p in avatars)
7823 parts.Add(p);
7824
7825 remaining = null;
7826 foreach (object part in parts)
7827 {
7828 if (part is SceneObjectPart)
7829 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7830 else
7831 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7832 }
7833 }
7834 }
7249 } 7835 }
7250 7836
7251 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7837 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7838 float material_density, float material_friction,
7839 float material_restitution, float material_gravity_modifier)
7252 { 7840 {
7253 m_host.AddScriptLPS(1); 7841 ExtraPhysicsData physdata = new ExtraPhysicsData();
7842 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7843 physdata.Density = part.Density;
7844 physdata.Friction = part.Friction;
7845 physdata.Bounce = part.Restitution;
7846 physdata.GravitationModifier = part.GravityModifier;
7254 7847
7255 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7848 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7849 physdata.Density = material_density;
7850 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7851 physdata.Friction = material_friction;
7852 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7853 physdata.Bounce = material_restitution;
7854 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7855 physdata.GravitationModifier = material_gravity_modifier;
7856
7857 part.UpdateExtraPhysics(physdata);
7256 } 7858 }
7257 7859
7258 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7860 public void llSetPhysicsMaterial(int material_bits,
7861 float material_gravity_modifier, float material_restitution,
7862 float material_friction, float material_density)
7259 { 7863 {
7260 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7864 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7865 }
7261 7866
7262 LSL_List remaining = null; 7867 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7263 uint rulesParsed = 0; 7868 {
7869 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7870 llSetLinkPrimitiveParamsFast(linknumber, rules);
7871 ScriptSleep(200);
7872 }
7264 7873
7265 foreach (SceneObjectPart part in parts) 7874 // vector up using libomv (c&p from sop )
7266 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7875 // vector up rotated by r
7876 private Vector3 Zrot(Quaternion r)
7877 {
7878 double x, y, z, m;
7267 7879
7268 while (remaining != null && remaining.Length > 2) 7880 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7881 if (Math.Abs(1.0 - m) > 0.000001)
7269 { 7882 {
7270 linknumber = remaining.GetLSLIntegerItem(0); 7883 m = 1.0 / Math.Sqrt(m);
7271 rules = remaining.GetSublist(1, -1); 7884 r.X *= (float)m;
7272 parts = GetLinkParts(linknumber); 7885 r.Y *= (float)m;
7273 7886 r.Z *= (float)m;
7274 foreach (SceneObjectPart part in parts) 7887 r.W *= (float)m;
7275 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7276 } 7888 }
7889
7890 x = 2 * (r.X * r.Z + r.Y * r.W);
7891 y = 2 * (-r.X * r.W + r.Y * r.Z);
7892 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7893
7894 return new Vector3((float)x, (float)y, (float)z);
7277 } 7895 }
7278 7896
7279 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7897 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7280 { 7898 {
7899 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7900 return null;
7901
7281 int idx = 0; 7902 int idx = 0;
7282 int idxStart = 0; 7903 int idxStart = 0;
7283 7904
7905 SceneObjectGroup parentgrp = part.ParentGroup;
7906
7284 bool positionChanged = false; 7907 bool positionChanged = false;
7285 LSL_Vector currentPosition = GetPartLocalPos(part); 7908 LSL_Vector currentPosition = GetPartLocalPos(part);
7286 7909
@@ -7305,8 +7928,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7305 return null; 7928 return null;
7306 7929
7307 v=rules.GetVector3Item(idx++); 7930 v=rules.GetVector3Item(idx++);
7931 if (part.IsRoot && !part.ParentGroup.IsAttachment)
7932 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
7933 else
7934 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7308 positionChanged = true; 7935 positionChanged = true;
7309 currentPosition = GetSetPosTarget(part, v, currentPosition);
7310 7936
7311 break; 7937 break;
7312 case (int)ScriptBaseClass.PRIM_SIZE: 7938 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7323,7 +7949,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7323 7949
7324 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7950 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7325 // try to let this work as in SL... 7951 // try to let this work as in SL...
7326 if (part.ParentID == 0) 7952 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7327 { 7953 {
7328 // special case: If we are root, rotate complete SOG to new rotation 7954 // special case: If we are root, rotate complete SOG to new rotation
7329 SetRot(part, q); 7955 SetRot(part, q);
@@ -7583,7 +8209,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7583 return null; 8209 return null;
7584 8210
7585 string ph = rules.Data[idx++].ToString(); 8211 string ph = rules.Data[idx++].ToString();
7586 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8212 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7587 8213
7588 break; 8214 break;
7589 8215
@@ -7617,12 +8243,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7617 8243
7618 break; 8244 break;
7619 8245
8246 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8247 if (remain < 5)
8248 return null;
8249
8250 int material_bits = rules.GetLSLIntegerItem(idx++);
8251 float material_density = (float)rules.GetLSLFloatItem(idx++);
8252 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8253 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8254 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8255
8256 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8257
8258 break;
8259
7620 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8260 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7621 if (remain < 1) 8261 if (remain < 1)
7622 return null; 8262 return null;
7623 string temp = rules.Data[idx++].ToString(); 8263 string temp = rules.Data[idx++].ToString();
7624 8264
7625 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8265 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7626 8266
7627 break; 8267 break;
7628 8268
@@ -7696,14 +8336,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7696 if (part.ParentGroup.RootPart == part) 8336 if (part.ParentGroup.RootPart == part)
7697 { 8337 {
7698 SceneObjectGroup parent = part.ParentGroup; 8338 SceneObjectGroup parent = part.ParentGroup;
7699 parent.UpdateGroupPosition(currentPosition); 8339 Util.FireAndForget(delegate(object x) {
8340 parent.UpdateGroupPosition(currentPosition);
8341 });
7700 } 8342 }
7701 else 8343 else
7702 { 8344 {
7703 part.OffsetPosition = currentPosition; 8345 part.OffsetPosition = currentPosition;
7704 SceneObjectGroup parent = part.ParentGroup; 8346// SceneObjectGroup parent = part.ParentGroup;
7705 parent.HasGroupChanged = true; 8347// parent.HasGroupChanged = true;
7706 parent.ScheduleGroupForTerseUpdate(); 8348// parent.ScheduleGroupForTerseUpdate();
8349 part.ScheduleTerseUpdate();
7707 } 8350 }
7708 } 8351 }
7709 } 8352 }
@@ -7741,10 +8384,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7741 8384
7742 public LSL_String llXorBase64Strings(string str1, string str2) 8385 public LSL_String llXorBase64Strings(string str1, string str2)
7743 { 8386 {
7744 m_host.AddScriptLPS(1); 8387 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7745 Deprecated("llXorBase64Strings"); 8388
7746 ScriptSleep(300); 8389 ScriptSleep(300);
7747 return String.Empty; 8390 m_host.AddScriptLPS(1);
8391
8392 if (str1 == String.Empty)
8393 return String.Empty;
8394 if (str2 == String.Empty)
8395 return str1;
8396
8397 int len = str2.Length;
8398 if ((len % 4) != 0) // LL is EVIL!!!!
8399 {
8400 while (str2.EndsWith("="))
8401 str2 = str2.Substring(0, str2.Length - 1);
8402
8403 len = str2.Length;
8404 int mod = len % 4;
8405
8406 if (mod == 1)
8407 str2 = str2.Substring(0, str2.Length - 1);
8408 else if (mod == 2)
8409 str2 += "==";
8410 else if (mod == 3)
8411 str2 += "=";
8412 }
8413
8414 byte[] data1;
8415 byte[] data2;
8416 try
8417 {
8418 data1 = Convert.FromBase64String(str1);
8419 data2 = Convert.FromBase64String(str2);
8420 }
8421 catch (Exception)
8422 {
8423 return new LSL_String(String.Empty);
8424 }
8425
8426 // For cases where the decoded length of s2 is greater
8427 // than the decoded length of s1, simply perform a normal
8428 // decode and XOR
8429 //
8430 if (data2.Length >= data1.Length)
8431 {
8432 for (int pos = 0 ; pos < data1.Length ; pos++ )
8433 data1[pos] ^= data2[pos];
8434
8435 return Convert.ToBase64String(data1);
8436 }
8437
8438 // Remove padding
8439 while (str1.EndsWith("="))
8440 str1 = str1.Substring(0, str1.Length - 1);
8441 while (str2.EndsWith("="))
8442 str2 = str2.Substring(0, str2.Length - 1);
8443
8444 byte[] d1 = new byte[str1.Length];
8445 byte[] d2 = new byte[str2.Length];
8446
8447 for (int i = 0 ; i < str1.Length ; i++)
8448 {
8449 int idx = b64.IndexOf(str1.Substring(i, 1));
8450 if (idx == -1)
8451 idx = 0;
8452 d1[i] = (byte)idx;
8453 }
8454
8455 for (int i = 0 ; i < str2.Length ; i++)
8456 {
8457 int idx = b64.IndexOf(str2.Substring(i, 1));
8458 if (idx == -1)
8459 idx = 0;
8460 d2[i] = (byte)idx;
8461 }
8462
8463 string output = String.Empty;
8464
8465 for (int pos = 0 ; pos < d1.Length ; pos++)
8466 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8467
8468 while (output.Length % 3 > 0)
8469 output += "=";
8470
8471 return output;
7748 } 8472 }
7749 8473
7750 public void llRemoteDataSetRegion() 8474 public void llRemoteDataSetRegion()
@@ -7869,8 +8593,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7869 public LSL_Integer llGetNumberOfPrims() 8593 public LSL_Integer llGetNumberOfPrims()
7870 { 8594 {
7871 m_host.AddScriptLPS(1); 8595 m_host.AddScriptLPS(1);
7872 8596 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7873 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8597
8598 return m_host.ParentGroup.PrimCount + avatarCount;
7874 } 8599 }
7875 8600
7876 /// <summary> 8601 /// <summary>
@@ -7885,55 +8610,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7885 m_host.AddScriptLPS(1); 8610 m_host.AddScriptLPS(1);
7886 UUID objID = UUID.Zero; 8611 UUID objID = UUID.Zero;
7887 LSL_List result = new LSL_List(); 8612 LSL_List result = new LSL_List();
8613
8614 // If the ID is not valid, return null result
7888 if (!UUID.TryParse(obj, out objID)) 8615 if (!UUID.TryParse(obj, out objID))
7889 { 8616 {
7890 result.Add(new LSL_Vector()); 8617 result.Add(new LSL_Vector());
7891 result.Add(new LSL_Vector()); 8618 result.Add(new LSL_Vector());
7892 return result; 8619 return result;
7893 } 8620 }
8621
8622 // Check if this is an attached prim. If so, replace
8623 // the UUID with the avatar UUID and report it's bounding box
8624 SceneObjectPart part = World.GetSceneObjectPart(objID);
8625 if (part != null && part.ParentGroup.IsAttachment)
8626 objID = part.ParentGroup.AttachedAvatar;
8627
8628 // Find out if this is an avatar ID. If so, return it's box
7894 ScenePresence presence = World.GetScenePresence(objID); 8629 ScenePresence presence = World.GetScenePresence(objID);
7895 if (presence != null) 8630 if (presence != null)
7896 { 8631 {
7897 if (presence.ParentID == 0) // not sat on an object 8632 // As per LSL Wiki, there is no difference between sitting
8633 // and standing avatar since server 1.36
8634 LSL_Vector lower;
8635 LSL_Vector upper;
8636
8637 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8638
8639 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8640 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8641/*
7898 { 8642 {
7899 LSL_Vector lower; 8643 // This is for ground sitting avatars
7900 LSL_Vector upper; 8644 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7901 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8645 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7902 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8646 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7903 {
7904 // This is for ground sitting avatars
7905 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7906 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7907 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7908 }
7909 else
7910 {
7911 // This is for standing/flying avatars
7912 float height = presence.Appearance.AvatarHeight / 2.0f;
7913 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7914 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7915 }
7916 result.Add(lower);
7917 result.Add(upper);
7918 return result;
7919 } 8647 }
7920 else 8648 else
7921 { 8649 {
7922 // sitting on an object so we need the bounding box of that 8650 // This is for standing/flying avatars
7923 // which should include the avatar so set the UUID to the 8651 float height = presence.Appearance.AvatarHeight / 2.0f;
7924 // UUID of the object the avatar is sat on and allow it to fall through 8652 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7925 // to processing an object 8653 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7926 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7927 objID = p.UUID;
7928 } 8654 }
8655
8656 // Adjust to the documented error offsets (see LSL Wiki)
8657 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8658 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8659*/
8660 {
8661 // This is for ground sitting avatars TODO!
8662 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8663 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
8664 }
8665 else
8666 {
8667 // This is for standing/flying avatars
8668 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8669 upper = new LSL_Vector(box.X, box.Y, box.Z);
8670 }
8671
8672 if (lower.x > upper.x)
8673 lower.x = upper.x;
8674 if (lower.y > upper.y)
8675 lower.y = upper.y;
8676 if (lower.z > upper.z)
8677 lower.z = upper.z;
8678
8679 result.Add(lower);
8680 result.Add(upper);
8681 return result;
7929 } 8682 }
7930 SceneObjectPart part = World.GetSceneObjectPart(objID); 8683
8684 part = World.GetSceneObjectPart(objID);
7931 // Currently only works for single prims without a sitting avatar 8685 // Currently only works for single prims without a sitting avatar
7932 if (part != null) 8686 if (part != null)
7933 { 8687 {
7934 Vector3 halfSize = part.Scale / 2.0f; 8688 float minX;
7935 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8689 float maxX;
7936 LSL_Vector upper = new LSL_Vector(halfSize); 8690 float minY;
8691 float maxY;
8692 float minZ;
8693 float maxZ;
8694
8695 // This BBox is in sim coordinates, with the offset being
8696 // a contained point.
8697 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8698 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8699
8700 minX -= offsets[0].X;
8701 maxX -= offsets[0].X;
8702 minY -= offsets[0].Y;
8703 maxY -= offsets[0].Y;
8704 minZ -= offsets[0].Z;
8705 maxZ -= offsets[0].Z;
8706
8707 LSL_Vector lower;
8708 LSL_Vector upper;
8709
8710 // Adjust to the documented error offsets (see LSL Wiki)
8711 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8712 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8713
8714 if (lower.x > upper.x)
8715 lower.x = upper.x;
8716 if (lower.y > upper.y)
8717 lower.y = upper.y;
8718 if (lower.z > upper.z)
8719 lower.z = upper.z;
8720
7937 result.Add(lower); 8721 result.Add(lower);
7938 result.Add(upper); 8722 result.Add(upper);
7939 return result; 8723 return result;
@@ -7950,224 +8734,74 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7950 return new LSL_Vector(m_host.GetGeometricCenter()); 8734 return new LSL_Vector(m_host.GetGeometricCenter());
7951 } 8735 }
7952 8736
7953 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 8737 public LSL_List llGetPrimitiveParams(LSL_List rules)
7954 { 8738 {
7955 LSL_List result = new LSL_List(); 8739 m_host.AddScriptLPS(1);
7956 LSL_List remaining = null;
7957 8740
7958 while (true) 8741 LSL_List result = new LSL_List();
7959 {
7960 if (entity is SceneObjectPart)
7961 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result);
7962 else
7963 remaining = GetAgentParams((ScenePresence)entity, rules, ref result);
7964 8742
7965 if (remaining == null || remaining.Length <= 2) 8743 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
7966 return result;
7967 8744
8745 while ((object)remaining != null && remaining.Length > 2)
8746 {
7968 int linknumber = remaining.GetLSLIntegerItem(0); 8747 int linknumber = remaining.GetLSLIntegerItem(0);
7969 rules = remaining.GetSublist(1, -1); 8748 rules = remaining.GetSublist(1, -1);
7970 entity = GetLinkEntity(linknumber); 8749 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7971 }
7972 }
7973 8750
7974 public LSL_List llGetPrimitiveParams(LSL_List rules) 8751 foreach (SceneObjectPart part in parts)
7975 { 8752 remaining = GetPrimParams(part, rules, ref result);
7976 m_host.AddScriptLPS(1); 8753 }
7977 8754
7978 return GetEntityParams(m_host, rules); 8755 return result;
7979 } 8756 }
7980 8757
7981 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8758 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
7982 { 8759 {
7983 m_host.AddScriptLPS(1); 8760 m_host.AddScriptLPS(1);
7984 8761
7985 return GetEntityParams(GetLinkEntity(linknumber), rules); 8762 // acording to SL wiki this must indicate a single link number or link_root or link_this.
7986 } 8763 // keep other options as before
7987 8764
7988 public LSL_Vector GetAgentSize(ScenePresence sp) 8765 List<SceneObjectPart> parts;
7989 { 8766 List<ScenePresence> avatars;
7990 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); 8767
7991 } 8768 LSL_List res = new LSL_List();
8769 LSL_List remaining = null;
7992 8770
7993 /// <summary> 8771 while (rules.Length > 0)
7994 /// Gets params for a seated avatar in a linkset.
7995 /// </summary>
7996 /// <returns></returns>
7997 /// <param name='sp'></param>
7998 /// <param name='rules'></param>
7999 /// <param name='res'></param>
8000 public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res)
8001 {
8002 int idx = 0;
8003 while (idx < rules.Length)
8004 { 8772 {
8005 int code = (int)rules.GetLSLIntegerItem(idx++); 8773 parts = GetLinkParts(linknumber);
8006 int remain = rules.Length-idx; 8774 avatars = GetLinkAvatars(linknumber);
8007 8775
8008 switch (code) 8776 remaining = null;
8777 foreach (SceneObjectPart part in parts)
8009 { 8778 {
8010 case (int)ScriptBaseClass.PRIM_MATERIAL: 8779 remaining = GetPrimParams(part, rules, ref res);
8011 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 8780 }
8012 break; 8781 foreach (ScenePresence avatar in avatars)
8013 8782 {
8014 case (int)ScriptBaseClass.PRIM_PHYSICS: 8783 remaining = GetPrimParams(avatar, rules, ref res);
8015 res.Add(ScriptBaseClass.FALSE); 8784 }
8016 break;
8017
8018 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8019 res.Add(ScriptBaseClass.FALSE);
8020 break;
8021
8022 case (int)ScriptBaseClass.PRIM_PHANTOM:
8023 res.Add(ScriptBaseClass.FALSE);
8024 break;
8025
8026 case (int)ScriptBaseClass.PRIM_POSITION:
8027 res.Add(new LSL_Vector(sp.AbsolutePosition));
8028 break;
8029
8030 case (int)ScriptBaseClass.PRIM_SIZE:
8031 res.Add(GetAgentSize(sp));
8032 break;
8033
8034 case (int)ScriptBaseClass.PRIM_ROTATION:
8035 res.Add(sp.GetWorldRotation());
8036 break;
8037
8038 case (int)ScriptBaseClass.PRIM_TYPE:
8039 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8040 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8041 res.Add(new LSL_Vector(0, 1, 0));
8042 res.Add(new LSL_Float(0));
8043 res.Add(new LSL_Vector(0, 0, 0));
8044 res.Add(new LSL_Vector(1, 1, 0));
8045 res.Add(new LSL_Vector(0, 0, 0));
8046 break;
8047
8048 case (int)ScriptBaseClass.PRIM_TEXTURE:
8049 if (remain < 1)
8050 return null;
8051
8052 int face = (int)rules.GetLSLIntegerItem(idx++);
8053 if (face > 21)
8054 break;
8055
8056 res.Add(new LSL_String(""));
8057 res.Add(ScriptBaseClass.ZERO_VECTOR);
8058 res.Add(ScriptBaseClass.ZERO_VECTOR);
8059 res.Add(new LSL_Float(0));
8060 break;
8061
8062 case (int)ScriptBaseClass.PRIM_COLOR:
8063 if (remain < 1)
8064 return null;
8065
8066 face = (int)rules.GetLSLIntegerItem(idx++);
8067 if (face > 21)
8068 break;
8069
8070 res.Add(ScriptBaseClass.ZERO_VECTOR);
8071 res.Add(new LSL_Float(0));
8072 break;
8073
8074 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8075 if (remain < 1)
8076 return null;
8077
8078 face = (int)rules.GetLSLIntegerItem(idx++);
8079 if (face > 21)
8080 break;
8081
8082 res.Add(ScriptBaseClass.PRIM_SHINY_NONE);
8083 res.Add(ScriptBaseClass.PRIM_BUMP_NONE);
8084 break;
8085
8086 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8087 if (remain < 1)
8088 return null;
8089
8090 face = (int)rules.GetLSLIntegerItem(idx++);
8091 if (face > 21)
8092 break;
8093
8094 res.Add(ScriptBaseClass.FALSE);
8095 break;
8096
8097 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8098 res.Add(ScriptBaseClass.FALSE);
8099 res.Add(new LSL_Integer(0));
8100 res.Add(new LSL_Float(0));
8101 res.Add(new LSL_Float(0));
8102 res.Add(new LSL_Float(0));
8103 res.Add(new LSL_Float(0));
8104 res.Add(ScriptBaseClass.ZERO_VECTOR);
8105 break;
8106
8107 case (int)ScriptBaseClass.PRIM_TEXGEN:
8108 if (remain < 1)
8109 return null;
8110
8111 face = (int)rules.GetLSLIntegerItem(idx++);
8112 if (face > 21)
8113 break;
8114
8115 res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT);
8116 break;
8117
8118 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8119 res.Add(ScriptBaseClass.FALSE);
8120 res.Add(ScriptBaseClass.ZERO_VECTOR);
8121 res.Add(ScriptBaseClass.ZERO_VECTOR);
8122 break;
8123
8124 case (int)ScriptBaseClass.PRIM_GLOW:
8125 if (remain < 1)
8126 return null;
8127
8128 face = (int)rules.GetLSLIntegerItem(idx++);
8129 if (face > 21)
8130 break;
8131
8132 res.Add(new LSL_Float(0));
8133 break;
8134
8135 case (int)ScriptBaseClass.PRIM_TEXT:
8136 res.Add(new LSL_String(""));
8137 res.Add(ScriptBaseClass.ZERO_VECTOR);
8138 res.Add(new LSL_Float(1));
8139 break;
8140
8141 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8142 res.Add(new LSL_Rotation(sp.Rotation));
8143 break;
8144
8145 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8146 res.Add(new LSL_Vector(sp.OffsetPosition));
8147 break;
8148
8149 case (int)ScriptBaseClass.PRIM_SLICE:
8150 res.Add(new LSL_Vector(0, 1, 0));
8151 break;
8152
8153 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8154 if(remain < 3)
8155 return null;
8156 8785
8157 return rules.GetSublist(idx, -1); 8786 if ((object)remaining != null && remaining.Length > 0)
8787 {
8788 linknumber = remaining.GetLSLIntegerItem(0);
8789 rules = remaining.GetSublist(1, -1);
8158 } 8790 }
8791 else
8792 break;
8159 } 8793 }
8160 8794
8161 return null; 8795 return res;
8162 } 8796 }
8163 8797
8164 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 8798 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
8165 { 8799 {
8166 int idx = 0; 8800 int idx=0;
8167 while (idx < rules.Length) 8801 while (idx < rules.Length)
8168 { 8802 {
8169 int code = (int)rules.GetLSLIntegerItem(idx++); 8803 int code=(int)rules.GetLSLIntegerItem(idx++);
8170 int remain = rules.Length-idx; 8804 int remain=rules.Length-idx;
8171 8805
8172 switch (code) 8806 switch (code)
8173 { 8807 {
@@ -8197,19 +8831,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8197 break; 8831 break;
8198 8832
8199 case (int)ScriptBaseClass.PRIM_POSITION: 8833 case (int)ScriptBaseClass.PRIM_POSITION:
8200 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 8834 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8201 8835 part.AbsolutePosition.Y,
8202 // For some reason, the part.AbsolutePosition.* values do not change if the 8836 part.AbsolutePosition.Z);
8203 // linkset is rotated; they always reflect the child prim's world position
8204 // as though the linkset is unrotated. This is incompatible behavior with SL's
8205 // implementation, so will break scripts imported from there (not to mention it
8206 // makes it more difficult to determine a child prim's actual inworld position).
8207 if (!part.IsRoot)
8208 {
8209 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8210 v = ((v - rootPos) * llGetRootRotation()) + rootPos;
8211 }
8212
8213 res.Add(v); 8837 res.Add(v);
8214 break; 8838 break;
8215 8839
@@ -8379,30 +9003,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8379 if (remain < 1) 9003 if (remain < 1)
8380 return null; 9004 return null;
8381 9005
8382 face=(int)rules.GetLSLIntegerItem(idx++); 9006 face = (int)rules.GetLSLIntegerItem(idx++);
8383 9007
8384 tex = part.Shape.Textures; 9008 tex = part.Shape.Textures;
9009 int shiny;
8385 if (face == ScriptBaseClass.ALL_SIDES) 9010 if (face == ScriptBaseClass.ALL_SIDES)
8386 { 9011 {
8387 for (face = 0; face < GetNumberOfSides(part); face++) 9012 for (face = 0; face < GetNumberOfSides(part); face++)
8388 { 9013 {
8389 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9014 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8390 // Convert Shininess to PRIM_SHINY_* 9015 if (shinyness == Shininess.High)
8391 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9016 {
8392 // PRIM_BUMP_* 9017 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8393 res.Add(new LSL_Integer((int)texface.Bump)); 9018 }
9019 else if (shinyness == Shininess.Medium)
9020 {
9021 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9022 }
9023 else if (shinyness == Shininess.Low)
9024 {
9025 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9026 }
9027 else
9028 {
9029 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9030 }
9031 res.Add(new LSL_Integer(shiny));
9032 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8394 } 9033 }
8395 } 9034 }
8396 else 9035 else
8397 { 9036 {
8398 if (face >= 0 && face < GetNumberOfSides(part)) 9037 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9038 if (shinyness == Shininess.High)
8399 { 9039 {
8400 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9040 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8401 // Convert Shininess to PRIM_SHINY_* 9041 }
8402 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9042 else if (shinyness == Shininess.Medium)
8403 // PRIM_BUMP_* 9043 {
8404 res.Add(new LSL_Integer((int)texface.Bump)); 9044 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9045 }
9046 else if (shinyness == Shininess.Low)
9047 {
9048 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9049 }
9050 else
9051 {
9052 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8405 } 9053 }
9054 res.Add(new LSL_Integer(shiny));
9055 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8406 } 9056 }
8407 break; 9057 break;
8408 9058
@@ -8413,21 +9063,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8413 face = (int)rules.GetLSLIntegerItem(idx++); 9063 face = (int)rules.GetLSLIntegerItem(idx++);
8414 9064
8415 tex = part.Shape.Textures; 9065 tex = part.Shape.Textures;
9066 int fullbright;
8416 if (face == ScriptBaseClass.ALL_SIDES) 9067 if (face == ScriptBaseClass.ALL_SIDES)
8417 { 9068 {
8418 for (face = 0; face < GetNumberOfSides(part); face++) 9069 for (face = 0; face < GetNumberOfSides(part); face++)
8419 { 9070 {
8420 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9071 if (tex.GetFace((uint)face).Fullbright == true)
8421 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9072 {
9073 fullbright = ScriptBaseClass.TRUE;
9074 }
9075 else
9076 {
9077 fullbright = ScriptBaseClass.FALSE;
9078 }
9079 res.Add(new LSL_Integer(fullbright));
8422 } 9080 }
8423 } 9081 }
8424 else 9082 else
8425 { 9083 {
8426 if (face >= 0 && face < GetNumberOfSides(part)) 9084 if (tex.GetFace((uint)face).Fullbright == true)
8427 { 9085 {
8428 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9086 fullbright = ScriptBaseClass.TRUE;
8429 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9087 }
9088 else
9089 {
9090 fullbright = ScriptBaseClass.FALSE;
8430 } 9091 }
9092 res.Add(new LSL_Integer(fullbright));
8431 } 9093 }
8432 break; 9094 break;
8433 9095
@@ -8449,27 +9111,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8449 break; 9111 break;
8450 9112
8451 case (int)ScriptBaseClass.PRIM_TEXGEN: 9113 case (int)ScriptBaseClass.PRIM_TEXGEN:
9114 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8452 if (remain < 1) 9115 if (remain < 1)
8453 return null; 9116 return null;
8454 9117
8455 face=(int)rules.GetLSLIntegerItem(idx++); 9118 face = (int)rules.GetLSLIntegerItem(idx++);
8456 9119
8457 tex = part.Shape.Textures; 9120 tex = part.Shape.Textures;
8458 if (face == ScriptBaseClass.ALL_SIDES) 9121 if (face == ScriptBaseClass.ALL_SIDES)
8459 { 9122 {
8460 for (face = 0; face < GetNumberOfSides(part); face++) 9123 for (face = 0; face < GetNumberOfSides(part); face++)
8461 { 9124 {
8462 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9125 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8463 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9126 {
8464 res.Add(new LSL_Integer((uint)texgen >> 1)); 9127 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9128 }
9129 else
9130 {
9131 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9132 }
8465 } 9133 }
8466 } 9134 }
8467 else 9135 else
8468 { 9136 {
8469 if (face >= 0 && face < GetNumberOfSides(part)) 9137 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9138 {
9139 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9140 }
9141 else
8470 { 9142 {
8471 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9143 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8472 res.Add(new LSL_Integer((uint)texgen >> 1));
8473 } 9144 }
8474 } 9145 }
8475 break; 9146 break;
@@ -8493,24 +9164,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8493 if (remain < 1) 9164 if (remain < 1)
8494 return null; 9165 return null;
8495 9166
8496 face=(int)rules.GetLSLIntegerItem(idx++); 9167 face = (int)rules.GetLSLIntegerItem(idx++);
8497 9168
8498 tex = part.Shape.Textures; 9169 tex = part.Shape.Textures;
9170 float primglow;
8499 if (face == ScriptBaseClass.ALL_SIDES) 9171 if (face == ScriptBaseClass.ALL_SIDES)
8500 { 9172 {
8501 for (face = 0; face < GetNumberOfSides(part); face++) 9173 for (face = 0; face < GetNumberOfSides(part); face++)
8502 { 9174 {
8503 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9175 primglow = tex.GetFace((uint)face).Glow;
8504 res.Add(new LSL_Float(texface.Glow)); 9176 res.Add(new LSL_Float(primglow));
8505 } 9177 }
8506 } 9178 }
8507 else 9179 else
8508 { 9180 {
8509 if (face >= 0 && face < GetNumberOfSides(part)) 9181 primglow = tex.GetFace((uint)face).Glow;
8510 { 9182 res.Add(new LSL_Float(primglow));
8511 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8512 res.Add(new LSL_Float(texface.Glow));
8513 }
8514 } 9183 }
8515 break; 9184 break;
8516 9185
@@ -8522,15 +9191,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8522 textColor.B)); 9191 textColor.B));
8523 res.Add(new LSL_Float(textColor.A)); 9192 res.Add(new LSL_Float(textColor.A));
8524 break; 9193 break;
9194
8525 case (int)ScriptBaseClass.PRIM_NAME: 9195 case (int)ScriptBaseClass.PRIM_NAME:
8526 res.Add(new LSL_String(part.Name)); 9196 res.Add(new LSL_String(part.Name));
8527 break; 9197 break;
9198
8528 case (int)ScriptBaseClass.PRIM_DESC: 9199 case (int)ScriptBaseClass.PRIM_DESC:
8529 res.Add(new LSL_String(part.Description)); 9200 res.Add(new LSL_String(part.Description));
8530 break; 9201 break;
8531 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9202 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8532 res.Add(new LSL_Rotation(part.RotationOffset)); 9203 res.Add(new LSL_Rotation(part.RotationOffset));
8533 break; 9204 break;
9205
8534 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9206 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8535 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9207 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8536 break; 9208 break;
@@ -9141,8 +9813,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9141 // The function returns an ordered list 9813 // The function returns an ordered list
9142 // representing the tokens found in the supplied 9814 // representing the tokens found in the supplied
9143 // sources string. If two successive tokenizers 9815 // sources string. If two successive tokenizers
9144 // are encountered, then a NULL entry is added 9816 // are encountered, then a null-string entry is
9145 // to the list. 9817 // added to the list.
9146 // 9818 //
9147 // It is a precondition that the source and 9819 // It is a precondition that the source and
9148 // toekizer lisst are non-null. If they are null, 9820 // toekizer lisst are non-null. If they are null,
@@ -9150,7 +9822,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9150 // while their lengths are being determined. 9822 // while their lengths are being determined.
9151 // 9823 //
9152 // A small amount of working memoryis required 9824 // A small amount of working memoryis required
9153 // of approximately 8*#tokenizers. 9825 // of approximately 8*#tokenizers + 8*srcstrlen.
9154 // 9826 //
9155 // There are many ways in which this function 9827 // There are many ways in which this function
9156 // can be implemented, this implementation is 9828 // can be implemented, this implementation is
@@ -9166,155 +9838,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9166 // and eliminates redundant tokenizers as soon 9838 // and eliminates redundant tokenizers as soon
9167 // as is possible. 9839 // as is possible.
9168 // 9840 //
9169 // The implementation tries to avoid any copying 9841 // The implementation tries to minimize temporary
9170 // of arrays or other objects. 9842 // garbage generation.
9171 // </remarks> 9843 // </remarks>
9172 9844
9173 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9845 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9174 { 9846 {
9175 int beginning = 0; 9847 return ParseString2List(src, separators, spacers, true);
9176 int srclen = src.Length; 9848 }
9177 int seplen = separators.Length;
9178 object[] separray = separators.Data;
9179 int spclen = spacers.Length;
9180 object[] spcarray = spacers.Data;
9181 int mlen = seplen+spclen;
9182
9183 int[] offset = new int[mlen+1];
9184 bool[] active = new bool[mlen];
9185
9186 int best;
9187 int j;
9188
9189 // Initial capacity reduces resize cost
9190 9849
9191 LSL_List tokens = new LSL_List(); 9850 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9851 {
9852 int srclen = src.Length;
9853 int seplen = separators.Length;
9854 object[] separray = separators.Data;
9855 int spclen = spacers.Length;
9856 object[] spcarray = spacers.Data;
9857 int dellen = 0;
9858 string[] delarray = new string[seplen+spclen];
9192 9859
9193 // All entries are initially valid 9860 int outlen = 0;
9861 string[] outarray = new string[srclen*2+1];
9194 9862
9195 for (int i = 0; i < mlen; i++) 9863 int i, j;
9196 active[i] = true; 9864 string d;
9197 9865
9198 offset[mlen] = srclen; 9866 m_host.AddScriptLPS(1);
9199 9867
9200 while (beginning < srclen) 9868 /*
9869 * Convert separator and spacer lists to C# strings.
9870 * Also filter out null strings so we don't hang.
9871 */
9872 for (i = 0; i < seplen; i ++)
9201 { 9873 {
9874 d = separray[i].ToString();
9875 if (d.Length > 0)
9876 {
9877 delarray[dellen++] = d;
9878 }
9879 }
9880 seplen = dellen;
9202 9881
9203 best = mlen; // as bad as it gets 9882 for (i = 0; i < spclen; i ++)
9883 {
9884 d = spcarray[i].ToString();
9885 if (d.Length > 0)
9886 {
9887 delarray[dellen++] = d;
9888 }
9889 }
9204 9890
9205 // Scan for separators 9891 /*
9892 * Scan through source string from beginning to end.
9893 */
9894 for (i = 0;;)
9895 {
9206 9896
9207 for (j = 0; j < seplen; j++) 9897 /*
9898 * Find earliest delimeter in src starting at i (if any).
9899 */
9900 int earliestDel = -1;
9901 int earliestSrc = srclen;
9902 string earliestStr = null;
9903 for (j = 0; j < dellen; j ++)
9208 { 9904 {
9209 if (separray[j].ToString() == String.Empty) 9905 d = delarray[j];
9210 active[j] = false; 9906 if (d != null)
9211
9212 if (active[j])
9213 { 9907 {
9214 // scan all of the markers 9908 int index = src.IndexOf(d, i);
9215 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9909 if (index < 0)
9216 { 9910 {
9217 // not present at all 9911 delarray[j] = null; // delim nowhere in src, don't check it anymore
9218 active[j] = false;
9219 } 9912 }
9220 else 9913 else if (index < earliestSrc)
9221 { 9914 {
9222 // present and correct 9915 earliestSrc = index; // where delimeter starts in source string
9223 if (offset[j] < offset[best]) 9916 earliestDel = j; // where delimeter is in delarray[]
9224 { 9917 earliestStr = d; // the delimeter string from delarray[]
9225 // closest so far 9918 if (index == i) break; // can't do any better than found at beg of string
9226 best = j;
9227 if (offset[best] == beginning)
9228 break;
9229 }
9230 } 9919 }
9231 } 9920 }
9232 } 9921 }
9233 9922
9234 // Scan for spacers 9923 /*
9235 9924 * Output source string starting at i through start of earliest delimeter.
9236 if (offset[best] != beginning) 9925 */
9926 if (keepNulls || (earliestSrc > i))
9237 { 9927 {
9238 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9928 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9239 {
9240 if (spcarray[j-seplen].ToString() == String.Empty)
9241 active[j] = false;
9242
9243 if (active[j])
9244 {
9245 // scan all of the markers
9246 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9247 {
9248 // not present at all
9249 active[j] = false;
9250 }
9251 else
9252 {
9253 // present and correct
9254 if (offset[j] < offset[best])
9255 {
9256 // closest so far
9257 best = j;
9258 }
9259 }
9260 }
9261 }
9262 } 9929 }
9263 9930
9264 // This is the normal exit from the scanning loop 9931 /*
9932 * If no delimeter found at or after i, we're done scanning.
9933 */
9934 if (earliestDel < 0) break;
9265 9935
9266 if (best == mlen) 9936 /*
9937 * If delimeter was a spacer, output the spacer.
9938 */
9939 if (earliestDel >= seplen)
9267 { 9940 {
9268 // no markers were found on this pass 9941 outarray[outlen++] = earliestStr;
9269 // so we're pretty much done
9270 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9271 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9272 break;
9273 } 9942 }
9274 9943
9275 // Otherwise we just add the newly delimited token 9944 /*
9276 // and recalculate where the search should continue. 9945 * Look at rest of src string following delimeter.
9277 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9946 */
9278 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9947 i = earliestSrc + earliestStr.Length;
9279
9280 if (best < seplen)
9281 {
9282 beginning = offset[best] + (separray[best].ToString()).Length;
9283 }
9284 else
9285 {
9286 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9287 string str = spcarray[best - seplen].ToString();
9288 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9289 tokens.Add(new LSL_String(str));
9290 }
9291 } 9948 }
9292 9949
9293 // This an awkward an not very intuitive boundary case. If the 9950 /*
9294 // last substring is a tokenizer, then there is an implied trailing 9951 * Make up an exact-sized output array suitable for an LSL_List object.
9295 // null list entry. Hopefully the single comparison will not be too 9952 */
9296 // arduous. Alternatively the 'break' could be replced with a return 9953 object[] outlist = new object[outlen];
9297 // but that's shabby programming. 9954 for (i = 0; i < outlen; i ++)
9298
9299 if ((beginning == srclen) && (keepNulls))
9300 { 9955 {
9301 if (srclen != 0) 9956 outlist[i] = new LSL_String(outarray[i]);
9302 tokens.Add(new LSL_String(""));
9303 } 9957 }
9304 9958 return new LSL_List(outlist);
9305 return tokens;
9306 }
9307
9308 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9309 {
9310 m_host.AddScriptLPS(1);
9311 return this.ParseString(src, separators, spacers, false);
9312 }
9313
9314 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9315 {
9316 m_host.AddScriptLPS(1);
9317 return this.ParseString(src, separators, spacers, true);
9318 } 9959 }
9319 9960
9320 public LSL_Integer llGetObjectPermMask(int mask) 9961 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9409,6 +10050,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9409 case 4: 10050 case 4:
9410 return (int)item.NextPermissions; 10051 return (int)item.NextPermissions;
9411 } 10052 }
10053 m_host.TaskInventory.LockItemsForRead(false);
9412 10054
9413 return -1; 10055 return -1;
9414 } 10056 }
@@ -9612,31 +10254,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9612 UUID key = new UUID(); 10254 UUID key = new UUID();
9613 if (UUID.TryParse(id, out key)) 10255 if (UUID.TryParse(id, out key))
9614 { 10256 {
9615 try 10257 // return total object mass
9616 { 10258 SceneObjectPart part = World.GetSceneObjectPart(key);
9617 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10259 if (part != null)
9618 if (obj != null) 10260 return part.ParentGroup.GetMass();
9619 return (double)obj.GetMass(); 10261
9620 // the object is null so the key is for an avatar 10262 // the object is null so the key is for an avatar
9621 ScenePresence avatar = World.GetScenePresence(key); 10263 ScenePresence avatar = World.GetScenePresence(key);
9622 if (avatar != null) 10264 if (avatar != null)
9623 if (avatar.IsChildAgent)
9624 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9625 // child agents have a mass of 1.0
9626 return 1;
9627 else
9628 return (double)avatar.GetMass();
9629 }
9630 catch (KeyNotFoundException)
9631 { 10265 {
9632 return 0; // The Object/Agent not in the region so just return zero 10266 if (avatar.IsChildAgent)
10267 {
10268 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10269 // child agents have a mass of 1.0
10270 return 1;
10271 }
10272 else
10273 {
10274 return (double)avatar.GetMass();
10275 }
9633 } 10276 }
9634 } 10277 }
9635 return 0; 10278 return 0;
9636 } 10279 }
9637 10280
9638 /// <summary> 10281 /// <summary>
9639 /// illListReplaceList removes the sub-list defined by the inclusive indices 10282 /// llListReplaceList removes the sub-list defined by the inclusive indices
9640 /// start and end and inserts the src list in its place. The inclusive 10283 /// start and end and inserts the src list in its place. The inclusive
9641 /// nature of the indices means that at least one element must be deleted 10284 /// nature of the indices means that at least one element must be deleted
9642 /// if the indices are within the bounds of the existing list. I.e. 2,2 10285 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9693,16 +10336,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9693 // based upon end. Note that if end exceeds the upper 10336 // based upon end. Note that if end exceeds the upper
9694 // bound in this case, the entire destination list 10337 // bound in this case, the entire destination list
9695 // is removed. 10338 // is removed.
9696 else 10339 else if (start == 0)
9697 { 10340 {
9698 if (end + 1 < dest.Length) 10341 if (end + 1 < dest.Length)
9699 {
9700 return src + dest.GetSublist(end + 1, -1); 10342 return src + dest.GetSublist(end + 1, -1);
9701 }
9702 else 10343 else
9703 {
9704 return src; 10344 return src;
9705 } 10345 }
10346 else // Start < 0
10347 {
10348 if (end + 1 < dest.Length)
10349 return dest.GetSublist(end + 1, -1);
10350 else
10351 return new LSL_List();
9706 } 10352 }
9707 } 10353 }
9708 // Finally, if start > end, we strip away a prefix and 10354 // Finally, if start > end, we strip away a prefix and
@@ -9753,17 +10399,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9753 int width = 0; 10399 int width = 0;
9754 int height = 0; 10400 int height = 0;
9755 10401
9756 ParcelMediaCommandEnum? commandToSend = null; 10402 uint commandToSend = 0;
9757 float time = 0.0f; // default is from start 10403 float time = 0.0f; // default is from start
9758 10404
9759 ScenePresence presence = null; 10405 ScenePresence presence = null;
9760 10406
9761 for (int i = 0; i < commandList.Data.Length; i++) 10407 for (int i = 0; i < commandList.Data.Length; i++)
9762 { 10408 {
9763 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10409 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9764 switch (command) 10410 switch (command)
9765 { 10411 {
9766 case ParcelMediaCommandEnum.Agent: 10412 case (uint)ParcelMediaCommandEnum.Agent:
9767 // we send only to one agent 10413 // we send only to one agent
9768 if ((i + 1) < commandList.Length) 10414 if ((i + 1) < commandList.Length)
9769 { 10415 {
@@ -9780,25 +10426,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9780 } 10426 }
9781 break; 10427 break;
9782 10428
9783 case ParcelMediaCommandEnum.Loop: 10429 case (uint)ParcelMediaCommandEnum.Loop:
9784 loop = 1; 10430 loop = 1;
9785 commandToSend = command; 10431 commandToSend = command;
9786 update = true; //need to send the media update packet to set looping 10432 update = true; //need to send the media update packet to set looping
9787 break; 10433 break;
9788 10434
9789 case ParcelMediaCommandEnum.Play: 10435 case (uint)ParcelMediaCommandEnum.Play:
9790 loop = 0; 10436 loop = 0;
9791 commandToSend = command; 10437 commandToSend = command;
9792 update = true; //need to send the media update packet to make sure it doesn't loop 10438 update = true; //need to send the media update packet to make sure it doesn't loop
9793 break; 10439 break;
9794 10440
9795 case ParcelMediaCommandEnum.Pause: 10441 case (uint)ParcelMediaCommandEnum.Pause:
9796 case ParcelMediaCommandEnum.Stop: 10442 case (uint)ParcelMediaCommandEnum.Stop:
9797 case ParcelMediaCommandEnum.Unload: 10443 case (uint)ParcelMediaCommandEnum.Unload:
9798 commandToSend = command; 10444 commandToSend = command;
9799 break; 10445 break;
9800 10446
9801 case ParcelMediaCommandEnum.Url: 10447 case (uint)ParcelMediaCommandEnum.Url:
9802 if ((i + 1) < commandList.Length) 10448 if ((i + 1) < commandList.Length)
9803 { 10449 {
9804 if (commandList.Data[i + 1] is LSL_String) 10450 if (commandList.Data[i + 1] is LSL_String)
@@ -9811,7 +10457,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9811 } 10457 }
9812 break; 10458 break;
9813 10459
9814 case ParcelMediaCommandEnum.Texture: 10460 case (uint)ParcelMediaCommandEnum.Texture:
9815 if ((i + 1) < commandList.Length) 10461 if ((i + 1) < commandList.Length)
9816 { 10462 {
9817 if (commandList.Data[i + 1] is LSL_String) 10463 if (commandList.Data[i + 1] is LSL_String)
@@ -9824,7 +10470,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9824 } 10470 }
9825 break; 10471 break;
9826 10472
9827 case ParcelMediaCommandEnum.Time: 10473 case (uint)ParcelMediaCommandEnum.Time:
9828 if ((i + 1) < commandList.Length) 10474 if ((i + 1) < commandList.Length)
9829 { 10475 {
9830 if (commandList.Data[i + 1] is LSL_Float) 10476 if (commandList.Data[i + 1] is LSL_Float)
@@ -9836,7 +10482,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9836 } 10482 }
9837 break; 10483 break;
9838 10484
9839 case ParcelMediaCommandEnum.AutoAlign: 10485 case (uint)ParcelMediaCommandEnum.AutoAlign:
9840 if ((i + 1) < commandList.Length) 10486 if ((i + 1) < commandList.Length)
9841 { 10487 {
9842 if (commandList.Data[i + 1] is LSL_Integer) 10488 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9850,7 +10496,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9850 } 10496 }
9851 break; 10497 break;
9852 10498
9853 case ParcelMediaCommandEnum.Type: 10499 case (uint)ParcelMediaCommandEnum.Type:
9854 if ((i + 1) < commandList.Length) 10500 if ((i + 1) < commandList.Length)
9855 { 10501 {
9856 if (commandList.Data[i + 1] is LSL_String) 10502 if (commandList.Data[i + 1] is LSL_String)
@@ -9863,7 +10509,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9863 } 10509 }
9864 break; 10510 break;
9865 10511
9866 case ParcelMediaCommandEnum.Desc: 10512 case (uint)ParcelMediaCommandEnum.Desc:
9867 if ((i + 1) < commandList.Length) 10513 if ((i + 1) < commandList.Length)
9868 { 10514 {
9869 if (commandList.Data[i + 1] is LSL_String) 10515 if (commandList.Data[i + 1] is LSL_String)
@@ -9876,7 +10522,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9876 } 10522 }
9877 break; 10523 break;
9878 10524
9879 case ParcelMediaCommandEnum.Size: 10525 case (uint)ParcelMediaCommandEnum.Size:
9880 if ((i + 2) < commandList.Length) 10526 if ((i + 2) < commandList.Length)
9881 { 10527 {
9882 if (commandList.Data[i + 1] is LSL_Integer) 10528 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9946,7 +10592,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9946 } 10592 }
9947 } 10593 }
9948 10594
9949 if (commandToSend != null) 10595 if (commandToSend != 0)
9950 { 10596 {
9951 // the commandList contained a start/stop/... command, too 10597 // the commandList contained a start/stop/... command, too
9952 if (presence == null) 10598 if (presence == null)
@@ -9983,7 +10629,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9983 10629
9984 if (aList.Data[i] != null) 10630 if (aList.Data[i] != null)
9985 { 10631 {
9986 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10632 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9987 { 10633 {
9988 case ParcelMediaCommandEnum.Url: 10634 case ParcelMediaCommandEnum.Url:
9989 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10635 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -10040,15 +10686,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10040 10686
10041 if (quick_pay_buttons.Data.Length < 4) 10687 if (quick_pay_buttons.Data.Length < 4)
10042 { 10688 {
10043 LSLError("List must have at least 4 elements"); 10689 int x;
10044 return; 10690 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10691 {
10692 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10693 }
10045 } 10694 }
10046 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10695 int[] nPrice = new int[5];
10047 10696 nPrice[0] = price;
10048 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10697 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
10049 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10698 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
10050 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10699 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
10051 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10700 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10701 m_host.ParentGroup.RootPart.PayPrice = nPrice;
10052 m_host.ParentGroup.HasGroupChanged = true; 10702 m_host.ParentGroup.HasGroupChanged = true;
10053 } 10703 }
10054 10704
@@ -10065,7 +10715,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10065 return Vector3.Zero; 10715 return Vector3.Zero;
10066 } 10716 }
10067 10717
10068 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10718// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10719 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10069 if (presence != null) 10720 if (presence != null)
10070 { 10721 {
10071 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 10722 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
@@ -10088,7 +10739,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10088 return Quaternion.Identity; 10739 return Quaternion.Identity;
10089 } 10740 }
10090 10741
10091 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10742// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10743 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10092 if (presence != null) 10744 if (presence != null)
10093 { 10745 {
10094 return new LSL_Rotation(presence.CameraRotation); 10746 return new LSL_Rotation(presence.CameraRotation);
@@ -10148,14 +10800,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10148 { 10800 {
10149 m_host.AddScriptLPS(1); 10801 m_host.AddScriptLPS(1);
10150 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10802 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10151 if (detectedParams == null) return; // only works on the first detected avatar 10803 if (detectedParams == null)
10152 10804 {
10805 if (m_host.ParentGroup.IsAttachment == true)
10806 {
10807 detectedParams = new DetectParams();
10808 detectedParams.Key = m_host.OwnerID;
10809 }
10810 else
10811 {
10812 return;
10813 }
10814 }
10815
10153 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10816 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10154 if (avatar != null) 10817 if (avatar != null)
10155 { 10818 {
10156 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10819 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10157 simname, pos, lookAt); 10820 simname, pos, lookAt);
10158 } 10821 }
10822
10159 ScriptSleep(1000); 10823 ScriptSleep(1000);
10160 } 10824 }
10161 10825
@@ -10279,12 +10943,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10279 10943
10280 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10944 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10281 object[] data = rules.Data; 10945 object[] data = rules.Data;
10282 for (int i = 0; i < data.Length; ++i) { 10946 for (int i = 0; i < data.Length; ++i)
10947 {
10283 int type = Convert.ToInt32(data[i++].ToString()); 10948 int type = Convert.ToInt32(data[i++].ToString());
10284 if (i >= data.Length) break; // odd number of entries => ignore the last 10949 if (i >= data.Length) break; // odd number of entries => ignore the last
10285 10950
10286 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10951 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10287 switch (type) { 10952 switch (type)
10953 {
10288 case ScriptBaseClass.CAMERA_FOCUS: 10954 case ScriptBaseClass.CAMERA_FOCUS:
10289 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10955 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10290 case ScriptBaseClass.CAMERA_POSITION: 10956 case ScriptBaseClass.CAMERA_POSITION:
@@ -10389,19 +11055,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10389 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11055 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10390 { 11056 {
10391 m_host.AddScriptLPS(1); 11057 m_host.AddScriptLPS(1);
10392 string ret = String.Empty; 11058
10393 string src1 = llBase64ToString(str1); 11059 if (str1 == String.Empty)
10394 string src2 = llBase64ToString(str2); 11060 return String.Empty;
10395 int c = 0; 11061 if (str2 == String.Empty)
10396 for (int i = 0; i < src1.Length; i++) 11062 return str1;
11063
11064 int len = str2.Length;
11065 if ((len % 4) != 0) // LL is EVIL!!!!
11066 {
11067 while (str2.EndsWith("="))
11068 str2 = str2.Substring(0, str2.Length - 1);
11069
11070 len = str2.Length;
11071 int mod = len % 4;
11072
11073 if (mod == 1)
11074 str2 = str2.Substring(0, str2.Length - 1);
11075 else if (mod == 2)
11076 str2 += "==";
11077 else if (mod == 3)
11078 str2 += "=";
11079 }
11080
11081 byte[] data1;
11082 byte[] data2;
11083 try
11084 {
11085 data1 = Convert.FromBase64String(str1);
11086 data2 = Convert.FromBase64String(str2);
11087 }
11088 catch (Exception)
11089 {
11090 return new LSL_String(String.Empty);
11091 }
11092
11093 byte[] d2 = new Byte[data1.Length];
11094 int pos = 0;
11095
11096 if (data1.Length <= data2.Length)
11097 {
11098 Array.Copy(data2, 0, d2, 0, data1.Length);
11099 }
11100 else
10397 { 11101 {
10398 ret += (char) (src1[i] ^ src2[c]); 11102 while (pos < data1.Length)
11103 {
11104 len = data1.Length - pos;
11105 if (len > data2.Length)
11106 len = data2.Length;
10399 11107
10400 c++; 11108 Array.Copy(data2, 0, d2, pos, len);
10401 if (c >= src2.Length) 11109 pos += len;
10402 c = 0; 11110 }
10403 } 11111 }
10404 return llStringToBase64(ret); 11112
11113 for (pos = 0 ; pos < data1.Length ; pos++ )
11114 data1[pos] ^= d2[pos];
11115
11116 return Convert.ToBase64String(data1);
10405 } 11117 }
10406 11118
10407 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11119 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10454,16 +11166,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10454 if (userAgent != null) 11166 if (userAgent != null)
10455 httpHeaders["User-Agent"] = userAgent; 11167 httpHeaders["User-Agent"] = userAgent;
10456 11168
11169 // See if the URL contains any header hacks
11170 string[] urlParts = url.Split(new char[] {'\n'});
11171 if (urlParts.Length > 1)
11172 {
11173 // Iterate the passed headers and parse them
11174 for (int i = 1 ; i < urlParts.Length ; i++ )
11175 {
11176 // The rest of those would be added to the body in SL.
11177 // Let's not do that.
11178 if (urlParts[i] == String.Empty)
11179 break;
11180
11181 // See if this could be a valid header
11182 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11183 if (headerParts.Length != 2)
11184 continue;
11185
11186 string headerName = headerParts[0].Trim();
11187 string headerValue = headerParts[1].Trim();
11188
11189 // Filter out headers that could be used to abuse
11190 // another system or cloak the request
11191 if (headerName.ToLower() == "x-secondlife-shard" ||
11192 headerName.ToLower() == "x-secondlife-object-name" ||
11193 headerName.ToLower() == "x-secondlife-object-key" ||
11194 headerName.ToLower() == "x-secondlife-region" ||
11195 headerName.ToLower() == "x-secondlife-local-position" ||
11196 headerName.ToLower() == "x-secondlife-local-velocity" ||
11197 headerName.ToLower() == "x-secondlife-local-rotation" ||
11198 headerName.ToLower() == "x-secondlife-owner-name" ||
11199 headerName.ToLower() == "x-secondlife-owner-key" ||
11200 headerName.ToLower() == "connection" ||
11201 headerName.ToLower() == "content-length" ||
11202 headerName.ToLower() == "from" ||
11203 headerName.ToLower() == "host" ||
11204 headerName.ToLower() == "proxy-authorization" ||
11205 headerName.ToLower() == "referer" ||
11206 headerName.ToLower() == "trailer" ||
11207 headerName.ToLower() == "transfer-encoding" ||
11208 headerName.ToLower() == "via" ||
11209 headerName.ToLower() == "authorization")
11210 continue;
11211
11212 httpHeaders[headerName] = headerValue;
11213 }
11214
11215 // Finally, strip any protocol specifier from the URL
11216 url = urlParts[0].Trim();
11217 int idx = url.IndexOf(" HTTP/");
11218 if (idx != -1)
11219 url = url.Substring(0, idx);
11220 }
11221
10457 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11222 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10458 Regex r = new Regex(authregex); 11223 Regex r = new Regex(authregex);
10459 int[] gnums = r.GetGroupNumbers(); 11224 int[] gnums = r.GetGroupNumbers();
10460 Match m = r.Match(url); 11225 Match m = r.Match(url);
10461 if (m.Success) { 11226 if (m.Success)
10462 for (int i = 1; i < gnums.Length; i++) { 11227 {
11228 for (int i = 1; i < gnums.Length; i++)
11229 {
10463 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11230 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10464 //CaptureCollection cc = g.Captures; 11231 //CaptureCollection cc = g.Captures;
10465 } 11232 }
10466 if (m.Groups.Count == 5) { 11233 if (m.Groups.Count == 5)
11234 {
10467 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11235 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10468 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11236 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10469 } 11237 }
@@ -10666,6 +11434,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10666 11434
10667 LSL_List ret = new LSL_List(); 11435 LSL_List ret = new LSL_List();
10668 UUID key = new UUID(); 11436 UUID key = new UUID();
11437
11438
10669 if (UUID.TryParse(id, out key)) 11439 if (UUID.TryParse(id, out key))
10670 { 11440 {
10671 ScenePresence av = World.GetScenePresence(key); 11441 ScenePresence av = World.GetScenePresence(key);
@@ -10683,13 +11453,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10683 ret.Add(new LSL_String("")); 11453 ret.Add(new LSL_String(""));
10684 break; 11454 break;
10685 case ScriptBaseClass.OBJECT_POS: 11455 case ScriptBaseClass.OBJECT_POS:
10686 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11456 Vector3 avpos;
11457
11458 if (av.ParentID != 0 && av.ParentPart != null)
11459 {
11460 avpos = av.OffsetPosition;
11461
11462 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11463 avpos -= sitOffset;
11464
11465 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11466 }
11467 else
11468 avpos = av.AbsolutePosition;
11469
11470 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10687 break; 11471 break;
10688 case ScriptBaseClass.OBJECT_ROT: 11472 case ScriptBaseClass.OBJECT_ROT:
10689 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 11473 Quaternion avrot = av.Rotation;
11474 if (av.ParentID != 0 && av.ParentPart != null)
11475 {
11476 avrot = av.ParentPart.GetWorldRotation() * avrot;
11477 }
11478 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10690 break; 11479 break;
10691 case ScriptBaseClass.OBJECT_VELOCITY: 11480 case ScriptBaseClass.OBJECT_VELOCITY:
10692 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11481 Vector3 avvel = av.Velocity;
11482 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10693 break; 11483 break;
10694 case ScriptBaseClass.OBJECT_OWNER: 11484 case ScriptBaseClass.OBJECT_OWNER:
10695 ret.Add(new LSL_String(id)); 11485 ret.Add(new LSL_String(id));
@@ -10774,11 +11564,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10774 case ScriptBaseClass.OBJECT_NAME: 11564 case ScriptBaseClass.OBJECT_NAME:
10775 ret.Add(new LSL_String(obj.Name)); 11565 ret.Add(new LSL_String(obj.Name));
10776 break; 11566 break;
10777 case ScriptBaseClass.OBJECT_DESC: 11567 case ScriptBaseClass.OBJECT_DESC:
10778 ret.Add(new LSL_String(obj.Description)); 11568 ret.Add(new LSL_String(obj.Description));
10779 break; 11569 break;
10780 case ScriptBaseClass.OBJECT_POS: 11570 case ScriptBaseClass.OBJECT_POS:
10781 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11571 Vector3 opos = obj.AbsolutePosition;
11572 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10782 break; 11573 break;
10783 case ScriptBaseClass.OBJECT_ROT: 11574 case ScriptBaseClass.OBJECT_ROT:
10784 { 11575 {
@@ -10828,9 +11619,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10828 // The value returned in SL for normal prims is prim count 11619 // The value returned in SL for normal prims is prim count
10829 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11620 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10830 break; 11621 break;
10831 // The following 3 costs I have intentionaly coded to return zero. They are part of 11622
10832 // "Land Impact" calculations. These calculations are probably not applicable 11623 // costs below may need to be diferent for root parts, need to check
10833 // to OpenSim and are not yet complete in SL
10834 case ScriptBaseClass.OBJECT_SERVER_COST: 11624 case ScriptBaseClass.OBJECT_SERVER_COST:
10835 // The linden calculation is here 11625 // The linden calculation is here
10836 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11626 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10838,16 +11628,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10838 ret.Add(new LSL_Float(0)); 11628 ret.Add(new LSL_Float(0));
10839 break; 11629 break;
10840 case ScriptBaseClass.OBJECT_STREAMING_COST: 11630 case ScriptBaseClass.OBJECT_STREAMING_COST:
10841 // The linden calculation is here 11631 // The value returned in SL for normal prims is prim count * 0.06
10842 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11632 ret.Add(new LSL_Float(obj.StreamingCost));
10843 // The value returned in SL for normal prims looks like the prim count * 0.06
10844 ret.Add(new LSL_Float(0));
10845 break; 11633 break;
10846 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11634 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10847 // The linden calculation is here 11635 // The value returned in SL for normal prims is prim count
10848 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11636 ret.Add(new LSL_Float(obj.PhysicsCost));
10849 // The value returned in SL for normal prims looks like the prim count
10850 ret.Add(new LSL_Float(0));
10851 break; 11637 break;
10852 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11638 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
10853 ret.Add(new LSL_Float(0)); 11639 ret.Add(new LSL_Float(0));
@@ -11106,15 +11892,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11106 return result; 11892 return result;
11107 } 11893 }
11108 11894
11109 public void print(string str) 11895 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
11110 { 11896 {
11111 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11897 List<SceneObjectPart> parts = GetLinkParts(link);
11112 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11898 if (parts.Count < 1)
11113 if (ossl != null) 11899 return 0;
11114 { 11900
11115 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11901 return GetNumberOfSides(parts[0]);
11116 m_log.Info("LSL print():" + str);
11117 }
11118 } 11902 }
11119 11903
11120 private string Name2Username(string name) 11904 private string Name2Username(string name)
@@ -11159,7 +11943,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11159 11943
11160 return rq.ToString(); 11944 return rq.ToString();
11161 } 11945 }
11162 11946/*
11947 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11948 {
11949 m_SayShoutCount = 0;
11950 }
11951*/
11163 private struct Tri 11952 private struct Tri
11164 { 11953 {
11165 public Vector3 p1; 11954 public Vector3 p1;
@@ -11308,9 +12097,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11308 12097
11309 ContactResult result = new ContactResult (); 12098 ContactResult result = new ContactResult ();
11310 result.ConsumerID = group.LocalId; 12099 result.ConsumerID = group.LocalId;
11311 result.Depth = intersection.distance; 12100// result.Depth = intersection.distance;
11312 result.Normal = intersection.normal; 12101 result.Normal = intersection.normal;
11313 result.Pos = intersection.ipoint; 12102 result.Pos = intersection.ipoint;
12103 result.Depth = Vector3.Mag(rayStart - result.Pos);
11314 12104
11315 contacts.Add(result); 12105 contacts.Add(result);
11316 }); 12106 });
@@ -11443,6 +12233,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11443 12233
11444 return contacts[0]; 12234 return contacts[0];
11445 } 12235 }
12236/*
12237 // not done:
12238 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12239 {
12240 ContactResult[] contacts = null;
12241 World.ForEachSOG(delegate(SceneObjectGroup group)
12242 {
12243 if (m_host.ParentGroup == group)
12244 return;
12245
12246 if (group.IsAttachment)
12247 return;
12248
12249 if(group.RootPart.PhysActor != null)
12250 return;
12251
12252 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12253 });
12254 return contacts;
12255 }
12256*/
11446 12257
11447 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12258 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11448 { 12259 {
@@ -11566,18 +12377,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11566 } 12377 }
11567 } 12378 }
11568 12379
12380 // Double check this
11569 if (checkTerrain) 12381 if (checkTerrain)
11570 { 12382 {
11571 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12383 bool skipGroundCheck = false;
11572 if (groundContact != null) 12384
11573 results.Add((ContactResult)groundContact); 12385 foreach (ContactResult c in results)
12386 {
12387 if (c.ConsumerID == 0) // Physics gave us a ground collision
12388 skipGroundCheck = true;
12389 }
12390
12391 if (!skipGroundCheck)
12392 {
12393 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12394 if (groundContact != null)
12395 results.Add((ContactResult)groundContact);
12396 }
11574 } 12397 }
11575 12398
11576 results.Sort(delegate(ContactResult a, ContactResult b) 12399 results.Sort(delegate(ContactResult a, ContactResult b)
11577 { 12400 {
11578 return a.Depth.CompareTo(b.Depth); 12401 return a.Depth.CompareTo(b.Depth);
11579 }); 12402 });
11580 12403
11581 int values = 0; 12404 int values = 0;
11582 SceneObjectGroup thisgrp = m_host.ParentGroup; 12405 SceneObjectGroup thisgrp = m_host.ParentGroup;
11583 12406
@@ -11670,7 +12493,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11670 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12493 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11671 if (!isAccount) return 0; 12494 if (!isAccount) return 0;
11672 if (estate.HasAccess(id)) return 1; 12495 if (estate.HasAccess(id)) return 1;
11673 if (estate.IsBanned(id)) 12496 if (estate.IsBanned(id, World.GetUserFlags(id)))
11674 estate.RemoveBan(id); 12497 estate.RemoveBan(id);
11675 estate.AddEstateUser(id); 12498 estate.AddEstateUser(id);
11676 break; 12499 break;
@@ -11689,14 +12512,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11689 break; 12512 break;
11690 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12513 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11691 if (!isAccount) return 0; 12514 if (!isAccount) return 0;
11692 if (estate.IsBanned(id)) return 1; 12515 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11693 EstateBan ban = new EstateBan(); 12516 EstateBan ban = new EstateBan();
11694 ban.EstateID = estate.EstateID; 12517 ban.EstateID = estate.EstateID;
11695 ban.BannedUserID = id; 12518 ban.BannedUserID = id;
11696 estate.AddBan(ban); 12519 estate.AddBan(ban);
11697 break; 12520 break;
11698 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12521 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11699 if (!isAccount || !estate.IsBanned(id)) return 0; 12522 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11700 estate.RemoveBan(id); 12523 estate.RemoveBan(id);
11701 break; 12524 break;
11702 default: return 0; 12525 default: return 0;
@@ -11753,19 +12576,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11753 public void llSetSoundQueueing(int queue) 12576 public void llSetSoundQueueing(int queue)
11754 { 12577 {
11755 m_host.AddScriptLPS(1); 12578 m_host.AddScriptLPS(1);
11756 NotImplemented("llSetSoundQueueing");
11757 } 12579 }
11758 12580
11759 public void llCollisionSprite(string impact_sprite) 12581 public void llCollisionSprite(string impact_sprite)
11760 { 12582 {
11761 m_host.AddScriptLPS(1); 12583 m_host.AddScriptLPS(1);
11762 NotImplemented("llCollisionSprite"); 12584 // Viewer 2.0 broke this and it's likely LL has no intention
12585 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11763 } 12586 }
11764 12587
11765 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12588 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11766 { 12589 {
11767 m_host.AddScriptLPS(1); 12590 m_host.AddScriptLPS(1);
11768 NotImplemented("llGodLikeRezObject"); 12591
12592 if (!World.Permissions.IsGod(m_host.OwnerID))
12593 NotImplemented("llGodLikeRezObject");
12594
12595 AssetBase rezAsset = World.AssetService.Get(inventory);
12596 if (rezAsset == null)
12597 {
12598 llSay(0, "Asset not found");
12599 return;
12600 }
12601
12602 SceneObjectGroup group = null;
12603
12604 try
12605 {
12606 string xmlData = Utils.BytesToString(rezAsset.Data);
12607 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12608 }
12609 catch
12610 {
12611 llSay(0, "Asset not found");
12612 return;
12613 }
12614
12615 if (group == null)
12616 {
12617 llSay(0, "Asset not found");
12618 return;
12619 }
12620
12621 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12622 group.RootPart.AttachOffset = group.AbsolutePosition;
12623
12624 group.ResetIDs();
12625
12626 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12627 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12628 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12629 group.ScheduleGroupForFullUpdate();
12630
12631 // objects rezzed with this method are die_at_edge by default.
12632 group.RootPart.SetDieAtEdge(true);
12633
12634 group.ResumeScripts();
12635
12636 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12637 "object_rez", new Object[] {
12638 new LSL_String(
12639 group.RootPart.UUID.ToString()) },
12640 new DetectParams[0]));
11769 } 12641 }
11770 12642
11771 public LSL_String llTransferLindenDollars(string destination, int amount) 12643 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -11817,7 +12689,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11817 } 12689 }
11818 12690
11819 bool result = money.ObjectGiveMoney( 12691 bool result = money.ObjectGiveMoney(
11820 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12692 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn);
11821 12693
11822 if (result) 12694 if (result)
11823 { 12695 {
@@ -11842,6 +12714,598 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11842 } 12714 }
11843 12715
11844 #endregion 12716 #endregion
12717
12718 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12719 {
12720 SceneObjectGroup group = m_host.ParentGroup;
12721
12722 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12723 return;
12724 if (group.IsAttachment)
12725 return;
12726
12727 if (frames.Data.Length > 0) // We are getting a new motion
12728 {
12729 if (group.RootPart.KeyframeMotion != null)
12730 group.RootPart.KeyframeMotion.Delete();
12731 group.RootPart.KeyframeMotion = null;
12732
12733 int idx = 0;
12734
12735 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12736 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12737
12738 while (idx < options.Data.Length)
12739 {
12740 int option = (int)options.GetLSLIntegerItem(idx++);
12741 int remain = options.Data.Length - idx;
12742
12743 switch (option)
12744 {
12745 case ScriptBaseClass.KFM_MODE:
12746 if (remain < 1)
12747 break;
12748 int modeval = (int)options.GetLSLIntegerItem(idx++);
12749 switch(modeval)
12750 {
12751 case ScriptBaseClass.KFM_FORWARD:
12752 mode = KeyframeMotion.PlayMode.Forward;
12753 break;
12754 case ScriptBaseClass.KFM_REVERSE:
12755 mode = KeyframeMotion.PlayMode.Reverse;
12756 break;
12757 case ScriptBaseClass.KFM_LOOP:
12758 mode = KeyframeMotion.PlayMode.Loop;
12759 break;
12760 case ScriptBaseClass.KFM_PING_PONG:
12761 mode = KeyframeMotion.PlayMode.PingPong;
12762 break;
12763 }
12764 break;
12765 case ScriptBaseClass.KFM_DATA:
12766 if (remain < 1)
12767 break;
12768 int dataval = (int)options.GetLSLIntegerItem(idx++);
12769 data = (KeyframeMotion.DataFormat)dataval;
12770 break;
12771 }
12772 }
12773
12774 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12775
12776 idx = 0;
12777
12778 int elemLength = 2;
12779 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12780 elemLength = 3;
12781
12782 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12783 while (idx < frames.Data.Length)
12784 {
12785 int remain = frames.Data.Length - idx;
12786
12787 if (remain < elemLength)
12788 break;
12789
12790 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12791 frame.Position = null;
12792 frame.Rotation = null;
12793
12794 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12795 {
12796 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12797 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12798 }
12799 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12800 {
12801 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12802 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12803 q.Normalize();
12804 frame.Rotation = q;
12805 }
12806
12807 float tempf = (float)frames.GetLSLFloatItem(idx++);
12808 frame.TimeMS = (int)(tempf * 1000.0f);
12809
12810 keyframes.Add(frame);
12811 }
12812
12813 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12814 group.RootPart.KeyframeMotion.Start();
12815 }
12816 else
12817 {
12818 if (group.RootPart.KeyframeMotion == null)
12819 return;
12820
12821 if (options.Data.Length == 0)
12822 {
12823 group.RootPart.KeyframeMotion.Stop();
12824 return;
12825 }
12826
12827 int code = (int)options.GetLSLIntegerItem(0);
12828
12829 int idx = 0;
12830
12831 while (idx < options.Data.Length)
12832 {
12833 int option = (int)options.GetLSLIntegerItem(idx++);
12834 int remain = options.Data.Length - idx;
12835
12836 switch (option)
12837 {
12838 case ScriptBaseClass.KFM_COMMAND:
12839 int cmd = (int)options.GetLSLIntegerItem(idx++);
12840 switch (cmd)
12841 {
12842 case ScriptBaseClass.KFM_CMD_PLAY:
12843 group.RootPart.KeyframeMotion.Start();
12844 break;
12845 case ScriptBaseClass.KFM_CMD_STOP:
12846 group.RootPart.KeyframeMotion.Stop();
12847 break;
12848 case ScriptBaseClass.KFM_CMD_PAUSE:
12849 group.RootPart.KeyframeMotion.Pause();
12850 break;
12851 }
12852 break;
12853 }
12854 }
12855 }
12856 }
12857
12858 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12859 {
12860 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12861
12862 int idx = 0;
12863 int idxStart = 0;
12864
12865 bool positionChanged = false;
12866 Vector3 finalPos = Vector3.Zero;
12867
12868 try
12869 {
12870 while (idx < rules.Length)
12871 {
12872 ++rulesParsed;
12873 int code = rules.GetLSLIntegerItem(idx++);
12874
12875 int remain = rules.Length - idx;
12876 idxStart = idx;
12877
12878 switch (code)
12879 {
12880 case (int)ScriptBaseClass.PRIM_POSITION:
12881 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12882 {
12883 if (remain < 1)
12884 return null;
12885
12886 LSL_Vector v;
12887 v = rules.GetVector3Item(idx++);
12888
12889 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12890 if (part == null)
12891 break;
12892
12893 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12894 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12895 if (part.LinkNum > 1)
12896 {
12897 localRot = GetPartLocalRot(part);
12898 localPos = GetPartLocalPos(part);
12899 }
12900
12901 v -= localPos;
12902 v /= localRot;
12903
12904 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12905
12906 v = v + 2 * sitOffset;
12907
12908 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12909 av.SendAvatarDataToAllAgents();
12910
12911 }
12912 break;
12913
12914 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12915 case (int)ScriptBaseClass.PRIM_ROTATION:
12916 {
12917 if (remain < 1)
12918 return null;
12919
12920 LSL_Rotation r;
12921 r = rules.GetQuaternionItem(idx++);
12922
12923 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12924 if (part == null)
12925 break;
12926
12927 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12928 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12929
12930 if (part.LinkNum > 1)
12931 localRot = GetPartLocalRot(part);
12932
12933 r = r * llGetRootRotation() / localRot;
12934 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12935 av.SendAvatarDataToAllAgents();
12936 }
12937 break;
12938
12939 // parse rest doing nothing but number of parameters error check
12940 case (int)ScriptBaseClass.PRIM_SIZE:
12941 case (int)ScriptBaseClass.PRIM_MATERIAL:
12942 case (int)ScriptBaseClass.PRIM_PHANTOM:
12943 case (int)ScriptBaseClass.PRIM_PHYSICS:
12944 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12945 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12946 case (int)ScriptBaseClass.PRIM_NAME:
12947 case (int)ScriptBaseClass.PRIM_DESC:
12948 if (remain < 1)
12949 return null;
12950 idx++;
12951 break;
12952
12953 case (int)ScriptBaseClass.PRIM_GLOW:
12954 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12955 case (int)ScriptBaseClass.PRIM_TEXGEN:
12956 if (remain < 2)
12957 return null;
12958 idx += 2;
12959 break;
12960
12961 case (int)ScriptBaseClass.PRIM_TYPE:
12962 if (remain < 3)
12963 return null;
12964 code = (int)rules.GetLSLIntegerItem(idx++);
12965 remain = rules.Length - idx;
12966 switch (code)
12967 {
12968 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12969 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12970 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12971 if (remain < 6)
12972 return null;
12973 idx += 6;
12974 break;
12975
12976 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12977 if (remain < 5)
12978 return null;
12979 idx += 5;
12980 break;
12981
12982 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12983 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12984 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12985 if (remain < 11)
12986 return null;
12987 idx += 11;
12988 break;
12989
12990 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12991 if (remain < 2)
12992 return null;
12993 idx += 2;
12994 break;
12995 }
12996 break;
12997
12998 case (int)ScriptBaseClass.PRIM_COLOR:
12999 case (int)ScriptBaseClass.PRIM_TEXT:
13000 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13001 case (int)ScriptBaseClass.PRIM_OMEGA:
13002 if (remain < 3)
13003 return null;
13004 idx += 3;
13005 break;
13006
13007 case (int)ScriptBaseClass.PRIM_TEXTURE:
13008 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13009 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
13010 if (remain < 5)
13011 return null;
13012 idx += 5;
13013 break;
13014
13015 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13016 if (remain < 7)
13017 return null;
13018
13019 idx += 7;
13020 break;
13021
13022 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13023 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13024 return null;
13025
13026 return rules.GetSublist(idx, -1);
13027 }
13028 }
13029 }
13030 catch (InvalidCastException e)
13031 {
13032 ShoutError(string.Format(
13033 "{0} error running rule #{1}: arg #{2} ",
13034 originFunc, rulesParsed, idx - idxStart) + e.Message);
13035 }
13036 finally
13037 {
13038 if (positionChanged)
13039 {
13040 av.OffsetPosition = finalPos;
13041// av.SendAvatarDataToAllAgents();
13042 av.SendTerseUpdateToAllClients();
13043 positionChanged = false;
13044 }
13045 }
13046 return null;
13047 }
13048
13049 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13050 {
13051 // avatars case
13052 // replies as SL wiki
13053
13054// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13055 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13056
13057 int idx = 0;
13058 while (idx < rules.Length)
13059 {
13060 int code = (int)rules.GetLSLIntegerItem(idx++);
13061 int remain = rules.Length - idx;
13062
13063 switch (code)
13064 {
13065 case (int)ScriptBaseClass.PRIM_MATERIAL:
13066 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13067 break;
13068
13069 case (int)ScriptBaseClass.PRIM_PHYSICS:
13070 res.Add(new LSL_Integer(0));
13071 break;
13072
13073 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13074 res.Add(new LSL_Integer(0));
13075 break;
13076
13077 case (int)ScriptBaseClass.PRIM_PHANTOM:
13078 res.Add(new LSL_Integer(0));
13079 break;
13080
13081 case (int)ScriptBaseClass.PRIM_POSITION:
13082
13083 Vector3 pos = avatar.OffsetPosition;
13084
13085 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13086 pos -= sitOffset;
13087
13088 if( sitPart != null)
13089 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13090
13091 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13092 break;
13093
13094 case (int)ScriptBaseClass.PRIM_SIZE:
13095 // as in llGetAgentSize above
13096// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13097 Vector3 s = avatar.Appearance.AvatarSize;
13098 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13099
13100 break;
13101
13102 case (int)ScriptBaseClass.PRIM_ROTATION:
13103 Quaternion rot = avatar.Rotation;
13104 if (sitPart != null)
13105 {
13106 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13107 }
13108
13109 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13110 break;
13111
13112 case (int)ScriptBaseClass.PRIM_TYPE:
13113 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13114 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13115 res.Add(new LSL_Vector(0f,1.0f,0f));
13116 res.Add(new LSL_Float(0.0f));
13117 res.Add(new LSL_Vector(0, 0, 0));
13118 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13119 res.Add(new LSL_Vector(0, 0, 0));
13120 break;
13121
13122 case (int)ScriptBaseClass.PRIM_TEXTURE:
13123 if (remain < 1)
13124 return null;
13125
13126 int face = (int)rules.GetLSLIntegerItem(idx++);
13127 if (face == ScriptBaseClass.ALL_SIDES)
13128 {
13129 for (face = 0; face < 21; face++)
13130 {
13131 res.Add(new LSL_String(""));
13132 res.Add(new LSL_Vector(0,0,0));
13133 res.Add(new LSL_Vector(0,0,0));
13134 res.Add(new LSL_Float(0.0));
13135 }
13136 }
13137 else
13138 {
13139 if (face >= 0 && face < 21)
13140 {
13141 res.Add(new LSL_String(""));
13142 res.Add(new LSL_Vector(0,0,0));
13143 res.Add(new LSL_Vector(0,0,0));
13144 res.Add(new LSL_Float(0.0));
13145 }
13146 }
13147 break;
13148
13149 case (int)ScriptBaseClass.PRIM_COLOR:
13150 if (remain < 1)
13151 return null;
13152
13153 face = (int)rules.GetLSLIntegerItem(idx++);
13154
13155 if (face == ScriptBaseClass.ALL_SIDES)
13156 {
13157 for (face = 0; face < 21; face++)
13158 {
13159 res.Add(new LSL_Vector(0,0,0));
13160 res.Add(new LSL_Float(0));
13161 }
13162 }
13163 else
13164 {
13165 res.Add(new LSL_Vector(0,0,0));
13166 res.Add(new LSL_Float(0));
13167 }
13168 break;
13169
13170 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13171 if (remain < 1)
13172 return null;
13173 face = (int)rules.GetLSLIntegerItem(idx++);
13174
13175 if (face == ScriptBaseClass.ALL_SIDES)
13176 {
13177 for (face = 0; face < 21; face++)
13178 {
13179 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13180 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13181 }
13182 }
13183 else
13184 {
13185 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13186 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13187 }
13188 break;
13189
13190 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13191 if (remain < 1)
13192 return null;
13193 face = (int)rules.GetLSLIntegerItem(idx++);
13194
13195 if (face == ScriptBaseClass.ALL_SIDES)
13196 {
13197 for (face = 0; face < 21; face++)
13198 {
13199 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13200 }
13201 }
13202 else
13203 {
13204 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13205 }
13206 break;
13207
13208 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13209 res.Add(new LSL_Integer(0));
13210 res.Add(new LSL_Integer(0));// softness
13211 res.Add(new LSL_Float(0.0f)); // gravity
13212 res.Add(new LSL_Float(0.0f)); // friction
13213 res.Add(new LSL_Float(0.0f)); // wind
13214 res.Add(new LSL_Float(0.0f)); // tension
13215 res.Add(new LSL_Vector(0f,0f,0f));
13216 break;
13217
13218 case (int)ScriptBaseClass.PRIM_TEXGEN:
13219 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13220 if (remain < 1)
13221 return null;
13222 face = (int)rules.GetLSLIntegerItem(idx++);
13223
13224 if (face == ScriptBaseClass.ALL_SIDES)
13225 {
13226 for (face = 0; face < 21; face++)
13227 {
13228 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13229 }
13230 }
13231 else
13232 {
13233 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13234 }
13235 break;
13236
13237 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13238 res.Add(new LSL_Integer(0));
13239 res.Add(new LSL_Vector(0f,0f,0f));
13240 res.Add(new LSL_Float(0f)); // intensity
13241 res.Add(new LSL_Float(0f)); // radius
13242 res.Add(new LSL_Float(0f)); // falloff
13243 break;
13244
13245 case (int)ScriptBaseClass.PRIM_GLOW:
13246 if (remain < 1)
13247 return null;
13248 face = (int)rules.GetLSLIntegerItem(idx++);
13249
13250 if (face == ScriptBaseClass.ALL_SIDES)
13251 {
13252 for (face = 0; face < 21; face++)
13253 {
13254 res.Add(new LSL_Float(0f));
13255 }
13256 }
13257 else
13258 {
13259 res.Add(new LSL_Float(0f));
13260 }
13261 break;
13262
13263 case (int)ScriptBaseClass.PRIM_TEXT:
13264 res.Add(new LSL_String(""));
13265 res.Add(new LSL_Vector(0f,0f,0f));
13266 res.Add(new LSL_Float(1.0f));
13267 break;
13268
13269 case (int)ScriptBaseClass.PRIM_NAME:
13270 res.Add(new LSL_String(avatar.Name));
13271 break;
13272
13273 case (int)ScriptBaseClass.PRIM_DESC:
13274 res.Add(new LSL_String(""));
13275 break;
13276
13277 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13278 Quaternion lrot = avatar.Rotation;
13279
13280 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13281 {
13282 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13283 }
13284 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13285 break;
13286
13287 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13288 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13289 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13290 lpos -= lsitOffset;
13291
13292 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13293 {
13294 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13295 }
13296 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13297 break;
13298
13299 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13300 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13301 return null;
13302
13303 return rules.GetSublist(idx, -1);
13304 }
13305 }
13306
13307 return null;
13308 }
11845 } 13309 }
11846 13310
11847 public class NotecardCache 13311 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 21bae27..bd776b6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -136,7 +136,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
137 137
138 Type returntype = m_comms.LookupReturnType(fname); 138 Type returntype = m_comms.LookupReturnType(fname);
139 if (returntype != typeof(string)) 139 if (returntype != typeof(void))
140 MODError(String.Format("return type mismatch for {0}",fname)); 140 MODError(String.Format("return type mismatch for {0}",fname));
141 141
142 modInvoke(fname,parms); 142 modInvoke(fname,parms);
@@ -329,6 +329,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 if (result != null) 329 if (result != null)
330 return result; 330 return result;
331 331
332 Type returntype = m_comms.LookupReturnType(fname);
333 if (returntype == typeof(void))
334 return null;
335
332 MODError(String.Format("Invocation of {0} failed; null return value",fname)); 336 MODError(String.Format("Invocation of {0} failed; null return value",fname));
333 } 337 }
334 catch (Exception e) 338 catch (Exception e)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 415166a..f4e4f44 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -139,6 +139,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
139 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 139 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
140 internal float m_ScriptDelayFactor = 1.0f; 140 internal float m_ScriptDelayFactor = 1.0f;
141 internal float m_ScriptDistanceFactor = 1.0f; 141 internal float m_ScriptDistanceFactor = 1.0f;
142 internal bool m_debuggerSafe = false;
142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 143 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
143 144
144 protected IUrlModule m_UrlModule = null; 145 protected IUrlModule m_UrlModule = null;
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
149 m_ScriptEngine = scriptEngine; 150 m_ScriptEngine = scriptEngine;
150 m_host = host; 151 m_host = host;
151 m_item = item; 152 m_item = item;
153 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
152 154
153 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 155 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
154 156
@@ -212,7 +214,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
212 214
213 internal void OSSLError(string msg) 215 internal void OSSLError(string msg)
214 { 216 {
215 throw new ScriptException("OSSL Runtime Error: " + msg); 217 if (m_debuggerSafe)
218 {
219 OSSLShoutError(msg);
220 }
221 else
222 {
223 throw new ScriptException("OSSL Runtime Error: " + msg);
224 }
216 } 225 }
217 226
218 /// <summary> 227 /// <summary>
@@ -931,18 +940,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
931 if (target != null) 940 if (target != null)
932 { 941 {
933 UUID animID=UUID.Zero; 942 UUID animID=UUID.Zero;
934 lock (m_host.TaskInventory) 943 m_host.TaskInventory.LockItemsForRead(true);
944 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
935 { 945 {
936 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 946 if (inv.Value.Name == animation)
937 { 947 {
938 if (inv.Value.Name == animation) 948 if (inv.Value.Type == (int)AssetType.Animation)
939 { 949 animID = inv.Value.AssetID;
940 if (inv.Value.Type == (int)AssetType.Animation) 950 continue;
941 animID = inv.Value.AssetID;
942 continue;
943 }
944 } 951 }
945 } 952 }
953 m_host.TaskInventory.LockItemsForRead(false);
946 if (animID == UUID.Zero) 954 if (animID == UUID.Zero)
947 target.Animator.AddAnimation(animation, m_host.UUID); 955 target.Animator.AddAnimation(animation, m_host.UUID);
948 else 956 else
@@ -983,6 +991,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
983 else 991 else
984 animID = UUID.Zero; 992 animID = UUID.Zero;
985 } 993 }
994 m_host.TaskInventory.LockItemsForRead(false);
986 995
987 if (animID == UUID.Zero) 996 if (animID == UUID.Zero)
988 target.Animator.RemoveAnimation(animation); 997 target.Animator.RemoveAnimation(animation);
@@ -1645,7 +1654,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1645 } 1654 }
1646 } 1655 }
1647 1656
1648 public Object osParseJSONNew(string JSON) 1657 private Object osParseJSONNew(string JSON)
1649 { 1658 {
1650 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew"); 1659 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew");
1651 1660
@@ -1847,15 +1856,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1847 { 1856 {
1848 UUID assetID = UUID.Zero; 1857 UUID assetID = UUID.Zero;
1849 1858
1850 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1859 bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID);
1860
1861 if (!notecardNameIsUUID)
1851 { 1862 {
1852 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1863 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1853 {
1854 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1855 {
1856 assetID = item.AssetID;
1857 }
1858 }
1859 } 1864 }
1860 1865
1861 if (assetID == UUID.Zero) 1866 if (assetID == UUID.Zero)
@@ -1866,7 +1871,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1866 AssetBase a = World.AssetService.Get(assetID.ToString()); 1871 AssetBase a = World.AssetService.Get(assetID.ToString());
1867 1872
1868 if (a == null) 1873 if (a == null)
1869 return UUID.Zero; 1874 {
1875 // Whoops, it's still possible here that the notecard name was properly
1876 // formatted like a UUID but isn't an asset UUID so lets look it up by name after all
1877 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1878 if (assetID == UUID.Zero)
1879 return UUID.Zero;
1880
1881 if (!NotecardCache.IsCached(assetID))
1882 {
1883 a = World.AssetService.Get(assetID.ToString());
1884
1885 if (a == null)
1886 {
1887 return UUID.Zero;
1888 }
1889 }
1890 }
1870 1891
1871 string data = Encoding.UTF8.GetString(a.Data); 1892 string data = Encoding.UTF8.GetString(a.Data);
1872 NotecardCache.Cache(assetID, data); 1893 NotecardCache.Cache(assetID, data);
@@ -1874,6 +1895,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1874 1895
1875 return assetID; 1896 return assetID;
1876 } 1897 }
1898 protected UUID SearchTaskInventoryForAssetId(string name)
1899 {
1900 UUID assetId = UUID.Zero;
1901 m_host.TaskInventory.LockItemsForRead(true);
1902 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1903 {
1904 if (item.Type == 7 && item.Name == name)
1905 {
1906 assetId = item.AssetID;
1907 }
1908 }
1909 m_host.TaskInventory.LockItemsForRead(false);
1910 return assetId;
1911 }
1877 1912
1878 /// <summary> 1913 /// <summary>
1879 /// Directly get an entire notecard at once. 1914 /// Directly get an entire notecard at once.
@@ -2351,7 +2386,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2351 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2386 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2352 m_host.AddScriptLPS(1); 2387 m_host.AddScriptLPS(1);
2353 2388
2354 return NpcCreate(firstname, lastname, position, notecard, false, false); 2389 return NpcCreate(firstname, lastname, position, notecard, true, false);
2355 } 2390 }
2356 2391
2357 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2392 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2362,24 +2397,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2362 return NpcCreate( 2397 return NpcCreate(
2363 firstname, lastname, position, notecard, 2398 firstname, lastname, position, notecard,
2364 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2399 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2365 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2400 false);
2401// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2366 } 2402 }
2367 2403
2368 private LSL_Key NpcCreate( 2404 private LSL_Key NpcCreate(
2369 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2405 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2370 { 2406 {
2407 if (!owned)
2408 OSSLError("Unowned NPCs are unsupported");
2409
2410 string groupTitle = String.Empty;
2411
2412 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2413 return new LSL_Key(UUID.Zero.ToString());
2414
2415 if (firstname != String.Empty || lastname != String.Empty)
2416 {
2417 if (firstname != "Shown outfit:")
2418 groupTitle = "- NPC -";
2419 }
2420
2371 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2421 INPCModule module = World.RequestModuleInterface<INPCModule>();
2372 if (module != null) 2422 if (module != null)
2373 { 2423 {
2374 AvatarAppearance appearance = null; 2424 AvatarAppearance appearance = null;
2375 2425
2376 UUID id; 2426// UUID id;
2377 if (UUID.TryParse(notecard, out id)) 2427// if (UUID.TryParse(notecard, out id))
2378 { 2428// {
2379 ScenePresence clonePresence = World.GetScenePresence(id); 2429// ScenePresence clonePresence = World.GetScenePresence(id);
2380 if (clonePresence != null) 2430// if (clonePresence != null)
2381 appearance = clonePresence.Appearance; 2431// appearance = clonePresence.Appearance;
2382 } 2432// }
2383 2433
2384 if (appearance == null) 2434 if (appearance == null)
2385 { 2435 {
@@ -2387,9 +2437,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2387 2437
2388 if (appearanceSerialized != null) 2438 if (appearanceSerialized != null)
2389 { 2439 {
2390 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2440 try
2391 appearance = new AvatarAppearance(); 2441 {
2392 appearance.Unpack(appearanceOsd); 2442 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2443 appearance = new AvatarAppearance();
2444 appearance.Unpack(appearanceOsd);
2445 }
2446 catch
2447 {
2448 return UUID.Zero.ToString();
2449 }
2393 } 2450 }
2394 else 2451 else
2395 { 2452 {
@@ -2408,6 +2465,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2408 World, 2465 World,
2409 appearance); 2466 appearance);
2410 2467
2468 ScenePresence sp;
2469 if (World.TryGetScenePresence(x, out sp))
2470 {
2471 sp.Grouptitle = groupTitle;
2472 sp.SendAvatarDataToAllAgents();
2473 }
2411 return new LSL_Key(x.ToString()); 2474 return new LSL_Key(x.ToString());
2412 } 2475 }
2413 2476
@@ -2705,16 +2768,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2705 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2768 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2706 m_host.AddScriptLPS(1); 2769 m_host.AddScriptLPS(1);
2707 2770
2708 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2771 ManualResetEvent ev = new ManualResetEvent(false);
2709 if (module != null)
2710 {
2711 UUID npcId = new UUID(npc.m_string);
2712 2772
2713 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2773 Util.FireAndForget(delegate(object x) {
2714 return; 2774 try
2775 {
2776 INPCModule module = World.RequestModuleInterface<INPCModule>();
2777 if (module != null)
2778 {
2779 UUID npcId = new UUID(npc.m_string);
2715 2780
2716 module.DeleteNPC(npcId, World); 2781 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2717 } 2782 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2783 {
2784 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2785 return;
2786 }
2787
2788 module.DeleteNPC(npcId, World);
2789 }
2790 }
2791 finally
2792 {
2793 ev.Set();
2794 }
2795 });
2796 ev.WaitOne();
2718 } 2797 }
2719 2798
2720 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2799 public void osNpcPlayAnimation(LSL_Key npc, string animation)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 88ab515..884f07c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -93,7 +93,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
93 private const int AGENT = 1; 93 private const int AGENT = 1;
94 private const int AGENT_BY_USERNAME = 0x10; 94 private const int AGENT_BY_USERNAME = 0x10;
95 private const int NPC = 0x20; 95 private const int NPC = 0x20;
96 private const int OS_NPC = 0x01000000;
97 private const int ACTIVE = 2; 96 private const int ACTIVE = 2;
98 private const int PASSIVE = 4; 97 private const int PASSIVE = 4;
99 private const int SCRIPTED = 8; 98 private const int SCRIPTED = 8;
@@ -240,7 +239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
240 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 239 List<SensedEntity> sensedEntities = new List<SensedEntity>();
241 240
242 // Is the sensor type is AGENT and not SCRIPTED then include agents 241 // Is the sensor type is AGENT and not SCRIPTED then include agents
243 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 242 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
244 { 243 {
245 sensedEntities.AddRange(doAgentSensor(ts)); 244 sensedEntities.AddRange(doAgentSensor(ts));
246 } 245 }
@@ -339,7 +338,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
339 float dy; 338 float dy;
340 float dz; 339 float dz;
341 340
342 Quaternion q = SensePoint.GetWorldRotation(); 341// Quaternion q = SensePoint.RotationOffset;
342 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
343 if (SensePoint.ParentGroup.IsAttachment) 343 if (SensePoint.ParentGroup.IsAttachment)
344 { 344 {
345 // In attachments, rotate the sensor cone with the 345 // In attachments, rotate the sensor cone with the
@@ -353,7 +353,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
353 // Position of a sensor in a child prim attached to an avatar 353 // Position of a sensor in a child prim attached to an avatar
354 // will be still wrong. 354 // will be still wrong.
355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
356 q = avatar.GetWorldRotation() * q; 356 fromRegionPos = avatar.AbsolutePosition;
357 q = avatar.Rotation;
357 } 358 }
358 359
359 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 360 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -480,7 +481,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
480 // Position of a sensor in a child prim attached to an avatar 481 // Position of a sensor in a child prim attached to an avatar
481 // will be still wrong. 482 // will be still wrong.
482 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 483 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
483 q = avatar.GetWorldRotation() * q; 484 if (avatar == null)
485 return sensedEntities;
486 fromRegionPos = avatar.AbsolutePosition;
487 q = avatar.Rotation;
484 } 488 }
485 489
486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 490 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -496,7 +500,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
496// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 500// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
497// presence.Name, presence.PresenceType, ts.name, ts.type); 501// presence.Name, presence.PresenceType, ts.name, ts.type);
498 502
499 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 503 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
500 { 504 {
501 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 505 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
502 if (npcData == null || !npcData.SenseAsAgent) 506 if (npcData == null || !npcData.SenseAsAgent)
@@ -696,4 +700,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
696 return retList; 700 return retList;
697 } 701 }
698 } 702 }
699} \ No newline at end of file 703}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index 0b14565..68aacd2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -123,25 +123,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
123 if (Timers.Count == 0) 123 if (Timers.Count == 0)
124 return; 124 return;
125 125
126 Dictionary<string, TimerInfo>.ValueCollection tvals;
126 lock (TimerListLock) 127 lock (TimerListLock)
127 { 128 {
128 // Go through all timers 129 // Go through all timers
129 Dictionary<string, TimerInfo>.ValueCollection tvals = Timers.Values; 130 tvals = Timers.Values;
130 foreach (TimerInfo ts in tvals) 131 }
132
133 foreach (TimerInfo ts in tvals)
134 {
135 // Time has passed?
136 if (ts.next < DateTime.Now.Ticks)
131 { 137 {
132 // Time has passed? 138 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
133 if (ts.next < DateTime.Now.Ticks) 139 // Add it to queue
134 { 140 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
135 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 141 new EventParams("timer", new Object[0],
136 // Add it to queue 142 new DetectParams[0]));
137 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 143 // set next interval
138 new EventParams("timer", new Object[0], 144
139 new DetectParams[0])); 145 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
140 // set next interval 146 ts.next = DateTime.Now.Ticks + ts.interval;
141
142 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
143 ts.next = DateTime.Now.Ticks + ts.interval;
144 }
145 } 147 }
146 } 148 }
147 } 149 }
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 4ac179a..9bf6f9b 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,11 @@ 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 void llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
211 LSL_String llTransferLindenDollars(string destination, int amount); 212 LSL_String llTransferLindenDollars(string destination, int amount);
212 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
213 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
@@ -331,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
331 void llSensorRemove(); 332 void llSensorRemove();
332 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);
333 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
334 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
335 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
336 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -357,11 +359,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
357 void llSetParcelMusicURL(string url); 359 void llSetParcelMusicURL(string url);
358 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 360 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
359 void llSetPos(LSL_Vector pos); 361 void llSetPos(LSL_Vector pos);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
360 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 363 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
361 void llSetPrimitiveParams(LSL_List rules); 364 void llSetPrimitiveParams(LSL_List rules);
362 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 365 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
363 void llSetPrimURL(string url); 366 void llSetPrimURL(string url);
364 LSL_Integer llSetRegionPos(LSL_Vector pos);
365 void llSetRemoteScriptAccessPin(int pin); 367 void llSetRemoteScriptAccessPin(int pin);
366 void llSetRot(LSL_Rotation rot); 368 void llSetRot(LSL_Rotation rot);
367 void llSetScale(LSL_Vector scale); 369 void llSetScale(LSL_Vector scale);
@@ -381,6 +383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
381 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 383 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
382 void llSetVehicleType(int type); 384 void llSetVehicleType(int type);
383 void llSetVehicleVectorParam(int param, LSL_Vector vec); 385 void llSetVehicleVectorParam(int param, LSL_Vector vec);
386 void llSetVelocity(LSL_Vector velocity, int local);
384 void llShout(int channelID, string text); 387 void llShout(int channelID, string text);
385 LSL_Float llSin(double f); 388 LSL_Float llSin(double f);
386 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 389 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -424,9 +427,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
424 LSL_Vector llWind(LSL_Vector offset); 427 LSL_Vector llWind(LSL_Vector offset);
425 LSL_String llXorBase64Strings(string str1, string str2); 428 LSL_String llXorBase64Strings(string str1, string str2);
426 LSL_String llXorBase64StringsCorrect(string str1, string str2); 429 LSL_String llXorBase64StringsCorrect(string str1, string str2);
427 void print(string str); 430 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
431 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
428 432
429 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); 433 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
430 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 435 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
431 } 436 }
432} 437}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 51d0581..a652cb8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -144,7 +144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
144 // Avatar Info Commands 144 // Avatar Info Commands
145 string osGetAgentIP(string agent); 145 string osGetAgentIP(string agent);
146 LSL_List osGetAgents(); 146 LSL_List osGetAgents();
147 147
148 // Teleport commands 148 // Teleport commands
149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
@@ -260,7 +260,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
260 string osGetScriptEngineName(); 260 string osGetScriptEngineName();
261 string osGetSimulatorVersion(); 261 string osGetSimulatorVersion();
262 string osGetPhysicsEngineType(); 262 string osGetPhysicsEngineType();
263 Object osParseJSONNew(string JSON);
264 Hashtable osParseJSON(string JSON); 263 Hashtable osParseJSON(string JSON);
265 264
266 void osMessageObject(key objectUUID,string message); 265 void osMessageObject(key objectUUID,string message);
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 bd66ba3..da3b31f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -56,7 +56,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
56 public const int ACTIVE = 2; 56 public const int ACTIVE = 2;
57 public const int PASSIVE = 4; 57 public const int PASSIVE = 4;
58 public const int SCRIPTED = 8; 58 public const int SCRIPTED = 8;
59 public const int OS_NPC = 0x01000000;
60 59
61 public const int CONTROL_FWD = 1; 60 public const int CONTROL_FWD = 1;
62 public const int CONTROL_BACK = 2; 61 public const int CONTROL_BACK = 2;
@@ -95,6 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
95 public const int AGENT_CROUCHING = 1024; 94 public const int AGENT_CROUCHING = 1024;
96 public const int AGENT_BUSY = 2048; 95 public const int AGENT_BUSY = 2048;
97 public const int AGENT_ALWAYS_RUN = 4096; 96 public const int AGENT_ALWAYS_RUN = 4096;
97 public const int AGENT_MALE = 8192;
98 98
99 //Particle Systems 99 //Particle Systems
100 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 100 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -337,6 +337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
337 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 337 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
338 public const int CHANGED_MEDIA = 2048; 338 public const int CHANGED_MEDIA = 2048;
339 public const int CHANGED_ANIMATION = 16384; 339 public const int CHANGED_ANIMATION = 16384;
340 public const int CHANGED_POSITION = 32768;
340 public const int TYPE_INVALID = 0; 341 public const int TYPE_INVALID = 0;
341 public const int TYPE_INTEGER = 1; 342 public const int TYPE_INTEGER = 1;
342 public const int TYPE_FLOAT = 2; 343 public const int TYPE_FLOAT = 2;
@@ -660,7 +661,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
660 public const int PRIM_MEDIA_PERM_OWNER = 1; 661 public const int PRIM_MEDIA_PERM_OWNER = 1;
661 public const int PRIM_MEDIA_PERM_GROUP = 2; 662 public const int PRIM_MEDIA_PERM_GROUP = 2;
662 public const int PRIM_MEDIA_PERM_ANYONE = 4; 663 public const int PRIM_MEDIA_PERM_ANYONE = 4;
663 664
664 public const int PRIM_PHYSICS_SHAPE_TYPE = 30; 665 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
665 public const int PRIM_PHYSICS_SHAPE_PRIM = 0; 666 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
666 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2; 667 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
@@ -671,7 +672,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
671 public const int FRICTION = 2; 672 public const int FRICTION = 2;
672 public const int RESTITUTION = 4; 673 public const int RESTITUTION = 4;
673 public const int GRAVITY_MULTIPLIER = 8; 674 public const int GRAVITY_MULTIPLIER = 8;
674 675
675 // extra constants for llSetPrimMediaParams 676 // extra constants for llSetPrimMediaParams
676 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 677 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
677 public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000); 678 public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000);
@@ -743,7 +744,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
743 744
744 public static readonly LSLInteger RCERR_UNKNOWN = -1; 745 public static readonly LSLInteger RCERR_UNKNOWN = -1;
745 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 746 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
746 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 747 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
748
749 public const int KFM_MODE = 1;
750 public const int KFM_LOOP = 1;
751 public const int KFM_REVERSE = 3;
752 public const int KFM_FORWARD = 0;
753 public const int KFM_PING_PONG = 2;
754 public const int KFM_DATA = 2;
755 public const int KFM_TRANSLATION = 2;
756 public const int KFM_ROTATION = 1;
757 public const int KFM_COMMAND = 0;
758 public const int KFM_CMD_PLAY = 0;
759 public const int KFM_CMD_STOP = 1;
760 public const int KFM_CMD_PAUSE = 2;
747 761
748 /// <summary> 762 /// <summary>
749 /// process name parameter as regex 763 /// process name parameter as regex
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index c7a7cf6..8ecc4f8 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();
@@ -869,9 +876,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
869 m_LSL_Functions.llGiveInventoryList(destination, category, inventory); 876 m_LSL_Functions.llGiveInventoryList(destination, category, inventory);
870 } 877 }
871 878
872 public void llGiveMoney(string destination, int amount) 879 public LSL_Integer llGiveMoney(string destination, int amount)
873 { 880 {
874 m_LSL_Functions.llGiveMoney(destination, amount); 881 return m_LSL_Functions.llGiveMoney(destination, amount);
875 } 882 }
876 883
877 public LSL_String llTransferLindenDollars(string destination, int amount) 884 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -1488,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1488 m_LSL_Functions.llSetAlpha(alpha, face); 1495 m_LSL_Functions.llSetAlpha(alpha, face);
1489 } 1496 }
1490 1497
1498 public void llSetAngularVelocity(LSL_Vector angvelocity, int local)
1499 {
1500 m_LSL_Functions.llSetAngularVelocity(angvelocity, local);
1501 }
1502
1491 public void llSetBuoyancy(double buoyancy) 1503 public void llSetBuoyancy(double buoyancy)
1492 { 1504 {
1493 m_LSL_Functions.llSetBuoyancy(buoyancy); 1505 m_LSL_Functions.llSetBuoyancy(buoyancy);
@@ -1613,6 +1625,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1613 m_LSL_Functions.llSetPos(pos); 1625 m_LSL_Functions.llSetPos(pos);
1614 } 1626 }
1615 1627
1628 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1629 {
1630 return m_LSL_Functions.llSetRegionPos(pos);
1631 }
1632
1616 public void llSetPrimitiveParams(LSL_List rules) 1633 public void llSetPrimitiveParams(LSL_List rules)
1617 { 1634 {
1618 m_LSL_Functions.llSetPrimitiveParams(rules); 1635 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1628,11 +1645,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1628 m_LSL_Functions.llSetPrimURL(url); 1645 m_LSL_Functions.llSetPrimURL(url);
1629 } 1646 }
1630 1647
1631 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1632 {
1633 return m_LSL_Functions.llSetRegionPos(pos);
1634 }
1635
1636 public void llSetRemoteScriptAccessPin(int pin) 1648 public void llSetRemoteScriptAccessPin(int pin)
1637 { 1649 {
1638 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1650 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1728,6 +1740,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1728 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1740 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1729 } 1741 }
1730 1742
1743 public void llSetVelocity(LSL_Vector velocity, int local)
1744 {
1745 m_LSL_Functions.llSetVelocity(velocity, local);
1746 }
1747
1731 public void llShout(int channelID, string text) 1748 public void llShout(int channelID, string text)
1732 { 1749 {
1733 m_LSL_Functions.llShout(channelID, text); 1750 m_LSL_Functions.llShout(channelID, text);
@@ -1978,9 +1995,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1978 return m_LSL_Functions.llClearLinkMedia(link, face); 1995 return m_LSL_Functions.llClearLinkMedia(link, face);
1979 } 1996 }
1980 1997
1981 public void print(string str) 1998 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1999 {
2000 return m_LSL_Functions.llGetLinkNumberOfSides(link);
2001 }
2002
2003 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
2004 {
2005 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2006 }
2007
2008 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1982 { 2009 {
1983 m_LSL_Functions.print(str); 2010 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1984 } 2011 }
1985 } 2012 }
1986} 2013}
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/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index c9902e4..b63773b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -435,11 +435,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
435 return m_OSSL_Functions.osParseJSON(JSON); 435 return m_OSSL_Functions.osParseJSON(JSON);
436 } 436 }
437 437
438 public Object osParseJSONNew(string JSON)
439 {
440 return m_OSSL_Functions.osParseJSONNew(JSON);
441 }
442
443 public void osMessageObject(key objectUUID,string message) 438 public void osMessageObject(key objectUUID,string message)
444 { 439 {
445 m_OSSL_Functions.osMessageObject(objectUUID,message); 440 m_OSSL_Functions.osMessageObject(objectUUID,message);
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);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index e02d35e..e44a106 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
39 40
40namespace OpenSim.Region.ScriptEngine.Shared 41namespace OpenSim.Region.ScriptEngine.Shared
@@ -120,6 +121,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
120 Type = 0; 121 Type = 0;
121 Velocity = new LSL_Types.Vector3(); 122 Velocity = new LSL_Types.Vector3();
122 initializeSurfaceTouch(); 123 initializeSurfaceTouch();
124 Country = String.Empty;
123 } 125 }
124 126
125 public UUID Key; 127 public UUID Key;
@@ -151,6 +153,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
151 private int touchFace; 153 private int touchFace;
152 public int TouchFace { get { return touchFace; } } 154 public int TouchFace { get { return touchFace; } }
153 155
156 public string Country;
157
154 // This can be done in two places including the constructor 158 // This can be done in two places including the constructor
155 // so be carefull what gets added here 159 // so be carefull what gets added here
156 private void initializeSurfaceTouch() 160 private void initializeSurfaceTouch()
@@ -198,6 +202,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
198 return; 202 return;
199 203
200 Name = presence.Firstname + " " + presence.Lastname; 204 Name = presence.Firstname + " " + presence.Lastname;
205 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
206 if (account != null)
207 Country = account.UserCountry;
208
201 Owner = Key; 209 Owner = Key;
202 Position = new LSL_Types.Vector3(presence.AbsolutePosition); 210 Position = new LSL_Types.Vector3(presence.AbsolutePosition);
203 Rotation = new LSL_Types.Quaternion( 211 Rotation = new LSL_Types.Quaternion(
@@ -207,22 +215,27 @@ namespace OpenSim.Region.ScriptEngine.Shared
207 presence.Rotation.W); 215 presence.Rotation.W);
208 Velocity = new LSL_Types.Vector3(presence.Velocity); 216 Velocity = new LSL_Types.Vector3(presence.Velocity);
209 217
210 if (presence.PresenceType != PresenceType.Npc) 218 Type = 0x01; // Avatar
211 { 219 if (presence.PresenceType == PresenceType.Npc)
212 Type = AGENT; 220 Type = 0x20;
213 } 221
214 else 222 // Cope Impl. We don't use OS_NPC.
215 { 223 //if (presence.PresenceType != PresenceType.Npc)
216 Type = OS_NPC; 224 //{
217 225 // Type = AGENT;
218 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 226 //}
219 INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); 227 //else
220 228 //{
221 if (npcData.SenseAsAgent) 229 // Type = OS_NPC;
222 { 230
223 Type |= AGENT; 231 // INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
224 } 232 // INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
225 } 233
234 // if (npcData.SenseAsAgent)
235 // {
236 // Type |= AGENT;
237 // }
238 //}
226 239
227 if (presence.Velocity != Vector3.Zero) 240 if (presence.Velocity != Vector3.Zero)
228 Type |= ACTIVE; 241 Type |= ACTIVE;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index bf19a42..26850c4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Reflection; 34using System.Reflection;
34using System.Runtime.Remoting; 35using System.Runtime.Remoting;
35using System.Runtime.Remoting.Lifetime; 36using System.Runtime.Remoting.Lifetime;
@@ -165,13 +166,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
165 166
166 public UUID ItemID { get; private set; } 167 public UUID ItemID { get; private set; }
167 168
168 public UUID ObjectID { get { return Part.UUID; } } 169 public UUID ObjectID { get; private set; }
169 170
170 public uint LocalID { get { return Part.LocalId; } } 171 public uint LocalID { get; private set; }
171 172
172 public UUID RootObjectID { get { return Part.ParentGroup.UUID; } } 173 public UUID RootObjectID { get; private set; }
173 174
174 public uint RootLocalID { get { return Part.ParentGroup.LocalId; } } 175 public uint RootLocalID { get; private set; }
175 176
176 public UUID AssetID { get; private set; } 177 public UUID AssetID { get; private set; }
177 178
@@ -235,8 +236,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
235 StartParam = startParam; 236 StartParam = startParam;
236 m_MaxScriptQueue = maxScriptQueue; 237 m_MaxScriptQueue = maxScriptQueue;
237 m_postOnRez = postOnRez; 238 m_postOnRez = postOnRez;
238 m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; 239 m_AttachedAvatar = part.ParentGroup.AttachedAvatar;
239 m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; 240 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID;
240 241
241 if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op") 242 if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op")
242 { 243 {
@@ -481,27 +482,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
481 PostEvent(new EventParams("attach", 482 PostEvent(new EventParams("attach",
482 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); 483 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0]));
483 } 484 }
485
484 } 486 }
485 } 487 }
486 488
487 private void ReleaseControls() 489 private void ReleaseControls()
488 { 490 {
489 int permsMask; 491 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
490 UUID permsGranter; 492
491 lock (Part.TaskInventory) 493 if (part != null)
492 { 494 {
493 if (!Part.TaskInventory.ContainsKey(ItemID)) 495 int permsMask;
496 UUID permsGranter;
497 part.TaskInventory.LockItemsForRead(true);
498 if (!part.TaskInventory.ContainsKey(ItemID))
499 {
500 part.TaskInventory.LockItemsForRead(false);
494 return; 501 return;
502 }
503 permsGranter = part.TaskInventory[ItemID].PermsGranter;
504 permsMask = part.TaskInventory[ItemID].PermsMask;
505 part.TaskInventory.LockItemsForRead(false);
495 506
496 permsGranter = Part.TaskInventory[ItemID].PermsGranter; 507 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
497 permsMask = Part.TaskInventory[ItemID].PermsMask; 508 {
498 } 509 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
499 510 if (presence != null)
500 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 511 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
501 { 512 }
502 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
503 if (presence != null)
504 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
505 } 513 }
506 } 514 }
507 515
@@ -650,6 +658,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
650 return true; 658 return true;
651 } 659 }
652 660
661 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
653 public void SetState(string state) 662 public void SetState(string state)
654 { 663 {
655 if (state == State) 664 if (state == State)
@@ -661,7 +670,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
661 new DetectParams[0])); 670 new DetectParams[0]));
662 PostEvent(new EventParams("state_entry", new Object[0], 671 PostEvent(new EventParams("state_entry", new Object[0],
663 new DetectParams[0])); 672 new DetectParams[0]));
664 673
665 throw new EventAbortException(); 674 throw new EventAbortException();
666 } 675 }
667 676
@@ -751,57 +760,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
751 /// <returns></returns> 760 /// <returns></returns>
752 public object EventProcessor() 761 public object EventProcessor()
753 { 762 {
763 EventParams data = null;
754 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 764 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
755 if (!Running) 765 if (!Running)
756 return 0; 766 return 0;
757 767
758 lock (m_Script)
759 {
760// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 768// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
761 769
762 if (Suspended) 770 if (Suspended)
763 return 0; 771 return 0;
764
765 EventParams data = null;
766 772
767 lock (EventQueue) 773 lock (EventQueue)
774 {
775 data = (EventParams) EventQueue.Dequeue();
776 if (data == null) // Shouldn't happen
768 { 777 {
769 data = (EventParams)EventQueue.Dequeue(); 778 if (EventQueue.Count > 0 && Running && !ShuttingDown)
770 if (data == null) // Shouldn't happen
771 { 779 {
772 if (EventQueue.Count > 0 && Running && !ShuttingDown) 780 m_CurrentWorkItem = Engine.QueueEventHandler(this);
773 {
774 m_CurrentWorkItem = Engine.QueueEventHandler(this);
775 }
776 else
777 {
778 m_CurrentWorkItem = null;
779 }
780 return 0;
781 } 781 }
782 782 else
783 if (data.EventName == "timer")
784 m_TimerQueued = false;
785 if (data.EventName == "control")
786 { 783 {
787 if (m_ControlEventsInQueue > 0) 784 m_CurrentWorkItem = null;
788 m_ControlEventsInQueue--;
789 } 785 }
790 if (data.EventName == "collision") 786 return 0;
791 m_CollisionInQueue = false;
792 } 787 }
793 788
789 if (data.EventName == "timer")
790 m_TimerQueued = false;
791 if (data.EventName == "control")
792 {
793 if (m_ControlEventsInQueue > 0)
794 m_ControlEventsInQueue--;
795 }
796 if (data.EventName == "collision")
797 m_CollisionInQueue = false;
798 }
799
800 lock(m_Script)
801 {
802
803// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
804 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
805
794 if (DebugLevel >= 2) 806 if (DebugLevel >= 2)
795 m_log.DebugFormat( 807 m_log.DebugFormat(
796 "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", 808 "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}",
797 data.EventName, 809 data.EventName,
798 ScriptName, 810 ScriptName,
799 Part.Name, 811 part.Name,
800 Part.LocalId, 812 part.LocalId,
801 Part.ParentGroup.Name, 813 part.ParentGroup.Name,
802 Part.ParentGroup.UUID, 814 part.ParentGroup.UUID,
803 Part.AbsolutePosition, 815 part.AbsolutePosition,
804 Part.ParentGroup.Scene.Name); 816 part.ParentGroup.Scene.Name);
805 817
806 m_DetectParams = data.DetectParams; 818 m_DetectParams = data.DetectParams;
807 819
@@ -814,17 +826,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
814 "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", 826 "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}",
815 State, 827 State,
816 ScriptName, 828 ScriptName,
817 Part.Name, 829 part.Name,
818 Part.LocalId, 830 part.LocalId,
819 Part.ParentGroup.Name, 831 part.ParentGroup.Name,
820 Part.ParentGroup.UUID, 832 part.ParentGroup.UUID,
821 Part.AbsolutePosition, 833 part.AbsolutePosition,
822 Part.ParentGroup.Scene.Name); 834 part.ParentGroup.Scene.Name);
823 835
824 AsyncCommandManager.RemoveScript(Engine, 836 AsyncCommandManager.RemoveScript(Engine,
825 LocalID, ItemID); 837 LocalID, ItemID);
826 838
827 Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); 839 if (part != null)
840 {
841 part.SetScriptEvents(ItemID,
842 (int)m_Script.GetStateEventFlags(State));
843 }
828 } 844 }
829 else 845 else
830 { 846 {
@@ -887,17 +903,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
887 text = text.Substring(0, 1000); 903 text = text.Substring(0, 1000);
888 Engine.World.SimChat(Utils.StringToBytes(text), 904 Engine.World.SimChat(Utils.StringToBytes(text),
889 ChatTypeEnum.DebugChannel, 2147483647, 905 ChatTypeEnum.DebugChannel, 2147483647,
890 Part.AbsolutePosition, 906 part.AbsolutePosition,
891 Part.Name, Part.UUID, false); 907 part.Name, part.UUID, false);
892 908
893 909
894 m_log.DebugFormat( 910 m_log.DebugFormat(
895 "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", 911 "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}",
896 ScriptName, 912 ScriptName,
897 PrimName, 913 PrimName,
898 Part.UUID, 914 part.UUID,
899 Part.AbsolutePosition, 915 part.AbsolutePosition,
900 Part.ParentGroup.Scene.Name, 916 part.ParentGroup.Scene.Name,
901 text.Replace("\n", "\\n"), 917 text.Replace("\n", "\\n"),
902 e.InnerException); 918 e.InnerException);
903 } 919 }
@@ -917,12 +933,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
917 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) 933 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
918 { 934 {
919 m_InSelfDelete = true; 935 m_InSelfDelete = true;
920 Engine.World.DeleteSceneObject(Part.ParentGroup, false); 936 if (part != null)
937 Engine.World.DeleteSceneObject(part.ParentGroup, false);
921 } 938 }
922 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) 939 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
923 { 940 {
924 m_InSelfDelete = true; 941 m_InSelfDelete = true;
925 Part.Inventory.RemoveInventoryItem(ItemID); 942 if (part != null)
943 part.Inventory.RemoveInventoryItem(ItemID);
926 } 944 }
927 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) 945 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException))
928 { 946 {
@@ -976,14 +994,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
976 ReleaseControls(); 994 ReleaseControls();
977 995
978 Stop(timeout); 996 Stop(timeout);
979 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 997 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
980 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 998 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
999 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
1000 part.CollisionSound = UUID.Zero;
981 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 1001 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
982 EventQueue.Clear(); 1002 EventQueue.Clear();
983 m_Script.ResetVars(); 1003 m_Script.ResetVars();
984 State = "default"; 1004 State = "default";
985 1005
986 Part.SetScriptEvents(ItemID, 1006 part.SetScriptEvents(ItemID,
987 (int)m_Script.GetStateEventFlags(State)); 1007 (int)m_Script.GetStateEventFlags(State));
988 if (running) 1008 if (running)
989 Start(); 1009 Start();
@@ -992,6 +1012,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
992 new Object[0], new DetectParams[0])); 1012 new Object[0], new DetectParams[0]));
993 } 1013 }
994 1014
1015 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
995 public void ApiResetScript() 1016 public void ApiResetScript()
996 { 1017 {
997 // bool running = Running; 1018 // bool running = Running;
@@ -1000,15 +1021,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1000 ReleaseControls(); 1021 ReleaseControls();
1001 1022
1002 m_Script.ResetVars(); 1023 m_Script.ResetVars();
1003 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 1024 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
1004 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 1025 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
1026 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
1027 part.CollisionSound = UUID.Zero;
1005 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 1028 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
1006 1029
1007 EventQueue.Clear(); 1030 EventQueue.Clear();
1008 m_Script.ResetVars(); 1031 m_Script.ResetVars();
1009 State = "default"; 1032 State = "default";
1010 1033
1011 Part.SetScriptEvents(ItemID, 1034 part.SetScriptEvents(ItemID,
1012 (int)m_Script.GetStateEventFlags(State)); 1035 (int)m_Script.GetStateEventFlags(State));
1013 1036
1014 if (m_CurrentEvent != "state_entry") 1037 if (m_CurrentEvent != "state_entry")
@@ -1022,10 +1045,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1022 1045
1023 public Dictionary<string, object> GetVars() 1046 public Dictionary<string, object> GetVars()
1024 { 1047 {
1025 if (m_Script != null) 1048 return m_Script.GetVars();
1026 return m_Script.GetVars();
1027 else
1028 return new Dictionary<string, object>();
1029 } 1049 }
1030 1050
1031 public void SetVars(Dictionary<string, object> vars) 1051 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 44fdd1a..b524a18 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -102,19 +102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
102 102
103 public override string ToString() 103 public override string ToString()
104 { 104 {
105 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 105 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
106 return s; 106 return s;
107 } 107 }
108 108
109 public static explicit operator LSLString(Vector3 vec) 109 public static explicit operator LSLString(Vector3 vec)
110 { 110 {
111 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 111 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
112 return new LSLString(s); 112 return new LSLString(s);
113 } 113 }
114 114
115 public static explicit operator string(Vector3 vec) 115 public static explicit operator string(Vector3 vec)
116 { 116 {
117 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 117 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
118 return s; 118 return s;
119 } 119 }
120 120
@@ -389,19 +389,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
389 389
390 public override string ToString() 390 public override string ToString()
391 { 391 {
392 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 392 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
393 return st; 393 return st;
394 } 394 }
395 395
396 public static explicit operator string(Quaternion r) 396 public static explicit operator string(Quaternion r)
397 { 397 {
398 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 398 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
399 return s; 399 return s;
400 } 400 }
401 401
402 public static explicit operator LSLString(Quaternion r) 402 public static explicit operator LSLString(Quaternion r)
403 { 403 {
404 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 404 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
405 return new LSLString(s); 405 return new LSLString(s);
406 } 406 }
407 407
@@ -512,7 +512,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
512 else if (o is LSL_Types.LSLFloat) 512 else if (o is LSL_Types.LSLFloat)
513 size += 8; 513 size += 8;
514 else if (o is LSL_Types.LSLString) 514 else if (o is LSL_Types.LSLString)
515 size += ((LSL_Types.LSLString)o).m_string.Length; 515 size += ((LSL_Types.LSLString)o).m_string == null ? 0 : ((LSL_Types.LSLString)o).m_string.Length;
516 else if (o is LSL_Types.key) 516 else if (o is LSL_Types.key)
517 size += ((LSL_Types.key)o).value.Length; 517 size += ((LSL_Types.key)o).value.Length;
518 else if (o is LSL_Types.Vector3) 518 else if (o is LSL_Types.Vector3)
@@ -521,6 +521,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
521 size += 64; 521 size += 64;
522 else if (o is int) 522 else if (o is int)
523 size += 4; 523 size += 4;
524 else if (o is uint)
525 size += 4;
524 else if (o is string) 526 else if (o is string)
525 size += ((string)o).Length; 527 size += ((string)o).Length;
526 else if (o is float) 528 else if (o is float)
@@ -711,24 +713,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
711 713
712 public static bool operator ==(list a, list b) 714 public static bool operator ==(list a, list b)
713 { 715 {
714 int la = -1; 716 int la = a.Length;
715 int lb = -1; 717 int lb = b.Length;
716 try { la = a.Length; }
717 catch (NullReferenceException) { }
718 try { lb = b.Length; }
719 catch (NullReferenceException) { }
720 718
721 return la == lb; 719 return la == lb;
722 } 720 }
723 721
724 public static bool operator !=(list a, list b) 722 public static bool operator !=(list a, list b)
725 { 723 {
726 int la = -1; 724 int la = a.Length;
727 int lb = -1; 725 int lb = b.Length;
728 try { la = a.Length; }
729 catch (NullReferenceException) { }
730 try {lb = b.Length;}
731 catch (NullReferenceException) { }
732 726
733 return la != lb; 727 return la != lb;
734 } 728 }
@@ -962,7 +956,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
962 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 956 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
963 } 957 }
964 958
965 if (ascending == 0) 959 if (ascending != 1)
966 { 960 {
967 ret = 0 - ret; 961 ret = 0 - ret;
968 } 962 }
@@ -995,6 +989,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
995 stride = 1; 989 stride = 1;
996 } 990 }
997 991
992 if ((Data.Length % stride) != 0)
993 return new list(ret);
994
998 // we can optimize here in the case where stride == 1 and the list 995 // we can optimize here in the case where stride == 1 and the list
999 // consists of homogeneous types 996 // consists of homogeneous types
1000 997
@@ -1014,7 +1011,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1014 if (homogeneous) 1011 if (homogeneous)
1015 { 1012 {
1016 Array.Sort(ret, new HomogeneousComparer()); 1013 Array.Sort(ret, new HomogeneousComparer());
1017 if (ascending == 0) 1014 if (ascending != 1)
1018 { 1015 {
1019 Array.Reverse(ret); 1016 Array.Reverse(ret);
1020 } 1017 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 8931be4..17243ab 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -28,6 +28,7 @@
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.Globalization; 32using System.Globalization;
32using System.IO; 33using System.IO;
33using System.Linq; 34using System.Linq;
@@ -148,6 +149,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
148 private Dictionary<UUID, IScriptInstance> m_Scripts = 149 private Dictionary<UUID, IScriptInstance> m_Scripts =
149 new Dictionary<UUID, IScriptInstance>(); 150 new Dictionary<UUID, IScriptInstance>();
150 151
152 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
153
151 // Maps the asset ID to the assembly 154 // Maps the asset ID to the assembly
152 155
153 private Dictionary<UUID, string> m_Assemblies = 156 private Dictionary<UUID, string> m_Assemblies =
@@ -170,6 +173,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
170 IWorkItemResult m_CurrentCompile = null; 173 IWorkItemResult m_CurrentCompile = null;
171 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 174 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
172 175
176 private void lockScriptsForRead(bool locked)
177 {
178 if (locked)
179 {
180 if (m_scriptsLock.RecursiveReadCount > 0)
181 {
182 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
183 m_scriptsLock.ExitReadLock();
184 }
185 if (m_scriptsLock.RecursiveWriteCount > 0)
186 {
187 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
188 m_scriptsLock.ExitWriteLock();
189 }
190
191 while (!m_scriptsLock.TryEnterReadLock(60000))
192 {
193 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
194 if (m_scriptsLock.IsWriteLockHeld)
195 {
196 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
197 }
198 }
199 }
200 else
201 {
202 if (m_scriptsLock.RecursiveReadCount > 0)
203 {
204 m_scriptsLock.ExitReadLock();
205 }
206 }
207 }
208 private void lockScriptsForWrite(bool locked)
209 {
210 if (locked)
211 {
212 if (m_scriptsLock.RecursiveReadCount > 0)
213 {
214 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
215 m_scriptsLock.ExitReadLock();
216 }
217 if (m_scriptsLock.RecursiveWriteCount > 0)
218 {
219 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
220 m_scriptsLock.ExitWriteLock();
221 }
222
223 while (!m_scriptsLock.TryEnterWriteLock(60000))
224 {
225 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
226 if (m_scriptsLock.IsWriteLockHeld)
227 {
228 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
229 }
230 }
231 }
232 else
233 {
234 if (m_scriptsLock.RecursiveWriteCount > 0)
235 {
236 m_scriptsLock.ExitWriteLock();
237 }
238 }
239 }
240
173 private ScriptEngineConsoleCommands m_consoleCommands; 241 private ScriptEngineConsoleCommands m_consoleCommands;
174 242
175 public string ScriptEngineName 243 public string ScriptEngineName
@@ -699,64 +767,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine
699 { 767 {
700 if (!m_Enabled) 768 if (!m_Enabled)
701 return; 769 return;
770 lockScriptsForRead(true);
702 771
703 lock (m_Scripts) 772 List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values);
704 {
705 m_log.InfoFormat(
706 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName);
707 773
708 foreach (IScriptInstance instance in m_Scripts.Values) 774// foreach (IScriptInstance instance in m_Scripts.Values)
775 foreach (IScriptInstance instance in instancesToDel)
776 {
777 // Force a final state save
778 //
779 if (m_Assemblies.ContainsKey(instance.AssetID))
709 { 780 {
710 // Force a final state save 781 string assembly = m_Assemblies[instance.AssetID];
711 //
712 if (m_Assemblies.ContainsKey(instance.AssetID))
713 {
714 string assembly = m_Assemblies[instance.AssetID];
715 782
716 try 783 try
717 { 784 {
718 instance.SaveState(assembly); 785 instance.SaveState(assembly);
719 }
720 catch (Exception e)
721 {
722 m_log.Error(
723 string.Format(
724 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
725 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
726 , e);
727 }
728 } 786 }
787 catch (Exception e)
788 {
789 m_log.Error(
790 string.Format(
791 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
792 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
793 , e);
794 }
795 }
729 796
730 // Clear the event queue and abort the instance thread 797 // Clear the event queue and abort the instance thread
731 // 798 //
732 instance.ClearQueue(); 799 instance.ClearQueue();
733 instance.Stop(0); 800 instance.Stop(0);
734 801
735 // Release events, timer, etc 802 // Release events, timer, etc
736 // 803 //
737 instance.DestroyScriptInstance(); 804 instance.DestroyScriptInstance();
738 805
739 // Unload scripts and app domains. 806 // Unload scripts and app domains
740 // Must be done explicitly because they have infinite 807 // Must be done explicitly because they have infinite
741 // lifetime. 808 // lifetime
742 // However, don't bother to do this if the simulator is shutting 809 //
743 // down since it takes a long time with many scripts. 810// if (!m_SimulatorShuttingDown)
744 if (!m_SimulatorShuttingDown) 811 {
812 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
813 if (m_DomainScripts[instance.AppDomain].Count == 0)
745 { 814 {
746 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 815 m_DomainScripts.Remove(instance.AppDomain);
747 if (m_DomainScripts[instance.AppDomain].Count == 0) 816 UnloadAppDomain(instance.AppDomain);
748 {
749 m_DomainScripts.Remove(instance.AppDomain);
750 UnloadAppDomain(instance.AppDomain);
751 }
752 } 817 }
753 } 818 }
754 819
755 m_Scripts.Clear(); 820// m_Scripts.Clear();
756 m_PrimObjects.Clear(); 821// m_PrimObjects.Clear();
757 m_Assemblies.Clear(); 822// m_Assemblies.Clear();
758 m_DomainScripts.Clear(); 823// m_DomainScripts.Clear();
759 } 824 }
825 lockScriptsForRead(false);
826 lockScriptsForWrite(true);
827 m_Scripts.Clear();
828 lockScriptsForWrite(false);
829 m_PrimObjects.Clear();
830 m_Assemblies.Clear();
831 m_DomainScripts.Clear();
832
760 lock (m_ScriptEngines) 833 lock (m_ScriptEngines)
761 { 834 {
762 m_ScriptEngines.Remove(this); 835 m_ScriptEngines.Remove(this);
@@ -825,22 +898,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
825 898
826 List<IScriptInstance> instances = new List<IScriptInstance>(); 899 List<IScriptInstance> instances = new List<IScriptInstance>();
827 900
828 lock (m_Scripts) 901 lockScriptsForRead(true);
829 { 902 foreach (IScriptInstance instance in m_Scripts.Values)
830 foreach (IScriptInstance instance in m_Scripts.Values)
831 instances.Add(instance); 903 instances.Add(instance);
832 } 904 lockScriptsForRead(false);
833 905
834 foreach (IScriptInstance i in instances) 906 foreach (IScriptInstance i in instances)
835 { 907 {
836 string assembly = String.Empty; 908 string assembly = String.Empty;
837 909
838 lock (m_Scripts) 910
839 {
840 if (!m_Assemblies.ContainsKey(i.AssetID)) 911 if (!m_Assemblies.ContainsKey(i.AssetID))
841 continue; 912 continue;
842 assembly = m_Assemblies[i.AssetID]; 913 assembly = m_Assemblies[i.AssetID];
843 } 914
844 915
845 try 916 try
846 { 917 {
@@ -1244,97 +1315,93 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1244 } 1315 }
1245 1316
1246 ScriptInstance instance = null; 1317 ScriptInstance instance = null;
1247 lock (m_Scripts) 1318 // Create the object record
1319 lockScriptsForRead(true);
1320 if ((!m_Scripts.ContainsKey(itemID)) ||
1321 (m_Scripts[itemID].AssetID != assetID))
1248 { 1322 {
1249 // Create the object record 1323 lockScriptsForRead(false);
1250 if ((!m_Scripts.ContainsKey(itemID)) ||
1251 (m_Scripts[itemID].AssetID != assetID))
1252 {
1253 UUID appDomain = assetID;
1254 1324
1255 if (part.ParentGroup.IsAttachment) 1325 UUID appDomain = assetID;
1256 appDomain = part.ParentGroup.RootPart.UUID;
1257 1326
1258 if (!m_AppDomains.ContainsKey(appDomain)) 1327 if (part.ParentGroup.IsAttachment)
1259 { 1328 appDomain = part.ParentGroup.RootPart.UUID;
1260 try
1261 {
1262 AppDomainSetup appSetup = new AppDomainSetup();
1263 appSetup.PrivateBinPath = Path.Combine(
1264 m_ScriptEnginesPath,
1265 m_Scene.RegionInfo.RegionID.ToString());
1266 1329
1267 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1330 if (!m_AppDomains.ContainsKey(appDomain))
1268 Evidence evidence = new Evidence(baseEvidence); 1331 {
1332 try
1333 {
1334 AppDomainSetup appSetup = new AppDomainSetup();
1335 appSetup.PrivateBinPath = Path.Combine(
1336 m_ScriptEnginesPath,
1337 m_Scene.RegionInfo.RegionID.ToString());
1269 1338
1270 AppDomain sandbox; 1339 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1271 if (m_AppDomainLoading) 1340 Evidence evidence = new Evidence(baseEvidence);
1272 {
1273 sandbox = AppDomain.CreateDomain(
1274 m_Scene.RegionInfo.RegionID.ToString(),
1275 evidence, appSetup);
1276 sandbox.AssemblyResolve +=
1277 new ResolveEventHandler(
1278 AssemblyResolver.OnAssemblyResolve);
1279 }
1280 else
1281 {
1282 sandbox = AppDomain.CurrentDomain;
1283 }
1284
1285 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1286 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1287 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1288 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1289 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1290 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1291 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1292
1293 m_AppDomains[appDomain] = sandbox;
1294 1341
1295 m_DomainScripts[appDomain] = new List<UUID>(); 1342 AppDomain sandbox;
1343 if (m_AppDomainLoading)
1344 {
1345 sandbox = AppDomain.CreateDomain(
1346 m_Scene.RegionInfo.RegionID.ToString(),
1347 evidence, appSetup);
1348 m_AppDomains[appDomain].AssemblyResolve +=
1349 new ResolveEventHandler(
1350 AssemblyResolver.OnAssemblyResolve);
1296 } 1351 }
1297 catch (Exception e) 1352 else
1298 { 1353 {
1299 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1354 sandbox = AppDomain.CurrentDomain;
1300 m_ScriptErrorMessage += "Exception creating app domain:\n";
1301 m_ScriptFailCount++;
1302 lock (m_AddingAssemblies)
1303 {
1304 m_AddingAssemblies[assembly]--;
1305 }
1306 return false;
1307 } 1355 }
1308 }
1309 m_DomainScripts[appDomain].Add(itemID);
1310
1311 instance = new ScriptInstance(this, part,
1312 item,
1313 startParam, postOnRez,
1314 m_MaxScriptQueue);
1315 1356
1316 if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) 1357 if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource))
1317 return false; 1358 return false;
1318 1359
1319// if (DebugLevel >= 1) 1360 m_AppDomains[appDomain] = sandbox;
1320// m_log.DebugFormat(
1321// "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1322// part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1323// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1324 1361
1325 if (presence != null) 1362 m_DomainScripts[appDomain] = new List<UUID>();
1363 }
1364 catch (Exception e)
1326 { 1365 {
1327 ShowScriptSaveResponse(item.OwnerID, 1366 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1328 assetID, "Compile successful", true); 1367 m_ScriptErrorMessage += "Exception creating app domain:\n";
1368 m_ScriptFailCount++;
1369 lock (m_AddingAssemblies)
1370 {
1371 m_AddingAssemblies[assembly]--;
1372 }
1373 return false;
1329 } 1374 }
1375 }
1376 m_DomainScripts[appDomain].Add(itemID);
1377
1378 instance = new ScriptInstance(this, part,
1379 item,
1380 startParam, postOnRez,
1381 m_MaxScriptQueue);
1330 1382
1331 instance.AppDomain = appDomain; 1383 instance.Load(m_AppDomains[appDomain], assembly, stateSource);
1332 instance.LineMap = linemap; 1384// m_log.DebugFormat(
1385// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1386// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1387// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1333 1388
1334 m_Scripts[itemID] = instance; 1389 if (presence != null)
1390 {
1391 ShowScriptSaveResponse(item.OwnerID,
1392 assetID, "Compile successful", true);
1335 } 1393 }
1336 }
1337 1394
1395 instance.AppDomain = appDomain;
1396 instance.LineMap = linemap;
1397 lockScriptsForWrite(true);
1398 m_Scripts[itemID] = instance;
1399 lockScriptsForWrite(false);
1400 }
1401 else
1402 {
1403 lockScriptsForRead(false);
1404 }
1338 lock (m_PrimObjects) 1405 lock (m_PrimObjects)
1339 { 1406 {
1340 if (!m_PrimObjects.ContainsKey(localID)) 1407 if (!m_PrimObjects.ContainsKey(localID))
@@ -1352,7 +1419,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1352 m_AddingAssemblies[assembly]--; 1419 m_AddingAssemblies[assembly]--;
1353 } 1420 }
1354 1421
1355 if (instance != null) 1422 if (instance!=null)
1356 instance.Init(); 1423 instance.Init();
1357 1424
1358 bool runIt; 1425 bool runIt;
@@ -1375,18 +1442,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1375 m_CompileDict.Remove(itemID); 1442 m_CompileDict.Remove(itemID);
1376 } 1443 }
1377 1444
1378 IScriptInstance instance = null; 1445 lockScriptsForRead(true);
1379 1446 // Do we even have it?
1380 lock (m_Scripts) 1447 if (!m_Scripts.ContainsKey(itemID))
1381 { 1448 {
1382 // Do we even have it? 1449 // Do we even have it?
1383 if (!m_Scripts.ContainsKey(itemID)) 1450 if (!m_Scripts.ContainsKey(itemID))
1384 return; 1451 return;
1385 1452
1386 instance = m_Scripts[itemID]; 1453 lockScriptsForRead(false);
1454 lockScriptsForWrite(true);
1387 m_Scripts.Remove(itemID); 1455 m_Scripts.Remove(itemID);
1456 lockScriptsForWrite(false);
1457
1458 return;
1388 } 1459 }
1460
1389 1461
1462 IScriptInstance instance=m_Scripts[itemID];
1463 lockScriptsForRead(false);
1464 lockScriptsForWrite(true);
1465 m_Scripts.Remove(itemID);
1466 lockScriptsForWrite(false);
1390 instance.ClearQueue(); 1467 instance.ClearQueue();
1391 1468
1392 instance.Stop(m_WaitForEventCompletionOnScriptStop); 1469 instance.Stop(m_WaitForEventCompletionOnScriptStop);
@@ -1423,8 +1500,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1423 1500
1424 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1501 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1425 if (handlerObjectRemoved != null) 1502 if (handlerObjectRemoved != null)
1426 handlerObjectRemoved(instance.ObjectID); 1503 {
1504 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1505 handlerObjectRemoved(part.UUID);
1506 }
1427 1507
1508 CleanAssemblies();
1509
1428 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1510 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1429 if (handlerScriptRemoved != null) 1511 if (handlerScriptRemoved != null)
1430 handlerScriptRemoved(itemID); 1512 handlerScriptRemoved(itemID);
@@ -1685,12 +1767,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1685 private IScriptInstance GetInstance(UUID itemID) 1767 private IScriptInstance GetInstance(UUID itemID)
1686 { 1768 {
1687 IScriptInstance instance; 1769 IScriptInstance instance;
1688 lock (m_Scripts) 1770 lockScriptsForRead(true);
1771 if (!m_Scripts.ContainsKey(itemID))
1689 { 1772 {
1690 if (!m_Scripts.ContainsKey(itemID)) 1773 lockScriptsForRead(false);
1691 return null; 1774 return null;
1692 instance = m_Scripts[itemID];
1693 } 1775 }
1776 instance = m_Scripts[itemID];
1777 lockScriptsForRead(false);
1694 return instance; 1778 return instance;
1695 } 1779 }
1696 1780
@@ -1714,6 +1798,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1714 return false; 1798 return false;
1715 } 1799 }
1716 1800
1801 [DebuggerNonUserCode]
1717 public void ApiResetScript(UUID itemID) 1802 public void ApiResetScript(UUID itemID)
1718 { 1803 {
1719 IScriptInstance instance = GetInstance(itemID); 1804 IScriptInstance instance = GetInstance(itemID);
@@ -1775,6 +1860,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1775 return UUID.Zero; 1860 return UUID.Zero;
1776 } 1861 }
1777 1862
1863 [DebuggerNonUserCode]
1778 public void SetState(UUID itemID, string newState) 1864 public void SetState(UUID itemID, string newState)
1779 { 1865 {
1780 IScriptInstance instance = GetInstance(itemID); 1866 IScriptInstance instance = GetInstance(itemID);
@@ -1797,11 +1883,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1797 1883
1798 List<IScriptInstance> instances = new List<IScriptInstance>(); 1884 List<IScriptInstance> instances = new List<IScriptInstance>();
1799 1885
1800 lock (m_Scripts) 1886 lockScriptsForRead(true);
1801 { 1887 foreach (IScriptInstance instance in m_Scripts.Values)
1802 foreach (IScriptInstance instance in m_Scripts.Values)
1803 instances.Add(instance); 1888 instances.Add(instance);
1804 } 1889 lockScriptsForRead(false);
1805 1890
1806 foreach (IScriptInstance i in instances) 1891 foreach (IScriptInstance i in instances)
1807 { 1892 {