aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-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.cs3146
-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.cs37
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs363
21 files changed, 3240 insertions, 1116 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 19eec71..d634805 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;
70 74
71namespace OpenSim.Region.ScriptEngine.Shared.Api 75namespace OpenSim.Region.ScriptEngine.Shared.Api
72{ 76{
@@ -113,17 +117,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
113 protected int m_notecardLineReadCharsMax = 255; 117 protected int m_notecardLineReadCharsMax = 255;
114 protected int m_scriptConsoleChannel = 0; 118 protected int m_scriptConsoleChannel = 0;
115 protected bool m_scriptConsoleChannelEnabled = false; 119 protected bool m_scriptConsoleChannelEnabled = false;
120 protected bool m_debuggerSafe = false;
116 protected IUrlModule m_UrlModule = null; 121 protected IUrlModule m_UrlModule = null;
117 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 122 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
118 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 123 new Dictionary<UUID, UserInfoCacheEntry>();
124 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
119 protected ISoundModule m_SoundModule = null; 125 protected ISoundModule m_SoundModule = null;
120 126
127// protected Timer m_ShoutSayTimer;
128 protected int m_SayShoutCount = 0;
129 DateTime m_lastSayShoutCheck;
130
131 private Dictionary<string, string> MovementAnimationsForLSL =
132 new Dictionary<string, string> {
133 {"FLY", "Flying"},
134 {"FLYSLOW", "FlyingSlow"},
135 {"HOVER_UP", "Hovering Up"},
136 {"HOVER_DOWN", "Hovering Down"},
137 {"HOVER", "Hovering"},
138 {"LAND", "Landing"},
139 {"FALLDOWN", "Falling Down"},
140 {"PREJUMP", "PreJumping"},
141 {"JUMP", "Jumping"},
142 {"STANDUP", "Standing Up"},
143 {"SOFT_LAND", "Soft Landing"},
144 {"STAND", "Standing"},
145 {"CROUCHWALK", "CrouchWalking"},
146 {"RUN", "Running"},
147 {"WALK", "Walking"},
148 {"CROUCH", "Crouching"},
149 {"TURNLEFT", "Turning Left"},
150 {"TURNRIGHT", "Turning Right"}
151 };
152
121 public void Initialize( 153 public void Initialize(
122 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) 154 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
123 { 155 {
156 m_lastSayShoutCheck = DateTime.UtcNow;
157
124 m_ScriptEngine = scriptEngine; 158 m_ScriptEngine = scriptEngine;
125 m_host = host; 159 m_host = host;
126 m_item = item; 160 m_item = item;
161 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
127 m_coopSleepHandle = coopSleepHandle; 162 m_coopSleepHandle = coopSleepHandle;
128 163
129 LoadConfig(); 164 LoadConfig();
@@ -212,6 +247,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
212 get { return m_ScriptEngine.World; } 247 get { return m_ScriptEngine.World; }
213 } 248 }
214 249
250 [DebuggerNonUserCode]
215 public void state(string newState) 251 public void state(string newState)
216 { 252 {
217 m_ScriptEngine.SetState(m_item.ItemID, newState); 253 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -221,6 +257,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
221 /// Reset the named script. The script must be present 257 /// Reset the named script. The script must be present
222 /// in the same prim. 258 /// in the same prim.
223 /// </summary> 259 /// </summary>
260 [DebuggerNonUserCode]
224 public void llResetScript() 261 public void llResetScript()
225 { 262 {
226 m_host.AddScriptLPS(1); 263 m_host.AddScriptLPS(1);
@@ -283,6 +320,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
283 } 320 }
284 } 321 }
285 322
323 public List<ScenePresence> GetLinkAvatars(int linkType)
324 {
325 List<ScenePresence> ret = new List<ScenePresence>();
326 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
327 return ret;
328
329 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
330
331 switch (linkType)
332 {
333 case ScriptBaseClass.LINK_SET:
334 return avs;
335
336 case ScriptBaseClass.LINK_ROOT:
337 return ret;
338
339 case ScriptBaseClass.LINK_ALL_OTHERS:
340 return avs;
341
342 case ScriptBaseClass.LINK_ALL_CHILDREN:
343 return avs;
344
345 case ScriptBaseClass.LINK_THIS:
346 return ret;
347
348 default:
349 if (linkType < 0)
350 return ret;
351
352 int partCount = m_host.ParentGroup.GetPartCount();
353
354 if (linkType <= partCount)
355 {
356 return ret;
357 }
358 else
359 {
360 linkType = linkType - partCount;
361 if (linkType > avs.Count)
362 {
363 return ret;
364 }
365 else
366 {
367 ret.Add(avs[linkType-1]);
368 return ret;
369 }
370 }
371 }
372 }
373
286 public List<SceneObjectPart> GetLinkParts(int linkType) 374 public List<SceneObjectPart> GetLinkParts(int linkType)
287 { 375 {
288 return GetLinkParts(m_host, linkType); 376 return GetLinkParts(m_host, linkType);
@@ -291,6 +379,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
291 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 379 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
292 { 380 {
293 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 381 List<SceneObjectPart> ret = new List<SceneObjectPart>();
382 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
383 return ret;
294 ret.Add(part); 384 ret.Add(part);
295 385
296 switch (linkType) 386 switch (linkType)
@@ -444,31 +534,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
444 534
445 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 535 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
446 536
447 /// <summary> 537 // Utility function for llRot2Euler
448 /// Convert an LSL rotation to a Euler vector. 538
449 /// </summary> 539 // normalize an angle between -PI and PI (-180 to +180 degrees)
450 /// <remarks> 540 protected double NormalizeAngle(double angle)
451 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
452 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
453 /// </remarks>
454 /// <param name="r"></param>
455 /// <returns></returns>
456 public LSL_Vector llRot2Euler(LSL_Rotation r)
457 { 541 {
458 m_host.AddScriptLPS(1); 542 if (angle > -Math.PI && angle < Math.PI)
543 return angle;
459 544
460 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 545 int numPis = (int)(Math.PI / angle);
461 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 546 double remainder = angle - Math.PI * numPis;
462 if (m == 0.0) return new LSL_Vector(); 547 if (numPis % 2 == 1)
463 double x = Math.Atan2(-v.y, v.z); 548 return Math.PI - angle;
464 double sin = v.x / m; 549 return remainder;
465 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 550 }
466 double y = Math.Asin(sin);
467 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
468 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)));
469 double z = Math.Atan2(v.y, v.x);
470 551
471 return new LSL_Vector(x, y, z); 552 public LSL_Vector llRot2Euler(LSL_Rotation q1)
553 {
554 m_host.AddScriptLPS(1);
555 LSL_Vector eul = new LSL_Vector();
556
557 double sqw = q1.s*q1.s;
558 double sqx = q1.x*q1.x;
559 double sqy = q1.z*q1.z;
560 double sqz = q1.y*q1.y;
561 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
562 double test = q1.x*q1.z + q1.y*q1.s;
563 if (test > 0.4999*unit) { // singularity at north pole
564 eul.z = 2 * Math.Atan2(q1.x,q1.s);
565 eul.y = Math.PI/2;
566 eul.x = 0;
567 return eul;
568 }
569 if (test < -0.4999*unit) { // singularity at south pole
570 eul.z = -2 * Math.Atan2(q1.x,q1.s);
571 eul.y = -Math.PI/2;
572 eul.x = 0;
573 return eul;
574 }
575 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
576 eul.y = Math.Asin(2*test/unit);
577 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
578 return eul;
472 } 579 }
473 580
474 /* From wiki: 581 /* From wiki:
@@ -521,18 +628,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
521 m_host.AddScriptLPS(1); 628 m_host.AddScriptLPS(1);
522 629
523 double x,y,z,s; 630 double x,y,z,s;
524 631 v.x *= 0.5;
525 double c1 = Math.Cos(v.x * 0.5); 632 v.y *= 0.5;
526 double c2 = Math.Cos(v.y * 0.5); 633 v.z *= 0.5;
527 double c3 = Math.Cos(v.z * 0.5); 634 double c1 = Math.Cos(v.x);
528 double s1 = Math.Sin(v.x * 0.5); 635 double c2 = Math.Cos(v.y);
529 double s2 = Math.Sin(v.y * 0.5); 636 double c1c2 = c1 * c2;
530 double s3 = Math.Sin(v.z * 0.5); 637 double s1 = Math.Sin(v.x);
531 638 double s2 = Math.Sin(v.y);
532 x = s1 * c2 * c3 + c1 * s2 * s3; 639 double s1s2 = s1 * s2;
533 y = c1 * s2 * c3 - s1 * c2 * s3; 640 double c1s2 = c1 * s2;
534 z = s1 * s2 * c3 + c1 * c2 * s3; 641 double s1c2 = s1 * c2;
535 s = c1 * c2 * c3 - s1 * s2 * s3; 642 double c3 = Math.Cos(v.z);
643 double s3 = Math.Sin(v.z);
644
645 x = s1c2 * c3 + c1s2 * s3;
646 y = c1s2 * c3 - s1c2 * s3;
647 z = s1s2 * c3 + c1c2 * s3;
648 s = c1c2 * c3 - s1s2 * s3;
536 649
537 return new LSL_Rotation(x, y, z, s); 650 return new LSL_Rotation(x, y, z, s);
538 } 651 }
@@ -670,77 +783,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
670 { 783 {
671 //A and B should both be normalized 784 //A and B should both be normalized
672 m_host.AddScriptLPS(1); 785 m_host.AddScriptLPS(1);
673 LSL_Rotation rotBetween; 786 /* This method is more accurate than the SL one, and thus causes problems
674 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 787 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
675 // continue calculation. 788
676 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 789 double dotProduct = LSL_Vector.Dot(a, b);
790 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
791 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
792 double angle = Math.Acos(dotProduct / magProduct);
793 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
794 double s = Math.Sin(angle / 2);
795
796 double x = axis.x * s;
797 double y = axis.y * s;
798 double z = axis.z * s;
799 double w = Math.Cos(angle / 2);
800
801 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
802 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
803
804 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
805 */
806
807 // This method mimics the 180 errors found in SL
808 // See www.euclideanspace.com... angleBetween
809 LSL_Vector vec_a = a;
810 LSL_Vector vec_b = b;
811
812 // Eliminate zero length
813 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
814 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
815 if (vec_a_mag < 0.00001 ||
816 vec_b_mag < 0.00001)
677 { 817 {
678 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 818 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
679 } 819 }
680 else 820
821 // Normalize
822 vec_a = llVecNorm(vec_a);
823 vec_b = llVecNorm(vec_b);
824
825 // Calculate axis and rotation angle
826 LSL_Vector axis = vec_a % vec_b;
827 LSL_Float cos_theta = vec_a * vec_b;
828
829 // Check if parallel
830 if (cos_theta > 0.99999)
681 { 831 {
682 a = LSL_Vector.Norm(a); 832 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
683 b = LSL_Vector.Norm(b); 833 }
684 double dotProduct = LSL_Vector.Dot(a, b); 834
685 // There are two degenerate cases possible. These are for vectors 180 or 835 // Check if anti-parallel
686 // 0 degrees apart. These have to be detected and handled individually. 836 else if (cos_theta < -0.99999)
687 // 837 {
688 // Check for vectors 180 degrees apart. 838 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
689 // A dot product of -1 would mean the angle between vectors is 180 degrees. 839 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
690 if (dotProduct < -0.9999999f) 840 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
691 { 841 }
692 // First assume X axis is orthogonal to the vectors. 842 else // other rotation
693 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 843 {
694 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 844 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
695 // Check for near zero vector. A very small non-zero number here will create 845 axis = llVecNorm(axis);
696 // a rotation in an undesired direction. 846 double x, y, z, s, t;
697 if (LSL_Vector.Mag(orthoVector) > 0.0001) 847 s = Math.Cos(theta);
698 { 848 t = Math.Sin(theta);
699 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 849 x = axis.x * t;
700 } 850 y = axis.y * t;
701 // If the magnitude of the vector was near zero, then assume the X axis is not 851 z = axis.z * t;
702 // orthogonal and use the Z axis instead. 852 return new LSL_Rotation(x,y,z,s);
703 else
704 {
705 // Set 180 z rotation.
706 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
707 }
708 }
709 // Check for parallel vectors.
710 // A dot product of 1 would mean the angle between vectors is 0 degrees.
711 else if (dotProduct > 0.9999999f)
712 {
713 // Set zero rotation.
714 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
715 }
716 else
717 {
718 // All special checks have been performed so get the axis of rotation.
719 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
720 // Quarternion s value is the length of the unit vector + dot product.
721 double qs = 1.0 + dotProduct;
722 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
723 // Normalize the rotation.
724 double mag = LSL_Rotation.Mag(rotBetween);
725 // We shouldn't have to worry about a divide by zero here. The qs value will be
726 // non-zero because we already know if we're here, then the dotProduct is not -1 so
727 // qs will not be zero. Also, we've already handled the input vectors being zero so the
728 // crossProduct vector should also not be zero.
729 rotBetween.x = rotBetween.x / mag;
730 rotBetween.y = rotBetween.y / mag;
731 rotBetween.z = rotBetween.z / mag;
732 rotBetween.s = rotBetween.s / mag;
733 // Check for undefined values and set zero rotation if any found. This code might not actually be required
734 // any longer since zero vectors are checked for at the top.
735 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
736 {
737 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
738 }
739 }
740 } 853 }
741 return rotBetween;
742 } 854 }
743 855
744 public void llWhisper(int channelID, string text) 856 public void llWhisper(int channelID, string text)
745 { 857 {
746 m_host.AddScriptLPS(1); 858 m_host.AddScriptLPS(1);
@@ -756,10 +868,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
756 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 868 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
757 } 869 }
758 870
871 private void CheckSayShoutTime()
872 {
873 DateTime now = DateTime.UtcNow;
874 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
875 {
876 m_lastSayShoutCheck = now;
877 m_SayShoutCount = 0;
878 }
879 else
880 m_SayShoutCount++;
881 }
882
759 public void llSay(int channelID, string text) 883 public void llSay(int channelID, string text)
760 { 884 {
761 m_host.AddScriptLPS(1); 885 m_host.AddScriptLPS(1);
762 886
887 if (channelID == 0)
888// m_SayShoutCount++;
889 CheckSayShoutTime();
890
891 if (m_SayShoutCount >= 11)
892 ScriptSleep(2000);
893
763 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 894 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
764 { 895 {
765 Console.WriteLine(text); 896 Console.WriteLine(text);
@@ -782,6 +913,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
782 { 913 {
783 m_host.AddScriptLPS(1); 914 m_host.AddScriptLPS(1);
784 915
916 if (channelID == 0)
917// m_SayShoutCount++;
918 CheckSayShoutTime();
919
920 if (m_SayShoutCount >= 11)
921 ScriptSleep(2000);
922
785 if (text.Length > 1023) 923 if (text.Length > 1023)
786 text = text.Substring(0, 1023); 924 text = text.Substring(0, 1023);
787 925
@@ -813,22 +951,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
813 951
814 public void llRegionSayTo(string target, int channel, string msg) 952 public void llRegionSayTo(string target, int channel, string msg)
815 { 953 {
954 string error = String.Empty;
955
816 if (msg.Length > 1023) 956 if (msg.Length > 1023)
817 msg = msg.Substring(0, 1023); 957 msg = msg.Substring(0, 1023);
818 958
819 m_host.AddScriptLPS(1); 959 m_host.AddScriptLPS(1);
820 960
821 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
822 {
823 return;
824 }
825
826 UUID TargetID; 961 UUID TargetID;
827 UUID.TryParse(target, out TargetID); 962 UUID.TryParse(target, out TargetID);
828 963
829 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 964 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
830 if (wComm != null) 965 if (wComm != null)
831 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 966 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
967 LSLError(error);
832 } 968 }
833 969
834 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 970 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1084,10 +1220,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1084 return detectedParams.TouchUV; 1220 return detectedParams.TouchUV;
1085 } 1221 }
1086 1222
1223 [DebuggerNonUserCode]
1087 public virtual void llDie() 1224 public virtual void llDie()
1088 { 1225 {
1089 m_host.AddScriptLPS(1); 1226 m_host.AddScriptLPS(1);
1090 throw new SelfDeleteException(); 1227 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1091 } 1228 }
1092 1229
1093 public LSL_Float llGround(LSL_Vector offset) 1230 public LSL_Float llGround(LSL_Vector offset)
@@ -1158,6 +1295,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1158 1295
1159 public void llSetStatus(int status, int value) 1296 public void llSetStatus(int status, int value)
1160 { 1297 {
1298 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1299 return;
1161 m_host.AddScriptLPS(1); 1300 m_host.AddScriptLPS(1);
1162 1301
1163 int statusrotationaxis = 0; 1302 int statusrotationaxis = 0;
@@ -1181,6 +1320,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1181 if (!allow) 1320 if (!allow)
1182 return; 1321 return;
1183 1322
1323 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1324 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1325 return;
1326
1184 m_host.ScriptSetPhysicsStatus(true); 1327 m_host.ScriptSetPhysicsStatus(true);
1185 } 1328 }
1186 else 1329 else
@@ -1381,6 +1524,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1381 { 1524 {
1382 m_host.AddScriptLPS(1); 1525 m_host.AddScriptLPS(1);
1383 1526
1527 SetColor(m_host, color, face);
1528 }
1529
1530 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1531 {
1532 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1533 return;
1534
1535 Primitive.TextureEntry tex = part.Shape.Textures;
1536 Color4 texcolor;
1537 if (face >= 0 && face < GetNumberOfSides(part))
1538 {
1539 texcolor = tex.CreateFace((uint)face).RGBA;
1540 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1541 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1542 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1543 tex.FaceTextures[face].RGBA = texcolor;
1544 part.UpdateTextureEntry(tex.GetBytes());
1545 return;
1546 }
1547 else if (face == ScriptBaseClass.ALL_SIDES)
1548 {
1549 for (uint i = 0; i < GetNumberOfSides(part); i++)
1550 {
1551 if (tex.FaceTextures[i] != null)
1552 {
1553 texcolor = tex.FaceTextures[i].RGBA;
1554 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1555 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1556 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1557 tex.FaceTextures[i].RGBA = texcolor;
1558 }
1559 texcolor = tex.DefaultTexture.RGBA;
1560 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1561 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1562 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1563 tex.DefaultTexture.RGBA = texcolor;
1564 }
1565 part.UpdateTextureEntry(tex.GetBytes());
1566 return;
1567 }
1568
1384 if (face == ScriptBaseClass.ALL_SIDES) 1569 if (face == ScriptBaseClass.ALL_SIDES)
1385 face = SceneObjectPart.ALL_SIDES; 1570 face = SceneObjectPart.ALL_SIDES;
1386 1571
@@ -1389,6 +1574,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1389 1574
1390 public void SetTexGen(SceneObjectPart part, int face,int style) 1575 public void SetTexGen(SceneObjectPart part, int face,int style)
1391 { 1576 {
1577 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1578 return;
1579
1392 Primitive.TextureEntry tex = part.Shape.Textures; 1580 Primitive.TextureEntry tex = part.Shape.Textures;
1393 MappingType textype; 1581 MappingType textype;
1394 textype = MappingType.Default; 1582 textype = MappingType.Default;
@@ -1419,6 +1607,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1419 1607
1420 public void SetGlow(SceneObjectPart part, int face, float glow) 1608 public void SetGlow(SceneObjectPart part, int face, float glow)
1421 { 1609 {
1610 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1611 return;
1612
1422 Primitive.TextureEntry tex = part.Shape.Textures; 1613 Primitive.TextureEntry tex = part.Shape.Textures;
1423 if (face >= 0 && face < GetNumberOfSides(part)) 1614 if (face >= 0 && face < GetNumberOfSides(part))
1424 { 1615 {
@@ -1444,6 +1635,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1444 1635
1445 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1636 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1446 { 1637 {
1638 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1639 return;
1447 1640
1448 Shininess sval = new Shininess(); 1641 Shininess sval = new Shininess();
1449 1642
@@ -1494,6 +1687,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1494 1687
1495 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1688 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1496 { 1689 {
1690 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1691 return;
1692
1497 Primitive.TextureEntry tex = part.Shape.Textures; 1693 Primitive.TextureEntry tex = part.Shape.Textures;
1498 if (face >= 0 && face < GetNumberOfSides(part)) 1694 if (face >= 0 && face < GetNumberOfSides(part))
1499 { 1695 {
@@ -1554,13 +1750,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1554 m_host.AddScriptLPS(1); 1750 m_host.AddScriptLPS(1);
1555 1751
1556 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1752 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1557 1753 if (parts.Count > 0)
1558 foreach (SceneObjectPart part in parts) 1754 {
1559 SetAlpha(part, alpha, face); 1755 try
1756 {
1757 foreach (SceneObjectPart part in parts)
1758 SetAlpha(part, alpha, face);
1759 }
1760 finally
1761 {
1762 }
1763 }
1560 } 1764 }
1561 1765
1562 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1766 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1563 { 1767 {
1768 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1769 return;
1770
1564 Primitive.TextureEntry tex = part.Shape.Textures; 1771 Primitive.TextureEntry tex = part.Shape.Textures;
1565 Color4 texcolor; 1772 Color4 texcolor;
1566 if (face >= 0 && face < GetNumberOfSides(part)) 1773 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1613,7 +1820,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1613 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1820 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1614 float wind, float tension, LSL_Vector Force) 1821 float wind, float tension, LSL_Vector Force)
1615 { 1822 {
1616 if (part == null) 1823 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1617 return; 1824 return;
1618 1825
1619 if (flexi) 1826 if (flexi)
@@ -1654,7 +1861,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1654 /// <param name="falloff"></param> 1861 /// <param name="falloff"></param>
1655 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1862 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1656 { 1863 {
1657 if (part == null) 1864 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1658 return; 1865 return;
1659 1866
1660 if (light) 1867 if (light)
@@ -1687,11 +1894,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1687 Primitive.TextureEntry tex = part.Shape.Textures; 1894 Primitive.TextureEntry tex = part.Shape.Textures;
1688 Color4 texcolor; 1895 Color4 texcolor;
1689 LSL_Vector rgb = new LSL_Vector(); 1896 LSL_Vector rgb = new LSL_Vector();
1897 int nsides = GetNumberOfSides(part);
1898
1690 if (face == ScriptBaseClass.ALL_SIDES) 1899 if (face == ScriptBaseClass.ALL_SIDES)
1691 { 1900 {
1692 int i; 1901 int i;
1693 1902 for (i = 0; i < nsides; i++)
1694 for (i = 0 ; i < GetNumberOfSides(part); i++)
1695 { 1903 {
1696 texcolor = tex.GetFace((uint)i).RGBA; 1904 texcolor = tex.GetFace((uint)i).RGBA;
1697 rgb.x += texcolor.R; 1905 rgb.x += texcolor.R;
@@ -1699,14 +1907,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1699 rgb.z += texcolor.B; 1907 rgb.z += texcolor.B;
1700 } 1908 }
1701 1909
1702 rgb.x /= (float)GetNumberOfSides(part); 1910 float invnsides = 1.0f / (float)nsides;
1703 rgb.y /= (float)GetNumberOfSides(part); 1911
1704 rgb.z /= (float)GetNumberOfSides(part); 1912 rgb.x *= invnsides;
1913 rgb.y *= invnsides;
1914 rgb.z *= invnsides;
1705 1915
1706 return rgb; 1916 return rgb;
1707 } 1917 }
1708 1918 if (face >= 0 && face < nsides)
1709 if (face >= 0 && face < GetNumberOfSides(part))
1710 { 1919 {
1711 texcolor = tex.GetFace((uint)face).RGBA; 1920 texcolor = tex.GetFace((uint)face).RGBA;
1712 rgb.x = texcolor.R; 1921 rgb.x = texcolor.R;
@@ -1733,15 +1942,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1733 m_host.AddScriptLPS(1); 1942 m_host.AddScriptLPS(1);
1734 1943
1735 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1944 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1736 1945 if (parts.Count > 0)
1737 foreach (SceneObjectPart part in parts) 1946 {
1738 SetTexture(part, texture, face); 1947 try
1739 1948 {
1949 foreach (SceneObjectPart part in parts)
1950 SetTexture(part, texture, face);
1951 }
1952 finally
1953 {
1954 }
1955 }
1740 ScriptSleep(200); 1956 ScriptSleep(200);
1741 } 1957 }
1742 1958
1743 protected void SetTexture(SceneObjectPart part, string texture, int face) 1959 protected void SetTexture(SceneObjectPart part, string texture, int face)
1744 { 1960 {
1961 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1962 return;
1963
1745 UUID textureID = new UUID(); 1964 UUID textureID = new UUID();
1746 1965
1747 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 1966 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
@@ -1786,6 +2005,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1786 2005
1787 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2006 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1788 { 2007 {
2008 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2009 return;
2010
1789 Primitive.TextureEntry tex = part.Shape.Textures; 2011 Primitive.TextureEntry tex = part.Shape.Textures;
1790 if (face >= 0 && face < GetNumberOfSides(part)) 2012 if (face >= 0 && face < GetNumberOfSides(part))
1791 { 2013 {
@@ -1822,6 +2044,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1822 2044
1823 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2045 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1824 { 2046 {
2047 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2048 return;
2049
1825 Primitive.TextureEntry tex = part.Shape.Textures; 2050 Primitive.TextureEntry tex = part.Shape.Textures;
1826 if (face >= 0 && face < GetNumberOfSides(part)) 2051 if (face >= 0 && face < GetNumberOfSides(part))
1827 { 2052 {
@@ -1858,6 +2083,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1858 2083
1859 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2084 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1860 { 2085 {
2086 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2087 return;
2088
1861 Primitive.TextureEntry tex = part.Shape.Textures; 2089 Primitive.TextureEntry tex = part.Shape.Textures;
1862 if (face >= 0 && face < GetNumberOfSides(part)) 2090 if (face >= 0 && face < GetNumberOfSides(part))
1863 { 2091 {
@@ -1999,7 +2227,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1999 return end; 2227 return end;
2000 } 2228 }
2001 2229
2002 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2230 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2003 { 2231 {
2004 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2232 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2005 return fromPos; 2233 return fromPos;
@@ -2015,9 +2243,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2015 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2243 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2016 targetPos.z = ground; 2244 targetPos.z = ground;
2017 } 2245 }
2018 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2246 if (adjust)
2247 return SetPosAdjust(fromPos, targetPos);
2019 2248
2020 return real_vec; 2249 return targetPos;
2021 } 2250 }
2022 2251
2023 /// <summary> 2252 /// <summary>
@@ -2028,27 +2257,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2028 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2257 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2029 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2258 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2030 { 2259 {
2031 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2260 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2261 return;
2262
2032 LSL_Vector currentPos = GetPartLocalPos(part); 2263 LSL_Vector currentPos = GetPartLocalPos(part);
2264 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2033 2265
2034 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2035 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2036 2266
2037 if (part.ParentGroup.RootPart == part) 2267 if (part.ParentGroup.RootPart == part)
2038 { 2268 {
2039 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2040 targetPos.z = ground;
2041 SceneObjectGroup parent = part.ParentGroup; 2269 SceneObjectGroup parent = part.ParentGroup;
2042 parent.UpdateGroupPosition(!adjust ? targetPos : 2270 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2043 SetPosAdjust(currentPos, targetPos)); 2271 return;
2272 Util.FireAndForget(delegate(object x) {
2273 parent.UpdateGroupPosition((Vector3)toPos);
2274 });
2044 } 2275 }
2045 else 2276 else
2046 { 2277 {
2047 part.OffsetPosition = !adjust ? targetPos : 2278 part.OffsetPosition = (Vector3)toPos;
2048 SetPosAdjust(currentPos, targetPos); 2279// SceneObjectGroup parent = part.ParentGroup;
2049 SceneObjectGroup parent = part.ParentGroup; 2280// parent.HasGroupChanged = true;
2050 parent.HasGroupChanged = true; 2281// parent.ScheduleGroupForTerseUpdate();
2051 parent.ScheduleGroupForTerseUpdate(); 2282 part.ScheduleTerseUpdate();
2052 } 2283 }
2053 } 2284 }
2054 2285
@@ -2077,13 +2308,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2077 else 2308 else
2078 { 2309 {
2079 if (part.ParentGroup.IsAttachment) 2310 if (part.ParentGroup.IsAttachment)
2080 {
2081 pos = part.AttachedPos; 2311 pos = part.AttachedPos;
2082 }
2083 else 2312 else
2084 {
2085 pos = part.AbsolutePosition; 2313 pos = part.AbsolutePosition;
2086 }
2087 } 2314 }
2088 2315
2089// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2316// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2095,8 +2322,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2095 { 2322 {
2096 m_host.AddScriptLPS(1); 2323 m_host.AddScriptLPS(1);
2097 2324
2325
2326 // 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
2327 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2328 // 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.
2329 // RootPart != null should shortcircuit
2330
2098 // try to let this work as in SL... 2331 // try to let this work as in SL...
2099 if (m_host.ParentID == 0) 2332 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2100 { 2333 {
2101 // special case: If we are root, rotate complete SOG to new rotation 2334 // special case: If we are root, rotate complete SOG to new rotation
2102 SetRot(m_host, rot); 2335 SetRot(m_host, rot);
@@ -2123,25 +2356,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2123 2356
2124 protected void SetRot(SceneObjectPart part, Quaternion rot) 2357 protected void SetRot(SceneObjectPart part, Quaternion rot)
2125 { 2358 {
2126 part.UpdateRotation(rot); 2359 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2127 // Update rotation does not move the object in the physics scene if it's a linkset. 2360 return;
2128 2361
2129//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2362 bool isroot = (part == part.ParentGroup.RootPart);
2130// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2363 bool isphys;
2131 2364
2132 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2133 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2134 // It's perfectly okay when the object is not an active physical body though.
2135 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2136 // but only if the object is not physial and active. This is important for rotating doors.
2137 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2138 // scene
2139 PhysicsActor pa = part.PhysActor; 2365 PhysicsActor pa = part.PhysActor;
2140 2366
2141 if (pa != null && !pa.IsPhysical) 2367 // keep using physactor ideia of isphysical
2368 // it should be SOP ideia of that
2369 // not much of a issue with ubitODE
2370 if (pa != null && pa.IsPhysical)
2371 isphys = true;
2372 else
2373 isphys = false;
2374
2375 // SL doesn't let scripts rotate root of physical linksets
2376 if (isroot && isphys)
2377 return;
2378
2379 part.UpdateRotation(rot);
2380
2381 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2382 // so do a nasty update of parts positions if is a root part rotation
2383 if (isroot && pa != null) // with if above implies non physical root part
2142 { 2384 {
2143 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2385 part.ParentGroup.ResetChildPrimPhysicsPositions();
2144 } 2386 }
2387 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2388 {
2389 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2390 if (sittingavas.Count > 0)
2391 {
2392 foreach (ScenePresence av in sittingavas)
2393 {
2394 if (isroot || part.LocalId == av.ParentID)
2395 av.SendTerseUpdateToAllClients();
2396 }
2397 }
2398 }
2145 } 2399 }
2146 2400
2147 /// <summary> 2401 /// <summary>
@@ -2158,6 +2412,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2158 2412
2159 m_host.AddScriptLPS(1); 2413 m_host.AddScriptLPS(1);
2160 Quaternion q = m_host.GetWorldRotation(); 2414 Quaternion q = m_host.GetWorldRotation();
2415
2416 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2417 {
2418 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2419 if (avatar != null)
2420 {
2421 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2422 q = avatar.CameraRotation * q; // Mouselook
2423 else
2424 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2425 }
2426 }
2427
2161 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2428 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2162 } 2429 }
2163 2430
@@ -2185,14 +2452,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2185 return new LSL_Rotation(q); 2452 return new LSL_Rotation(q);
2186 } 2453 }
2187 2454
2188 return new LSL_Rotation(part.GetWorldRotation()); 2455 q = part.GetWorldRotation();
2456 if (part.ParentGroup.AttachmentPoint != 0)
2457 {
2458 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2459 if (avatar != null)
2460 {
2461 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2462 q = avatar.CameraRotation * q; // Mouselook
2463 else
2464 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2465 }
2466 }
2467
2468 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2189 } 2469 }
2190 2470
2191 public LSL_Rotation llGetLocalRot() 2471 public LSL_Rotation llGetLocalRot()
2192 { 2472 {
2193 m_host.AddScriptLPS(1); 2473 return GetPartLocalRot(m_host);
2474 }
2194 2475
2195 return new LSL_Rotation(m_host.RotationOffset); 2476 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2477 {
2478 m_host.AddScriptLPS(1);
2479 Quaternion rot = part.RotationOffset;
2480 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2196 } 2481 }
2197 2482
2198 public void llSetForce(LSL_Vector force, int local) 2483 public void llSetForce(LSL_Vector force, int local)
@@ -2272,16 +2557,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2272 m_host.ApplyImpulse(v, local != 0); 2557 m_host.ApplyImpulse(v, local != 0);
2273 } 2558 }
2274 2559
2560
2275 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2561 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2276 { 2562 {
2277 m_host.AddScriptLPS(1); 2563 m_host.AddScriptLPS(1);
2278 m_host.ApplyAngularImpulse(force, local != 0); 2564 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2279 } 2565 }
2280 2566
2281 public void llSetTorque(LSL_Vector torque, int local) 2567 public void llSetTorque(LSL_Vector torque, int local)
2282 { 2568 {
2283 m_host.AddScriptLPS(1); 2569 m_host.AddScriptLPS(1);
2284 m_host.SetAngularImpulse(torque, local != 0); 2570 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2285 } 2571 }
2286 2572
2287 public LSL_Vector llGetTorque() 2573 public LSL_Vector llGetTorque()
@@ -2298,20 +2584,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2298 llSetTorque(torque, local); 2584 llSetTorque(torque, local);
2299 } 2585 }
2300 2586
2587 public void llSetVelocity(LSL_Vector vel, int local)
2588 {
2589 m_host.AddScriptLPS(1);
2590 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2591 }
2592
2301 public LSL_Vector llGetVel() 2593 public LSL_Vector llGetVel()
2302 { 2594 {
2303 m_host.AddScriptLPS(1); 2595 m_host.AddScriptLPS(1);
2304 2596
2305 Vector3 vel; 2597 Vector3 vel = Vector3.Zero;
2306 2598
2307 if (m_host.ParentGroup.IsAttachment) 2599 if (m_host.ParentGroup.IsAttachment)
2308 { 2600 {
2309 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2601 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2310 vel = avatar.Velocity; 2602 if (avatar != null)
2603 vel = avatar.Velocity;
2311 } 2604 }
2312 else 2605 else
2313 { 2606 {
2314 vel = m_host.Velocity; 2607 vel = m_host.ParentGroup.RootPart.Velocity;
2315 } 2608 }
2316 2609
2317 return new LSL_Vector(vel); 2610 return new LSL_Vector(vel);
@@ -2324,11 +2617,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2324 return new LSL_Vector(m_host.Acceleration); 2617 return new LSL_Vector(m_host.Acceleration);
2325 } 2618 }
2326 2619
2327 public LSL_Vector llGetOmega() 2620 public void llSetAngularVelocity(LSL_Vector avel, int local)
2328 { 2621 {
2329 m_host.AddScriptLPS(1); 2622 m_host.AddScriptLPS(1);
2623 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2624 }
2330 2625
2331 return new LSL_Vector(m_host.AngularVelocity); 2626 public LSL_Vector llGetOmega()
2627 {
2628 m_host.AddScriptLPS(1);
2629 Vector3 avel = m_host.AngularVelocity;
2630 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2332 } 2631 }
2333 2632
2334 public LSL_Float llGetTimeOfDay() 2633 public LSL_Float llGetTimeOfDay()
@@ -2687,7 +2986,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2687 return src.ToLower(); 2986 return src.ToLower();
2688 } 2987 }
2689 2988
2690 public void llGiveMoney(string destination, int amount) 2989 public LSL_Integer llGiveMoney(string destination, int amount)
2691 { 2990 {
2692 Util.FireAndForget(x => 2991 Util.FireAndForget(x =>
2693 { 2992 {
@@ -2719,8 +3018,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2719 } 3018 }
2720 3019
2721 money.ObjectGiveMoney( 3020 money.ObjectGiveMoney(
2722 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3021 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2723 }); 3022 });
3023
3024 return 0;
2724 } 3025 }
2725 3026
2726 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3027 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -2799,13 +3100,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2799 new_group.RootPart.UUID.ToString()) }, 3100 new_group.RootPart.UUID.ToString()) },
2800 new DetectParams[0])); 3101 new DetectParams[0]));
2801 3102
2802 float groupmass = new_group.GetMass(); 3103 // do recoil
3104 SceneObjectGroup hostgrp = m_host.ParentGroup;
3105 if (hostgrp == null)
3106 return;
3107
3108 if (hostgrp.IsAttachment) // don't recoil avatars
3109 return;
2803 3110
2804 PhysicsActor pa = new_group.RootPart.PhysActor; 3111 PhysicsActor pa = new_group.RootPart.PhysActor;
2805 3112
2806 //Recoil. 3113 //Recoil.
2807 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3114 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2808 { 3115 {
3116 float groupmass = new_group.GetMass();
2809 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3117 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2810 if (recoil != Vector3.Zero) 3118 if (recoil != Vector3.Zero)
2811 { 3119 {
@@ -2813,6 +3121,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2813 } 3121 }
2814 } 3122 }
2815 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3123 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3124 return;
3125
2816 }); 3126 });
2817 3127
2818 //ScriptSleep((int)((groupmass * velmag) / 10)); 3128 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2827,35 +3137,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2827 public void llLookAt(LSL_Vector target, double strength, double damping) 3137 public void llLookAt(LSL_Vector target, double strength, double damping)
2828 { 3138 {
2829 m_host.AddScriptLPS(1); 3139 m_host.AddScriptLPS(1);
2830 // Determine where we are looking from
2831 LSL_Vector from = llGetPos();
2832 3140
2833 // Work out the normalised vector from the source to the target 3141 // Get the normalized vector to the target
2834 LSL_Vector delta = llVecNorm(target - from); 3142 LSL_Vector d1 = llVecNorm(target - llGetPos());
2835 LSL_Vector angle = new LSL_Vector(0,0,0);
2836 3143
2837 // Calculate the yaw 3144 // Get the bearing (yaw)
2838 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3145 LSL_Vector a1 = new LSL_Vector(0,0,0);
2839 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3146 a1.z = llAtan2(d1.y, d1.x);
2840 3147
2841 // Calculate pitch 3148 // Get the elevation (pitch)
2842 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3149 LSL_Vector a2 = new LSL_Vector(0,0,0);
3150 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2843 3151
2844 // we need to convert from a vector describing 3152 LSL_Rotation r1 = llEuler2Rot(a1);
2845 // the angles of rotation in radians into rotation value 3153 LSL_Rotation r2 = llEuler2Rot(a2);
2846 LSL_Rotation rot = llEuler2Rot(angle); 3154 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2847
2848 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2849 // set the rotation of the object, copy that behavior
2850 PhysicsActor pa = m_host.PhysActor;
2851 3155
2852 if (strength == 0 || pa == null || !pa.IsPhysical) 3156 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2853 { 3157 {
2854 llSetRot(rot); 3158 // Do nothing if either value is 0 (this has been checked in SL)
3159 if (strength <= 0.0 || damping <= 0.0)
3160 return;
3161
3162 llSetRot(r3 * r2 * r1);
2855 } 3163 }
2856 else 3164 else
2857 { 3165 {
2858 m_host.StartLookAt(rot, (float)strength, (float)damping); 3166 if (strength == 0)
3167 {
3168 llSetRot(r3 * r2 * r1);
3169 return;
3170 }
3171
3172 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2859 } 3173 }
2860 } 3174 }
2861 3175
@@ -2902,17 +3216,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2902 } 3216 }
2903 else 3217 else
2904 { 3218 {
2905 if (m_host.IsRoot) 3219 // new SL always returns object mass
2906 { 3220// if (m_host.IsRoot)
3221// {
2907 return m_host.ParentGroup.GetMass(); 3222 return m_host.ParentGroup.GetMass();
2908 } 3223// }
2909 else 3224// else
2910 { 3225// {
2911 return m_host.GetMass(); 3226// return m_host.GetMass();
2912 } 3227// }
2913 } 3228 }
2914 } 3229 }
2915 3230
3231
3232 public LSL_Float llGetMassMKS()
3233 {
3234 return 100f * llGetMass();
3235 }
3236
2916 public void llCollisionFilter(string name, string id, int accept) 3237 public void llCollisionFilter(string name, string id, int accept)
2917 { 3238 {
2918 m_host.AddScriptLPS(1); 3239 m_host.AddScriptLPS(1);
@@ -2960,8 +3281,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2960 { 3281 {
2961 // Unregister controls from Presence 3282 // Unregister controls from Presence
2962 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3283 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2963 // Remove Take Control permission.
2964 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
2965 } 3284 }
2966 } 3285 }
2967 } 3286 }
@@ -2989,7 +3308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2989 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3308 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
2990 3309
2991 if (attachmentsModule != null) 3310 if (attachmentsModule != null)
2992 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3311 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
2993 else 3312 else
2994 return false; 3313 return false;
2995 } 3314 }
@@ -3019,9 +3338,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3019 { 3338 {
3020 m_host.AddScriptLPS(1); 3339 m_host.AddScriptLPS(1);
3021 3340
3022// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3023// return;
3024
3025 if (m_item.PermsGranter != m_host.OwnerID) 3341 if (m_item.PermsGranter != m_host.OwnerID)
3026 return; 3342 return;
3027 3343
@@ -3064,6 +3380,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3064 3380
3065 public void llInstantMessage(string user, string message) 3381 public void llInstantMessage(string user, string message)
3066 { 3382 {
3383 UUID result;
3384 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3385 {
3386 ShoutError("An invalid key was passed to llInstantMessage");
3387 ScriptSleep(2000);
3388 return;
3389 }
3390
3391
3067 m_host.AddScriptLPS(1); 3392 m_host.AddScriptLPS(1);
3068 3393
3069 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3394 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3078,14 +3403,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3078 UUID friendTransactionID = UUID.Random(); 3403 UUID friendTransactionID = UUID.Random();
3079 3404
3080 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3405 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3081 3406
3082 GridInstantMessage msg = new GridInstantMessage(); 3407 GridInstantMessage msg = new GridInstantMessage();
3083 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3408 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3084 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3409 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3085 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3410 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3086// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3411// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3087// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3412// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3088 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3413// DateTime dt = DateTime.UtcNow;
3414//
3415// // Ticks from UtcNow, but make it look like local. Evil, huh?
3416// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3417//
3418// try
3419// {
3420// // Convert that to the PST timezone
3421// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3422// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3423// }
3424// catch
3425// {
3426// // No logging here, as it could be VERY spammy
3427// }
3428//
3429// // And make it look local again to fool the unix time util
3430// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3431
3432 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3433
3089 //if (client != null) 3434 //if (client != null)
3090 //{ 3435 //{
3091 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3436 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3099,10 +3444,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3099 msg.message = message.Substring(0, 1024); 3444 msg.message = message.Substring(0, 1024);
3100 else 3445 else
3101 msg.message = message; 3446 msg.message = message;
3102 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3447 msg.dialog = (byte)19; // MessageFromObject
3103 msg.fromGroup = false;// fromGroup; 3448 msg.fromGroup = false;// fromGroup;
3104 msg.offline = (byte)0; //offline; 3449 msg.offline = (byte)0; //offline;
3105 msg.ParentEstateID = 0; //ParentEstateID; 3450 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3106 msg.Position = new Vector3(m_host.AbsolutePosition); 3451 msg.Position = new Vector3(m_host.AbsolutePosition);
3107 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3452 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3108 3453
@@ -3134,7 +3479,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3134 } 3479 }
3135 3480
3136 emailModule.SendEmail(m_host.UUID, address, subject, message); 3481 emailModule.SendEmail(m_host.UUID, address, subject, message);
3137 llSleep(EMAIL_PAUSE_TIME); 3482 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3138 } 3483 }
3139 3484
3140 public void llGetNextEmail(string address, string subject) 3485 public void llGetNextEmail(string address, string subject)
@@ -3380,7 +3725,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3380 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3725 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3381 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3726 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3382 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3727 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3728 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3383 ScriptBaseClass.PERMISSION_ATTACH; 3729 ScriptBaseClass.PERMISSION_ATTACH;
3730
3384 } 3731 }
3385 else 3732 else
3386 { 3733 {
@@ -3397,15 +3744,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3397 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3744 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3398 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3745 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3399 } 3746 }
3747 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3748 {
3749 implicitPerms = perm;
3750 }
3400 } 3751 }
3401 3752
3402 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3753 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3403 { 3754 {
3404 lock (m_host.TaskInventory) 3755 m_host.TaskInventory.LockItemsForWrite(true);
3405 { 3756 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3406 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3757 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3407 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3758 m_host.TaskInventory.LockItemsForWrite(false);
3408 }
3409 3759
3410 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3760 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3411 "run_time_permissions", new Object[] { 3761 "run_time_permissions", new Object[] {
@@ -3448,11 +3798,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3448 3798
3449 if (!m_waitingForScriptAnswer) 3799 if (!m_waitingForScriptAnswer)
3450 { 3800 {
3451 lock (m_host.TaskInventory) 3801 m_host.TaskInventory.LockItemsForWrite(true);
3452 { 3802 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3453 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3803 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3454 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3804 m_host.TaskInventory.LockItemsForWrite(false);
3455 }
3456 3805
3457 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3806 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3458 m_waitingForScriptAnswer=true; 3807 m_waitingForScriptAnswer=true;
@@ -3481,14 +3830,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3481 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3830 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3482 llReleaseControls(); 3831 llReleaseControls();
3483 3832
3484 lock (m_host.TaskInventory) 3833 m_host.TaskInventory.LockItemsForWrite(true);
3485 { 3834 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3486 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3835 m_host.TaskInventory.LockItemsForWrite(false);
3487 } 3836
3488 3837 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3489 m_ScriptEngine.PostScriptEvent( 3838 "run_time_permissions", new Object[] {
3490 m_item.ItemID, 3839 new LSL_Integer(answer) },
3491 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3840 new DetectParams[0]));
3492 } 3841 }
3493 3842
3494 public LSL_String llGetPermissionsKey() 3843 public LSL_String llGetPermissionsKey()
@@ -3527,14 +3876,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3527 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3876 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3528 { 3877 {
3529 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3878 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3530 3879 if (parts.Count > 0)
3531 foreach (SceneObjectPart part in parts) 3880 {
3532 part.SetFaceColorAlpha(face, color, null); 3881 try
3882 {
3883 foreach (SceneObjectPart part in parts)
3884 part.SetFaceColorAlpha(face, color, null);
3885 }
3886 finally
3887 {
3888 }
3889 }
3533 } 3890 }
3534 3891
3535 public void llCreateLink(string target, int parent) 3892 public void llCreateLink(string target, int parent)
3536 { 3893 {
3537 m_host.AddScriptLPS(1); 3894 m_host.AddScriptLPS(1);
3895
3538 UUID targetID; 3896 UUID targetID;
3539 3897
3540 if (!UUID.TryParse(target, out targetID)) 3898 if (!UUID.TryParse(target, out targetID))
@@ -3640,10 +3998,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3640 // Restructuring Multiple Prims. 3998 // Restructuring Multiple Prims.
3641 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3999 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3642 parts.Remove(parentPrim.RootPart); 4000 parts.Remove(parentPrim.RootPart);
3643 foreach (SceneObjectPart part in parts) 4001 if (parts.Count > 0)
3644 { 4002 {
3645 parentPrim.DelinkFromGroup(part.LocalId, true); 4003 try
4004 {
4005 foreach (SceneObjectPart part in parts)
4006 {
4007 parentPrim.DelinkFromGroup(part.LocalId, true);
4008 }
4009 }
4010 finally
4011 {
4012 }
3646 } 4013 }
4014
3647 parentPrim.HasGroupChanged = true; 4015 parentPrim.HasGroupChanged = true;
3648 parentPrim.ScheduleGroupForFullUpdate(); 4016 parentPrim.ScheduleGroupForFullUpdate();
3649 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4017 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3652,12 +4020,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3652 { 4020 {
3653 SceneObjectPart newRoot = parts[0]; 4021 SceneObjectPart newRoot = parts[0];
3654 parts.Remove(newRoot); 4022 parts.Remove(newRoot);
3655 foreach (SceneObjectPart part in parts) 4023
4024 try
3656 { 4025 {
3657 // Required for linking 4026 foreach (SceneObjectPart part in parts)
3658 part.ClearUpdateSchedule(); 4027 {
3659 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4028 part.ClearUpdateSchedule();
4029 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4030 }
3660 } 4031 }
4032 finally
4033 {
4034 }
4035
4036
3661 newRoot.ParentGroup.HasGroupChanged = true; 4037 newRoot.ParentGroup.HasGroupChanged = true;
3662 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4038 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3663 } 4039 }
@@ -3677,6 +4053,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3677 public void llBreakAllLinks() 4053 public void llBreakAllLinks()
3678 { 4054 {
3679 m_host.AddScriptLPS(1); 4055 m_host.AddScriptLPS(1);
4056
4057 TaskInventoryItem item = m_item;
4058
4059 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4060 && !m_automaticLinkPermission)
4061 {
4062 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4063 return;
4064 }
4065
3680 SceneObjectGroup parentPrim = m_host.ParentGroup; 4066 SceneObjectGroup parentPrim = m_host.ParentGroup;
3681 if (parentPrim.AttachmentPoint != 0) 4067 if (parentPrim.AttachmentPoint != 0)
3682 return; // Fail silently if attached 4068 return; // Fail silently if attached
@@ -3696,47 +4082,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3696 public LSL_String llGetLinkKey(int linknum) 4082 public LSL_String llGetLinkKey(int linknum)
3697 { 4083 {
3698 m_host.AddScriptLPS(1); 4084 m_host.AddScriptLPS(1);
3699 4085 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3700 if (linknum < 0) 4086 if (part != null)
3701 {
3702 if (linknum == ScriptBaseClass.LINK_THIS)
3703 return m_host.UUID.ToString();
3704 else
3705 return ScriptBaseClass.NULL_KEY;
3706 }
3707
3708 int actualPrimCount = m_host.ParentGroup.PrimCount;
3709 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
3710 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
3711
3712 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
3713 // prim that has any avatars sat upon it (in which case the root prim is link 1).
3714 if (linknum == 0)
3715 {
3716 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
3717 return m_host.UUID.ToString();
3718
3719 return ScriptBaseClass.NULL_KEY;
3720 }
3721 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
3722 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
3723 else if (linknum == 1 && actualPrimCount == 1)
3724 {
3725 if (sittingAvatarIds.Count > 0)
3726 return m_host.ParentGroup.RootPart.UUID.ToString();
3727 else
3728 return ScriptBaseClass.NULL_KEY;
3729 }
3730 else if (linknum <= adjustedPrimCount)
3731 { 4087 {
3732 if (linknum <= actualPrimCount) 4088 return part.UUID.ToString();
3733 return m_host.ParentGroup.GetLinkNumPart(linknum).UUID.ToString();
3734 else
3735 return sittingAvatarIds[linknum - actualPrimCount - 1].ToString();
3736 } 4089 }
3737 else 4090 else
3738 { 4091 {
3739 return ScriptBaseClass.NULL_KEY; 4092 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4093 {
4094 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4095
4096 if (linknum < 0)
4097 return UUID.Zero.ToString();
4098
4099 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4100 if (avatars.Count > linknum)
4101 {
4102 return avatars[linknum].UUID.ToString();
4103 }
4104 }
4105 return UUID.Zero.ToString();
3740 } 4106 }
3741 } 4107 }
3742 4108
@@ -3839,17 +4205,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3839 m_host.AddScriptLPS(1); 4205 m_host.AddScriptLPS(1);
3840 int count = 0; 4206 int count = 0;
3841 4207
3842 lock (m_host.TaskInventory) 4208 m_host.TaskInventory.LockItemsForRead(true);
4209 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3843 { 4210 {
3844 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4211 if (inv.Value.Type == type || type == -1)
3845 { 4212 {
3846 if (inv.Value.Type == type || type == -1) 4213 count = count + 1;
3847 {
3848 count = count + 1;
3849 }
3850 } 4214 }
3851 } 4215 }
3852 4216
4217 m_host.TaskInventory.LockItemsForRead(false);
3853 return count; 4218 return count;
3854 } 4219 }
3855 4220
@@ -3858,16 +4223,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3858 m_host.AddScriptLPS(1); 4223 m_host.AddScriptLPS(1);
3859 ArrayList keys = new ArrayList(); 4224 ArrayList keys = new ArrayList();
3860 4225
3861 lock (m_host.TaskInventory) 4226 m_host.TaskInventory.LockItemsForRead(true);
4227 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3862 { 4228 {
3863 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4229 if (inv.Value.Type == type || type == -1)
3864 { 4230 {
3865 if (inv.Value.Type == type || type == -1) 4231 keys.Add(inv.Value.Name);
3866 {
3867 keys.Add(inv.Value.Name);
3868 }
3869 } 4232 }
3870 } 4233 }
4234 m_host.TaskInventory.LockItemsForRead(false);
3871 4235
3872 if (keys.Count == 0) 4236 if (keys.Count == 0)
3873 { 4237 {
@@ -3905,7 +4269,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3905 if (item == null) 4269 if (item == null)
3906 { 4270 {
3907 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4271 llSay(0, String.Format("Could not find object '{0}'", inventory));
3908 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4272 return;
4273// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3909 } 4274 }
3910 4275
3911 UUID objId = item.ItemID; 4276 UUID objId = item.ItemID;
@@ -3933,33 +4298,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3933 return; 4298 return;
3934 } 4299 }
3935 } 4300 }
4301
3936 // destination is an avatar 4302 // destination is an avatar
3937 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4303 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3938 4304
3939 if (agentItem == null) 4305 if (agentItem == null)
3940 return; 4306 return;
3941 4307
3942 if (m_TransferModule != null) 4308 byte[] bucket = new byte[1];
3943 { 4309 bucket[0] = (byte)item.Type;
3944 byte[] bucket = new byte[1]; 4310 //byte[] objBytes = agentItem.ID.GetBytes();
3945 bucket[0] = (byte)item.Type; 4311 //Array.Copy(objBytes, 0, bucket, 1, 16);
3946 4312
3947 GridInstantMessage msg = new GridInstantMessage(World, 4313 GridInstantMessage msg = new GridInstantMessage(World,
3948 m_host.OwnerID, m_host.Name, destId, 4314 m_host.OwnerID, m_host.Name, destId,
3949 (byte)InstantMessageDialog.TaskInventoryOffered, 4315 (byte)InstantMessageDialog.TaskInventoryOffered,
3950 false, item.Name+". "+m_host.Name+" is located at "+ 4316 false, item.Name+". "+m_host.Name+" is located at "+
3951 World.RegionInfo.RegionName+" "+ 4317 World.RegionInfo.RegionName+" "+
3952 m_host.AbsolutePosition.ToString(), 4318 m_host.AbsolutePosition.ToString(),
3953 agentItem.ID, true, m_host.AbsolutePosition, 4319 agentItem.ID, true, m_host.AbsolutePosition,
3954 bucket, true); 4320 bucket, true);
3955 4321
3956 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4322 ScenePresence sp;
3957 }
3958 4323
4324 if (World.TryGetScenePresence(destId, out sp))
4325 {
4326 sp.ControllingClient.SendInstantMessage(msg);
4327 }
4328 else
4329 {
4330 if (m_TransferModule != null)
4331 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4332 }
4333
4334 //This delay should only occur when giving inventory to avatars.
3959 ScriptSleep(3000); 4335 ScriptSleep(3000);
3960 } 4336 }
3961 } 4337 }
3962 4338
4339 [DebuggerNonUserCode]
3963 public void llRemoveInventory(string name) 4340 public void llRemoveInventory(string name)
3964 { 4341 {
3965 m_host.AddScriptLPS(1); 4342 m_host.AddScriptLPS(1);
@@ -4014,109 +4391,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4014 { 4391 {
4015 m_host.AddScriptLPS(1); 4392 m_host.AddScriptLPS(1);
4016 4393
4017 UUID uuid = (UUID)id; 4394 UUID uuid;
4018 PresenceInfo pinfo = null; 4395 if (UUID.TryParse(id, out uuid))
4019 UserAccount account;
4020
4021 UserInfoCacheEntry ce;
4022 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4023 { 4396 {
4024 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4397 PresenceInfo pinfo = null;
4025 if (account == null) 4398 UserAccount account;
4399
4400 UserInfoCacheEntry ce;
4401 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4026 { 4402 {
4027 m_userInfoCache[uuid] = null; // Cache negative 4403 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4028 return UUID.Zero.ToString(); 4404 if (account == null)
4029 } 4405 {
4406 m_userInfoCache[uuid] = null; // Cache negative
4407 return UUID.Zero.ToString();
4408 }
4030 4409
4031 4410
4032 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4411 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4033 if (pinfos != null && pinfos.Length > 0) 4412 if (pinfos != null && pinfos.Length > 0)
4034 {
4035 foreach (PresenceInfo p in pinfos)
4036 { 4413 {
4037 if (p.RegionID != UUID.Zero) 4414 foreach (PresenceInfo p in pinfos)
4038 { 4415 {
4039 pinfo = p; 4416 if (p.RegionID != UUID.Zero)
4417 {
4418 pinfo = p;
4419 }
4040 } 4420 }
4041 } 4421 }
4042 }
4043 4422
4044 ce = new UserInfoCacheEntry(); 4423 ce = new UserInfoCacheEntry();
4045 ce.time = Util.EnvironmentTickCount(); 4424 ce.time = Util.EnvironmentTickCount();
4046 ce.account = account; 4425 ce.account = account;
4047 ce.pinfo = pinfo; 4426 ce.pinfo = pinfo;
4048 } 4427 m_userInfoCache[uuid] = ce;
4049 else 4428 }
4050 { 4429 else
4051 if (ce == null) 4430 {
4052 return UUID.Zero.ToString(); 4431 if (ce == null)
4432 return UUID.Zero.ToString();
4053 4433
4054 account = ce.account; 4434 account = ce.account;
4055 pinfo = ce.pinfo; 4435 pinfo = ce.pinfo;
4056 } 4436 }
4057 4437
4058 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4438 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4059 {
4060 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4061 if (pinfos != null && pinfos.Length > 0)
4062 { 4439 {
4063 foreach (PresenceInfo p in pinfos) 4440 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4441 if (pinfos != null && pinfos.Length > 0)
4064 { 4442 {
4065 if (p.RegionID != UUID.Zero) 4443 foreach (PresenceInfo p in pinfos)
4066 { 4444 {
4067 pinfo = p; 4445 if (p.RegionID != UUID.Zero)
4446 {
4447 pinfo = p;
4448 }
4068 } 4449 }
4069 } 4450 }
4070 } 4451 else
4071 else 4452 pinfo = null;
4072 pinfo = null;
4073 4453
4074 ce.time = Util.EnvironmentTickCount(); 4454 ce.time = Util.EnvironmentTickCount();
4075 ce.pinfo = pinfo; 4455 ce.pinfo = pinfo;
4076 } 4456 }
4077 4457
4078 string reply = String.Empty; 4458 string reply = String.Empty;
4079 4459
4080 switch (data) 4460 switch (data)
4081 { 4461 {
4082 case 1: // DATA_ONLINE (0|1) 4462 case 1: // DATA_ONLINE (0|1)
4083 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4463 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4084 reply = "1"; 4464 reply = "1";
4085 else 4465 else
4086 reply = "0"; 4466 reply = "0";
4087 break; 4467 break;
4088 case 2: // DATA_NAME (First Last) 4468 case 2: // DATA_NAME (First Last)
4089 reply = account.FirstName + " " + account.LastName; 4469 reply = account.FirstName + " " + account.LastName;
4090 break; 4470 break;
4091 case 3: // DATA_BORN (YYYY-MM-DD) 4471 case 3: // DATA_BORN (YYYY-MM-DD)
4092 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4472 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4093 born = born.AddSeconds(account.Created); 4473 born = born.AddSeconds(account.Created);
4094 reply = born.ToString("yyyy-MM-dd"); 4474 reply = born.ToString("yyyy-MM-dd");
4095 break; 4475 break;
4096 case 4: // DATA_RATING (0,0,0,0,0,0) 4476 case 4: // DATA_RATING (0,0,0,0,0,0)
4097 reply = "0,0,0,0,0,0"; 4477 reply = "0,0,0,0,0,0";
4098 break; 4478 break;
4099 case 7: // DATA_USERLEVEL (integer) 4479 case 8: // DATA_PAYINFO (0|1|2|3)
4100 reply = account.UserLevel.ToString(); 4480 reply = "0";
4101 break; 4481 break;
4102 case 8: // DATA_PAYINFO (0|1|2|3) 4482 default:
4103 reply = "0"; 4483 return UUID.Zero.ToString(); // Raise no event
4104 break; 4484 }
4105 default:
4106 return UUID.Zero.ToString(); // Raise no event
4107 }
4108 4485
4109 UUID rq = UUID.Random(); 4486 UUID rq = UUID.Random();
4110 4487
4111 UUID tid = AsyncCommands. 4488 UUID tid = AsyncCommands.
4112 DataserverPlugin.RegisterRequest(m_host.LocalId, 4489 DataserverPlugin.RegisterRequest(m_host.LocalId,
4113 m_item.ItemID, rq.ToString()); 4490 m_item.ItemID, rq.ToString());
4114 4491
4115 AsyncCommands. 4492 AsyncCommands.
4116 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4493 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4117 4494
4118 ScriptSleep(100); 4495 ScriptSleep(100);
4119 return tid.ToString(); 4496 return tid.ToString();
4497 }
4498 else
4499 {
4500 ShoutError("Invalid UUID passed to llRequestAgentData.");
4501 }
4502 return "";
4120 } 4503 }
4121 4504
4122 public LSL_String llRequestInventoryData(string name) 4505 public LSL_String llRequestInventoryData(string name)
@@ -4173,13 +4556,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4173 if (UUID.TryParse(agent, out agentId)) 4556 if (UUID.TryParse(agent, out agentId))
4174 { 4557 {
4175 ScenePresence presence = World.GetScenePresence(agentId); 4558 ScenePresence presence = World.GetScenePresence(agentId);
4176 if (presence != null) 4559 if (presence != null && presence.PresenceType != PresenceType.Npc)
4177 { 4560 {
4561 // agent must not be a god
4562 if (presence.UserLevel >= 200) return;
4563
4178 // agent must be over the owners land 4564 // agent must be over the owners land
4179 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4565 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4180 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4566 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4181 { 4567 {
4182 World.TeleportClientHome(agentId, presence.ControllingClient); 4568 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4569 {
4570 // They can't be teleported home for some reason
4571 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4572 if (regionInfo != null)
4573 {
4574 World.RequestTeleportLocation(
4575 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4576 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4577 }
4578 }
4183 } 4579 }
4184 } 4580 }
4185 } 4581 }
@@ -4288,7 +4684,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4288 UUID av = new UUID(); 4684 UUID av = new UUID();
4289 if (!UUID.TryParse(agent,out av)) 4685 if (!UUID.TryParse(agent,out av))
4290 { 4686 {
4291 LSLError("First parameter to llDialog needs to be a key");
4292 return; 4687 return;
4293 } 4688 }
4294 4689
@@ -4320,10 +4715,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4320 public void llCollisionSound(string impact_sound, double impact_volume) 4715 public void llCollisionSound(string impact_sound, double impact_volume)
4321 { 4716 {
4322 m_host.AddScriptLPS(1); 4717 m_host.AddScriptLPS(1);
4323 4718
4719 if(impact_sound == "")
4720 {
4721 m_host.CollisionSoundVolume = (float)impact_volume;
4722 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4723 m_host.CollisionSoundType = 0;
4724 return;
4725 }
4324 // TODO: Parameter check logic required. 4726 // TODO: Parameter check logic required.
4325 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 4727 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4326 m_host.CollisionSoundVolume = (float)impact_volume; 4728 m_host.CollisionSoundVolume = (float)impact_volume;
4729 m_host.CollisionSoundType = 1;
4327 } 4730 }
4328 4731
4329 public LSL_String llGetAnimation(string id) 4732 public LSL_String llGetAnimation(string id)
@@ -4337,14 +4740,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4337 4740
4338 if (m_host.RegionHandle == presence.RegionHandle) 4741 if (m_host.RegionHandle == presence.RegionHandle)
4339 { 4742 {
4340 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4341
4342 if (presence != null) 4743 if (presence != null)
4343 { 4744 {
4344 AnimationSet currentAnims = presence.Animator.Animations; 4745 if (presence.SitGround)
4345 string currentAnimationState = String.Empty; 4746 return "Sitting on Ground";
4346 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4747 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4347 return currentAnimationState; 4748 return "Sitting";
4749
4750 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4751 string lslMovementAnimation;
4752
4753 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4754 return lslMovementAnimation;
4348 } 4755 }
4349 } 4756 }
4350 4757
@@ -4492,7 +4899,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4492 { 4899 {
4493 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4900 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4494 float distance_term = distance * distance * distance; // Script Energy 4901 float distance_term = distance * distance * distance; // Script Energy
4495 float pusher_mass = m_host.GetMass(); 4902 // use total object mass and not part
4903 float pusher_mass = m_host.ParentGroup.GetMass();
4496 4904
4497 float PUSH_ATTENUATION_DISTANCE = 17f; 4905 float PUSH_ATTENUATION_DISTANCE = 17f;
4498 float PUSH_ATTENUATION_SCALE = 5f; 4906 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4746,6 +5154,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4746 { 5154 {
4747 return item.AssetID.ToString(); 5155 return item.AssetID.ToString();
4748 } 5156 }
5157 m_host.TaskInventory.LockItemsForRead(false);
4749 5158
4750 return UUID.Zero.ToString(); 5159 return UUID.Zero.ToString();
4751 } 5160 }
@@ -4898,14 +5307,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4898 { 5307 {
4899 m_host.AddScriptLPS(1); 5308 m_host.AddScriptLPS(1);
4900 5309
4901 if (src == null) 5310 return src.Length;
4902 {
4903 return 0;
4904 }
4905 else
4906 {
4907 return src.Length;
4908 }
4909 } 5311 }
4910 5312
4911 public LSL_Integer llList2Integer(LSL_List src, int index) 5313 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4976,7 +5378,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4976 else if (src.Data[index] is LSL_Float) 5378 else if (src.Data[index] is LSL_Float)
4977 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5379 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4978 else if (src.Data[index] is LSL_String) 5380 else if (src.Data[index] is LSL_String)
4979 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5381 {
5382 string str = ((LSL_String) src.Data[index]).m_string;
5383 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5384 if (m != Match.Empty)
5385 {
5386 str = m.Value;
5387 double d = 0.0;
5388 if (!Double.TryParse(str, out d))
5389 return 0.0;
5390
5391 return d;
5392 }
5393 return 0.0;
5394 }
4980 return Convert.ToDouble(src.Data[index]); 5395 return Convert.ToDouble(src.Data[index]);
4981 } 5396 }
4982 catch (FormatException) 5397 catch (FormatException)
@@ -5018,7 +5433,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5018 // for completion and should LSL_Key ever be implemented 5433 // for completion and should LSL_Key ever be implemented
5019 // as it's own struct 5434 // as it's own struct
5020 else if (!(src.Data[index] is LSL_String || 5435 else if (!(src.Data[index] is LSL_String ||
5021 src.Data[index] is LSL_Key)) 5436 src.Data[index] is LSL_Key ||
5437 src.Data[index] is String))
5022 { 5438 {
5023 return ""; 5439 return "";
5024 } 5440 }
@@ -5276,7 +5692,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5276 } 5692 }
5277 } 5693 }
5278 } 5694 }
5279 else { 5695 else
5696 {
5280 object[] array = new object[src.Length]; 5697 object[] array = new object[src.Length];
5281 Array.Copy(src.Data, 0, array, 0, src.Length); 5698 Array.Copy(src.Data, 0, array, 0, src.Length);
5282 result = new LSL_List(array); 5699 result = new LSL_List(array);
@@ -5383,7 +5800,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5383 public LSL_Integer llGetRegionAgentCount() 5800 public LSL_Integer llGetRegionAgentCount()
5384 { 5801 {
5385 m_host.AddScriptLPS(1); 5802 m_host.AddScriptLPS(1);
5386 return new LSL_Integer(World.GetRootAgentCount()); 5803
5804 int count = 0;
5805 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5806 count++;
5807 });
5808
5809 return new LSL_Integer(count);
5387 } 5810 }
5388 5811
5389 public LSL_Vector llGetRegionCorner() 5812 public LSL_Vector llGetRegionCorner()
@@ -5624,6 +6047,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5624 flags |= ScriptBaseClass.AGENT_AWAY; 6047 flags |= ScriptBaseClass.AGENT_AWAY;
5625 } 6048 }
5626 6049
6050 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6051 UUID[] anims = agent.Animator.GetAnimationArray();
6052 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6053 {
6054 flags |= ScriptBaseClass.AGENT_BUSY;
6055 }
6056
5627 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6057 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5628 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6058 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5629 { 6059 {
@@ -5671,6 +6101,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5671 flags |= ScriptBaseClass.AGENT_SITTING; 6101 flags |= ScriptBaseClass.AGENT_SITTING;
5672 } 6102 }
5673 6103
6104 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6105 {
6106 flags |= ScriptBaseClass.AGENT_MALE;
6107 }
6108
5674 return flags; 6109 return flags;
5675 } 6110 }
5676 6111
@@ -5818,9 +6253,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5818 6253
5819 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6254 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5820 6255
5821 foreach (SceneObjectPart part in parts) 6256 try
6257 {
6258 foreach (SceneObjectPart part in parts)
6259 {
6260 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6261 }
6262 }
6263 finally
5822 { 6264 {
5823 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5824 } 6265 }
5825 } 6266 }
5826 6267
@@ -5876,13 +6317,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5876 6317
5877 if (m_host.OwnerID == land.LandData.OwnerID) 6318 if (m_host.OwnerID == land.LandData.OwnerID)
5878 { 6319 {
5879 World.TeleportClientHome(agentID, presence.ControllingClient); 6320 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6321 presence.TeleportWithMomentum(p, null);
6322 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5880 } 6323 }
5881 } 6324 }
5882 } 6325 }
5883 ScriptSleep(5000); 6326 ScriptSleep(5000);
5884 } 6327 }
5885 6328
6329 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6330 {
6331 return ParseString2List(str, separators, in_spacers, false);
6332 }
6333
5886 public LSL_Integer llOverMyLand(string id) 6334 public LSL_Integer llOverMyLand(string id)
5887 { 6335 {
5888 m_host.AddScriptLPS(1); 6336 m_host.AddScriptLPS(1);
@@ -5939,25 +6387,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5939 } 6387 }
5940 else 6388 else
5941 { 6389 {
5942 agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); 6390// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6391 Vector3 s = avatar.Appearance.AvatarSize;
6392 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5943 } 6393 }
5944 return agentSize; 6394 return agentSize;
5945 } 6395 }
5946 6396
5947 public LSL_Integer llSameGroup(string agent) 6397 public LSL_Integer llSameGroup(string id)
5948 { 6398 {
5949 m_host.AddScriptLPS(1); 6399 m_host.AddScriptLPS(1);
5950 UUID agentId = new UUID(); 6400 UUID uuid = new UUID();
5951 if (!UUID.TryParse(agent, out agentId)) 6401 if (!UUID.TryParse(id, out uuid))
5952 return new LSL_Integer(0);
5953 ScenePresence presence = World.GetScenePresence(agentId);
5954 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5955 return new LSL_Integer(0); 6402 return new LSL_Integer(0);
5956 IClientAPI client = presence.ControllingClient; 6403
5957 if (m_host.GroupID == client.ActiveGroupId) 6404 // Check if it's a group key
6405 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5958 return new LSL_Integer(1); 6406 return new LSL_Integer(1);
5959 else 6407
6408 // We got passed a UUID.Zero
6409 if (uuid == UUID.Zero)
6410 return new LSL_Integer(0);
6411
6412 // Handle the case where id names an avatar
6413 ScenePresence presence = World.GetScenePresence(uuid);
6414 if (presence != null)
6415 {
6416 if (presence.IsChildAgent)
6417 return new LSL_Integer(0);
6418
6419 IClientAPI client = presence.ControllingClient;
6420 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6421 return new LSL_Integer(1);
6422
6423 return new LSL_Integer(0);
6424 }
6425
6426 // Handle object case
6427 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6428 if (part != null)
6429 {
6430 // This will handle both deed and non-deed and also the no
6431 // group case
6432 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6433 return new LSL_Integer(1);
6434
5960 return new LSL_Integer(0); 6435 return new LSL_Integer(0);
6436 }
6437
6438 return new LSL_Integer(0);
5961 } 6439 }
5962 6440
5963 public void llUnSit(string id) 6441 public void llUnSit(string id)
@@ -6087,7 +6565,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6087 return m_host.ParentGroup.AttachmentPoint; 6565 return m_host.ParentGroup.AttachmentPoint;
6088 } 6566 }
6089 6567
6090 public LSL_Integer llGetFreeMemory() 6568 public virtual LSL_Integer llGetFreeMemory()
6091 { 6569 {
6092 m_host.AddScriptLPS(1); 6570 m_host.AddScriptLPS(1);
6093 // Make scripts designed for LSO happy 6571 // Make scripts designed for LSO happy
@@ -6519,6 +6997,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6519 6997
6520 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6998 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6521 { 6999 {
7000 // LSL quaternions can normalize to 0, normal Quaternions can't.
7001 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7002 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7003
6522 part.SitTargetPosition = offset; 7004 part.SitTargetPosition = offset;
6523 part.SitTargetOrientation = rot; 7005 part.SitTargetOrientation = rot;
6524 part.ParentGroup.HasGroupChanged = true; 7006 part.ParentGroup.HasGroupChanged = true;
@@ -6706,30 +7188,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6706 UUID av = new UUID(); 7188 UUID av = new UUID();
6707 if (!UUID.TryParse(avatar,out av)) 7189 if (!UUID.TryParse(avatar,out av))
6708 { 7190 {
6709 LSLError("First parameter to llDialog needs to be a key"); 7191 //LSLError("First parameter to llDialog needs to be a key");
6710 return; 7192 return;
6711 } 7193 }
6712 if (buttons.Length < 1) 7194 if (buttons.Length < 1)
6713 { 7195 {
6714 LSLError("No less than 1 button can be shown"); 7196 buttons.Add("OK");
6715 return;
6716 } 7197 }
6717 if (buttons.Length > 12) 7198 if (buttons.Length > 12)
6718 { 7199 {
6719 LSLError("No more than 12 buttons can be shown"); 7200 ShoutError("button list too long, must be 12 or fewer entries");
6720 return;
6721 } 7201 }
6722 string[] buts = new string[buttons.Length]; 7202 int length = buttons.Length;
6723 for (int i = 0; i < buttons.Length; i++) 7203 if (length > 12)
7204 length = 12;
7205
7206 string[] buts = new string[length];
7207 for (int i = 0; i < length; i++)
6724 { 7208 {
6725 if (buttons.Data[i].ToString() == String.Empty) 7209 if (buttons.Data[i].ToString() == String.Empty)
6726 { 7210 {
6727 LSLError("button label cannot be blank"); 7211 ShoutError("button label cannot be blank");
6728 return; 7212 return;
6729 } 7213 }
6730 if (buttons.Data[i].ToString().Length > 24) 7214 if (buttons.Data[i].ToString().Length > 24)
6731 { 7215 {
6732 LSLError("button label cannot be longer than 24 characters"); 7216 ShoutError("button label cannot be longer than 24 characters");
6733 return; 7217 return;
6734 } 7218 }
6735 buts[i] = buttons.Data[i].ToString(); 7219 buts[i] = buttons.Data[i].ToString();
@@ -6796,9 +7280,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6796 return; 7280 return;
6797 } 7281 }
6798 7282
6799 // the rest of the permission checks are done in RezScript, so check the pin there as well 7283 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6800 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7284 if (dest != null)
7285 {
7286 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7287 {
7288 // the rest of the permission checks are done in RezScript, so check the pin there as well
7289 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6801 7290
7291 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7292 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7293 }
7294 }
6802 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7295 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6803 ScriptSleep(3000); 7296 ScriptSleep(3000);
6804 } 7297 }
@@ -6872,19 +7365,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6872 public LSL_String llMD5String(string src, int nonce) 7365 public LSL_String llMD5String(string src, int nonce)
6873 { 7366 {
6874 m_host.AddScriptLPS(1); 7367 m_host.AddScriptLPS(1);
6875 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7368 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6876 } 7369 }
6877 7370
6878 public LSL_String llSHA1String(string src) 7371 public LSL_String llSHA1String(string src)
6879 { 7372 {
6880 m_host.AddScriptLPS(1); 7373 m_host.AddScriptLPS(1);
6881 return Util.SHA1Hash(src).ToLower(); 7374 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6882 } 7375 }
6883 7376
6884 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7377 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6885 { 7378 {
6886 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7379 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6887 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7380 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7381 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7382 return shapeBlock;
6888 7383
6889 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7384 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6890 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7385 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6989,6 +7484,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6989 // Prim type box, cylinder and prism. 7484 // Prim type box, cylinder and prism.
6990 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) 7485 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)
6991 { 7486 {
7487 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7488 return;
7489
6992 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7490 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6993 ObjectShapePacket.ObjectDataBlock shapeBlock; 7491 ObjectShapePacket.ObjectDataBlock shapeBlock;
6994 7492
@@ -7042,6 +7540,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7042 // Prim type sphere. 7540 // Prim type sphere.
7043 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7541 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7044 { 7542 {
7543 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7544 return;
7545
7045 ObjectShapePacket.ObjectDataBlock shapeBlock; 7546 ObjectShapePacket.ObjectDataBlock shapeBlock;
7046 7547
7047 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7548 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7083,6 +7584,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7083 // Prim type torus, tube and ring. 7584 // Prim type torus, tube and ring.
7084 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) 7585 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)
7085 { 7586 {
7587 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7588 return;
7589
7086 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7590 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7087 ObjectShapePacket.ObjectDataBlock shapeBlock; 7591 ObjectShapePacket.ObjectDataBlock shapeBlock;
7088 7592
@@ -7218,6 +7722,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7218 // Prim type sculpt. 7722 // Prim type sculpt.
7219 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7723 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7220 { 7724 {
7725 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7726 return;
7727
7221 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7728 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7222 UUID sculptId; 7729 UUID sculptId;
7223 7730
@@ -7240,7 +7747,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7240 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7747 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7241 { 7748 {
7242 // default 7749 // default
7243 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7750 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7244 } 7751 }
7245 7752
7246 part.Shape.SetSculptProperties((byte)type, sculptId); 7753 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7257,48 +7764,130 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7257 ScriptSleep(200); 7764 ScriptSleep(200);
7258 } 7765 }
7259 7766
7260 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7767 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7261 { 7768 {
7262 m_host.AddScriptLPS(1); 7769 m_host.AddScriptLPS(1);
7263 7770
7264 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7771 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7772 }
7265 7773
7266 ScriptSleep(200); 7774 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7775 {
7776 List<object> parts = new List<object>();
7777 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7778 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7779 foreach (SceneObjectPart p in prims)
7780 parts.Add(p);
7781 foreach (ScenePresence p in avatars)
7782 parts.Add(p);
7783
7784 LSL_List remaining = null;
7785 uint rulesParsed = 0;
7786
7787 if (parts.Count > 0)
7788 {
7789 foreach (object part in parts)
7790 {
7791 if (part is SceneObjectPart)
7792 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7793 else
7794 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7795 }
7796
7797 while ((object)remaining != null && remaining.Length > 2)
7798 {
7799 linknumber = remaining.GetLSLIntegerItem(0);
7800 rules = remaining.GetSublist(1, -1);
7801 parts.Clear();
7802 prims = GetLinkParts(linknumber);
7803 avatars = GetLinkAvatars(linknumber);
7804 foreach (SceneObjectPart p in prims)
7805 parts.Add(p);
7806 foreach (ScenePresence p in avatars)
7807 parts.Add(p);
7808
7809 remaining = null;
7810 foreach (object part in parts)
7811 {
7812 if (part is SceneObjectPart)
7813 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7814 else
7815 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7816 }
7817 }
7818 }
7267 } 7819 }
7268 7820
7269 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7821 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7822 float material_density, float material_friction,
7823 float material_restitution, float material_gravity_modifier)
7270 { 7824 {
7271 m_host.AddScriptLPS(1); 7825 ExtraPhysicsData physdata = new ExtraPhysicsData();
7826 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7827 physdata.Density = part.Density;
7828 physdata.Friction = part.Friction;
7829 physdata.Bounce = part.Restitution;
7830 physdata.GravitationModifier = part.GravityModifier;
7272 7831
7273 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7832 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7833 physdata.Density = material_density;
7834 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7835 physdata.Friction = material_friction;
7836 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7837 physdata.Bounce = material_restitution;
7838 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7839 physdata.GravitationModifier = material_gravity_modifier;
7840
7841 part.UpdateExtraPhysics(physdata);
7274 } 7842 }
7275 7843
7276 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7844 public void llSetPhysicsMaterial(int material_bits,
7845 float material_gravity_modifier, float material_restitution,
7846 float material_friction, float material_density)
7277 { 7847 {
7278 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7848 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7849 }
7279 7850
7280 LSL_List remaining = null; 7851 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7281 uint rulesParsed = 0; 7852 {
7853 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7854 llSetLinkPrimitiveParamsFast(linknumber, rules);
7855 ScriptSleep(200);
7856 }
7282 7857
7283 foreach (SceneObjectPart part in parts) 7858 // vector up using libomv (c&p from sop )
7284 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7859 // vector up rotated by r
7860 private Vector3 Zrot(Quaternion r)
7861 {
7862 double x, y, z, m;
7285 7863
7286 while (remaining != null && remaining.Length > 2) 7864 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7865 if (Math.Abs(1.0 - m) > 0.000001)
7287 { 7866 {
7288 linknumber = remaining.GetLSLIntegerItem(0); 7867 m = 1.0 / Math.Sqrt(m);
7289 rules = remaining.GetSublist(1, -1); 7868 r.X *= (float)m;
7290 parts = GetLinkParts(linknumber); 7869 r.Y *= (float)m;
7291 7870 r.Z *= (float)m;
7292 foreach (SceneObjectPart part in parts) 7871 r.W *= (float)m;
7293 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7294 } 7872 }
7873
7874 x = 2 * (r.X * r.Z + r.Y * r.W);
7875 y = 2 * (-r.X * r.W + r.Y * r.Z);
7876 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7877
7878 return new Vector3((float)x, (float)y, (float)z);
7295 } 7879 }
7296 7880
7297 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7881 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7298 { 7882 {
7883 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7884 return null;
7885
7299 int idx = 0; 7886 int idx = 0;
7300 int idxStart = 0; 7887 int idxStart = 0;
7301 7888
7889 SceneObjectGroup parentgrp = part.ParentGroup;
7890
7302 bool positionChanged = false; 7891 bool positionChanged = false;
7303 LSL_Vector currentPosition = GetPartLocalPos(part); 7892 LSL_Vector currentPosition = GetPartLocalPos(part);
7304 7893
@@ -7323,8 +7912,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7323 return null; 7912 return null;
7324 7913
7325 v=rules.GetVector3Item(idx++); 7914 v=rules.GetVector3Item(idx++);
7915 if (part.IsRoot && !part.ParentGroup.IsAttachment)
7916 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
7917 else
7918 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7326 positionChanged = true; 7919 positionChanged = true;
7327 currentPosition = GetSetPosTarget(part, v, currentPosition);
7328 7920
7329 break; 7921 break;
7330 case (int)ScriptBaseClass.PRIM_SIZE: 7922 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7341,7 +7933,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7341 7933
7342 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7934 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7343 // try to let this work as in SL... 7935 // try to let this work as in SL...
7344 if (part.ParentID == 0) 7936 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7345 { 7937 {
7346 // special case: If we are root, rotate complete SOG to new rotation 7938 // special case: If we are root, rotate complete SOG to new rotation
7347 SetRot(part, q); 7939 SetRot(part, q);
@@ -7601,7 +8193,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7601 return null; 8193 return null;
7602 8194
7603 string ph = rules.Data[idx++].ToString(); 8195 string ph = rules.Data[idx++].ToString();
7604 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8196 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7605 8197
7606 break; 8198 break;
7607 8199
@@ -7635,12 +8227,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7635 8227
7636 break; 8228 break;
7637 8229
8230 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8231 if (remain < 5)
8232 return null;
8233
8234 int material_bits = rules.GetLSLIntegerItem(idx++);
8235 float material_density = (float)rules.GetLSLFloatItem(idx++);
8236 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8237 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8238 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8239
8240 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8241
8242 break;
8243
7638 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8244 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7639 if (remain < 1) 8245 if (remain < 1)
7640 return null; 8246 return null;
7641 string temp = rules.Data[idx++].ToString(); 8247 string temp = rules.Data[idx++].ToString();
7642 8248
7643 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8249 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7644 8250
7645 break; 8251 break;
7646 8252
@@ -7714,14 +8320,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7714 if (part.ParentGroup.RootPart == part) 8320 if (part.ParentGroup.RootPart == part)
7715 { 8321 {
7716 SceneObjectGroup parent = part.ParentGroup; 8322 SceneObjectGroup parent = part.ParentGroup;
7717 parent.UpdateGroupPosition(currentPosition); 8323 Util.FireAndForget(delegate(object x) {
8324 parent.UpdateGroupPosition(currentPosition);
8325 });
7718 } 8326 }
7719 else 8327 else
7720 { 8328 {
7721 part.OffsetPosition = currentPosition; 8329 part.OffsetPosition = currentPosition;
7722 SceneObjectGroup parent = part.ParentGroup; 8330// SceneObjectGroup parent = part.ParentGroup;
7723 parent.HasGroupChanged = true; 8331// parent.HasGroupChanged = true;
7724 parent.ScheduleGroupForTerseUpdate(); 8332// parent.ScheduleGroupForTerseUpdate();
8333 part.ScheduleTerseUpdate();
7725 } 8334 }
7726 } 8335 }
7727 } 8336 }
@@ -7759,10 +8368,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7759 8368
7760 public LSL_String llXorBase64Strings(string str1, string str2) 8369 public LSL_String llXorBase64Strings(string str1, string str2)
7761 { 8370 {
7762 m_host.AddScriptLPS(1); 8371 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7763 Deprecated("llXorBase64Strings"); 8372
7764 ScriptSleep(300); 8373 ScriptSleep(300);
7765 return String.Empty; 8374 m_host.AddScriptLPS(1);
8375
8376 if (str1 == String.Empty)
8377 return String.Empty;
8378 if (str2 == String.Empty)
8379 return str1;
8380
8381 int len = str2.Length;
8382 if ((len % 4) != 0) // LL is EVIL!!!!
8383 {
8384 while (str2.EndsWith("="))
8385 str2 = str2.Substring(0, str2.Length - 1);
8386
8387 len = str2.Length;
8388 int mod = len % 4;
8389
8390 if (mod == 1)
8391 str2 = str2.Substring(0, str2.Length - 1);
8392 else if (mod == 2)
8393 str2 += "==";
8394 else if (mod == 3)
8395 str2 += "=";
8396 }
8397
8398 byte[] data1;
8399 byte[] data2;
8400 try
8401 {
8402 data1 = Convert.FromBase64String(str1);
8403 data2 = Convert.FromBase64String(str2);
8404 }
8405 catch (Exception)
8406 {
8407 return new LSL_String(String.Empty);
8408 }
8409
8410 // For cases where the decoded length of s2 is greater
8411 // than the decoded length of s1, simply perform a normal
8412 // decode and XOR
8413 //
8414 if (data2.Length >= data1.Length)
8415 {
8416 for (int pos = 0 ; pos < data1.Length ; pos++ )
8417 data1[pos] ^= data2[pos];
8418
8419 return Convert.ToBase64String(data1);
8420 }
8421
8422 // Remove padding
8423 while (str1.EndsWith("="))
8424 str1 = str1.Substring(0, str1.Length - 1);
8425 while (str2.EndsWith("="))
8426 str2 = str2.Substring(0, str2.Length - 1);
8427
8428 byte[] d1 = new byte[str1.Length];
8429 byte[] d2 = new byte[str2.Length];
8430
8431 for (int i = 0 ; i < str1.Length ; i++)
8432 {
8433 int idx = b64.IndexOf(str1.Substring(i, 1));
8434 if (idx == -1)
8435 idx = 0;
8436 d1[i] = (byte)idx;
8437 }
8438
8439 for (int i = 0 ; i < str2.Length ; i++)
8440 {
8441 int idx = b64.IndexOf(str2.Substring(i, 1));
8442 if (idx == -1)
8443 idx = 0;
8444 d2[i] = (byte)idx;
8445 }
8446
8447 string output = String.Empty;
8448
8449 for (int pos = 0 ; pos < d1.Length ; pos++)
8450 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8451
8452 while (output.Length % 3 > 0)
8453 output += "=";
8454
8455 return output;
7766 } 8456 }
7767 8457
7768 public void llRemoteDataSetRegion() 8458 public void llRemoteDataSetRegion()
@@ -7889,8 +8579,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7889 public LSL_Integer llGetNumberOfPrims() 8579 public LSL_Integer llGetNumberOfPrims()
7890 { 8580 {
7891 m_host.AddScriptLPS(1); 8581 m_host.AddScriptLPS(1);
7892 8582 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7893 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8583
8584 return m_host.ParentGroup.PrimCount + avatarCount;
7894 } 8585 }
7895 8586
7896 /// <summary> 8587 /// <summary>
@@ -7905,55 +8596,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7905 m_host.AddScriptLPS(1); 8596 m_host.AddScriptLPS(1);
7906 UUID objID = UUID.Zero; 8597 UUID objID = UUID.Zero;
7907 LSL_List result = new LSL_List(); 8598 LSL_List result = new LSL_List();
8599
8600 // If the ID is not valid, return null result
7908 if (!UUID.TryParse(obj, out objID)) 8601 if (!UUID.TryParse(obj, out objID))
7909 { 8602 {
7910 result.Add(new LSL_Vector()); 8603 result.Add(new LSL_Vector());
7911 result.Add(new LSL_Vector()); 8604 result.Add(new LSL_Vector());
7912 return result; 8605 return result;
7913 } 8606 }
8607
8608 // Check if this is an attached prim. If so, replace
8609 // the UUID with the avatar UUID and report it's bounding box
8610 SceneObjectPart part = World.GetSceneObjectPart(objID);
8611 if (part != null && part.ParentGroup.IsAttachment)
8612 objID = part.ParentGroup.AttachedAvatar;
8613
8614 // Find out if this is an avatar ID. If so, return it's box
7914 ScenePresence presence = World.GetScenePresence(objID); 8615 ScenePresence presence = World.GetScenePresence(objID);
7915 if (presence != null) 8616 if (presence != null)
7916 { 8617 {
7917 if (presence.ParentID == 0) // not sat on an object 8618 // As per LSL Wiki, there is no difference between sitting
8619 // and standing avatar since server 1.36
8620 LSL_Vector lower;
8621 LSL_Vector upper;
8622
8623 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8624
8625 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8626 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8627/*
7918 { 8628 {
7919 LSL_Vector lower; 8629 // This is for ground sitting avatars
7920 LSL_Vector upper; 8630 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7921 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8631 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7922 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8632 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7923 { 8633 }
7924 // This is for ground sitting avatars 8634 else
7925 float height = presence.Appearance.AvatarHeight / 2.66666667f; 8635 {
7926 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); 8636 // This is for standing/flying avatars
7927 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); 8637 float height = presence.Appearance.AvatarHeight / 2.0f;
7928 } 8638 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7929 else 8639 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7930 { 8640 }
7931 // This is for standing/flying avatars 8641
7932 float height = presence.Appearance.AvatarHeight / 2.0f; 8642 // Adjust to the documented error offsets (see LSL Wiki)
7933 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); 8643 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7934 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); 8644 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7935 } 8645*/
7936 result.Add(lower); 8646 {
7937 result.Add(upper); 8647 // This is for ground sitting avatars TODO!
7938 return result; 8648 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8649 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
7939 } 8650 }
7940 else 8651 else
7941 { 8652 {
7942 // sitting on an object so we need the bounding box of that 8653 // This is for standing/flying avatars
7943 // which should include the avatar so set the UUID to the 8654 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
7944 // UUID of the object the avatar is sat on and allow it to fall through 8655 upper = new LSL_Vector(box.X, box.Y, box.Z);
7945 // to processing an object
7946 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7947 objID = p.UUID;
7948 } 8656 }
8657
8658 if (lower.x > upper.x)
8659 lower.x = upper.x;
8660 if (lower.y > upper.y)
8661 lower.y = upper.y;
8662 if (lower.z > upper.z)
8663 lower.z = upper.z;
8664
8665 result.Add(lower);
8666 result.Add(upper);
8667 return result;
7949 } 8668 }
7950 SceneObjectPart part = World.GetSceneObjectPart(objID); 8669
8670 part = World.GetSceneObjectPart(objID);
7951 // Currently only works for single prims without a sitting avatar 8671 // Currently only works for single prims without a sitting avatar
7952 if (part != null) 8672 if (part != null)
7953 { 8673 {
7954 Vector3 halfSize = part.Scale / 2.0f; 8674 float minX;
7955 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8675 float maxX;
7956 LSL_Vector upper = new LSL_Vector(halfSize); 8676 float minY;
8677 float maxY;
8678 float minZ;
8679 float maxZ;
8680
8681 // This BBox is in sim coordinates, with the offset being
8682 // a contained point.
8683 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8684 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8685
8686 minX -= offsets[0].X;
8687 maxX -= offsets[0].X;
8688 minY -= offsets[0].Y;
8689 maxY -= offsets[0].Y;
8690 minZ -= offsets[0].Z;
8691 maxZ -= offsets[0].Z;
8692
8693 LSL_Vector lower;
8694 LSL_Vector upper;
8695
8696 // Adjust to the documented error offsets (see LSL Wiki)
8697 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8698 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8699
8700 if (lower.x > upper.x)
8701 lower.x = upper.x;
8702 if (lower.y > upper.y)
8703 lower.y = upper.y;
8704 if (lower.z > upper.z)
8705 lower.z = upper.z;
8706
7957 result.Add(lower); 8707 result.Add(lower);
7958 result.Add(upper); 8708 result.Add(upper);
7959 return result; 8709 return result;
@@ -7967,7 +8717,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7967 8717
7968 public LSL_Vector llGetGeometricCenter() 8718 public LSL_Vector llGetGeometricCenter()
7969 { 8719 {
7970 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8720 Vector3 tmp = m_host.GetGeometricCenter();
8721 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7971 } 8722 }
7972 8723
7973 public LSL_List llGetPrimitiveParams(LSL_List rules) 8724 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7978,7 +8729,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7978 8729
7979 LSL_List remaining = GetPrimParams(m_host, rules, ref result); 8730 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
7980 8731
7981 while (remaining != null && remaining.Length > 2) 8732 while ((object)remaining != null && remaining.Length > 2)
7982 { 8733 {
7983 int linknumber = remaining.GetLSLIntegerItem(0); 8734 int linknumber = remaining.GetLSLIntegerItem(0);
7984 rules = remaining.GetSublist(1, -1); 8735 rules = remaining.GetSublist(1, -1);
@@ -7995,24 +8746,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7995 { 8746 {
7996 m_host.AddScriptLPS(1); 8747 m_host.AddScriptLPS(1);
7997 8748
7998 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8749 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8750 // keep other options as before
7999 8751
8752 List<SceneObjectPart> parts;
8753 List<ScenePresence> avatars;
8754
8000 LSL_List res = new LSL_List(); 8755 LSL_List res = new LSL_List();
8001 LSL_List remaining = null; 8756 LSL_List remaining = null;
8002 8757
8003 foreach (SceneObjectPart part in parts) 8758 while (rules.Length > 0)
8004 {
8005 remaining = GetPrimParams(part, rules, ref res);
8006 }
8007
8008 while (remaining != null && remaining.Length > 2)
8009 { 8759 {
8010 linknumber = remaining.GetLSLIntegerItem(0);
8011 rules = remaining.GetSublist(1, -1);
8012 parts = GetLinkParts(linknumber); 8760 parts = GetLinkParts(linknumber);
8761 avatars = GetLinkAvatars(linknumber);
8013 8762
8763 remaining = null;
8014 foreach (SceneObjectPart part in parts) 8764 foreach (SceneObjectPart part in parts)
8765 {
8015 remaining = GetPrimParams(part, rules, ref res); 8766 remaining = GetPrimParams(part, rules, ref res);
8767 }
8768 foreach (ScenePresence avatar in avatars)
8769 {
8770 remaining = GetPrimParams(avatar, rules, ref res);
8771 }
8772
8773 if ((object)remaining != null && remaining.Length > 0)
8774 {
8775 linknumber = remaining.GetLSLIntegerItem(0);
8776 rules = remaining.GetSublist(1, -1);
8777 }
8778 else
8779 break;
8016 } 8780 }
8017 8781
8018 return res; 8782 return res;
@@ -8057,13 +8821,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8057 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8821 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8058 part.AbsolutePosition.Y, 8822 part.AbsolutePosition.Y,
8059 part.AbsolutePosition.Z); 8823 part.AbsolutePosition.Z);
8060 // For some reason, the part.AbsolutePosition.* values do not change if the
8061 // linkset is rotated; they always reflect the child prim's world position
8062 // as though the linkset is unrotated. This is incompatible behavior with SL's
8063 // implementation, so will break scripts imported from there (not to mention it
8064 // makes it more difficult to determine a child prim's actual inworld position).
8065 if (part.ParentID != 0)
8066 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8067 res.Add(v); 8824 res.Add(v);
8068 break; 8825 break;
8069 8826
@@ -8235,30 +8992,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8235 if (remain < 1) 8992 if (remain < 1)
8236 return null; 8993 return null;
8237 8994
8238 face=(int)rules.GetLSLIntegerItem(idx++); 8995 face = (int)rules.GetLSLIntegerItem(idx++);
8239 8996
8240 tex = part.Shape.Textures; 8997 tex = part.Shape.Textures;
8998 int shiny;
8241 if (face == ScriptBaseClass.ALL_SIDES) 8999 if (face == ScriptBaseClass.ALL_SIDES)
8242 { 9000 {
8243 for (face = 0; face < GetNumberOfSides(part); face++) 9001 for (face = 0; face < GetNumberOfSides(part); face++)
8244 { 9002 {
8245 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9003 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8246 // Convert Shininess to PRIM_SHINY_* 9004 if (shinyness == Shininess.High)
8247 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9005 {
8248 // PRIM_BUMP_* 9006 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8249 res.Add(new LSL_Integer((int)texface.Bump)); 9007 }
9008 else if (shinyness == Shininess.Medium)
9009 {
9010 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9011 }
9012 else if (shinyness == Shininess.Low)
9013 {
9014 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9015 }
9016 else
9017 {
9018 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9019 }
9020 res.Add(new LSL_Integer(shiny));
9021 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8250 } 9022 }
8251 } 9023 }
8252 else 9024 else
8253 { 9025 {
8254 if (face >= 0 && face < GetNumberOfSides(part)) 9026 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9027 if (shinyness == Shininess.High)
8255 { 9028 {
8256 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9029 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8257 // Convert Shininess to PRIM_SHINY_*
8258 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8259 // PRIM_BUMP_*
8260 res.Add(new LSL_Integer((int)texface.Bump));
8261 } 9030 }
9031 else if (shinyness == Shininess.Medium)
9032 {
9033 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9034 }
9035 else if (shinyness == Shininess.Low)
9036 {
9037 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9038 }
9039 else
9040 {
9041 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9042 }
9043 res.Add(new LSL_Integer(shiny));
9044 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8262 } 9045 }
8263 break; 9046 break;
8264 9047
@@ -8266,24 +9049,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8266 if (remain < 1) 9049 if (remain < 1)
8267 return null; 9050 return null;
8268 9051
8269 face=(int)rules.GetLSLIntegerItem(idx++); 9052 face = (int)rules.GetLSLIntegerItem(idx++);
8270 9053
8271 tex = part.Shape.Textures; 9054 tex = part.Shape.Textures;
9055 int fullbright;
8272 if (face == ScriptBaseClass.ALL_SIDES) 9056 if (face == ScriptBaseClass.ALL_SIDES)
8273 { 9057 {
8274 for (face = 0; face < GetNumberOfSides(part); face++) 9058 for (face = 0; face < GetNumberOfSides(part); face++)
8275 { 9059 {
8276 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9060 if (tex.GetFace((uint)face).Fullbright == true)
8277 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9061 {
9062 fullbright = ScriptBaseClass.TRUE;
9063 }
9064 else
9065 {
9066 fullbright = ScriptBaseClass.FALSE;
9067 }
9068 res.Add(new LSL_Integer(fullbright));
8278 } 9069 }
8279 } 9070 }
8280 else 9071 else
8281 { 9072 {
8282 if (face >= 0 && face < GetNumberOfSides(part)) 9073 if (tex.GetFace((uint)face).Fullbright == true)
8283 { 9074 {
8284 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9075 fullbright = ScriptBaseClass.TRUE;
8285 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8286 } 9076 }
9077 else
9078 {
9079 fullbright = ScriptBaseClass.FALSE;
9080 }
9081 res.Add(new LSL_Integer(fullbright));
8287 } 9082 }
8288 break; 9083 break;
8289 9084
@@ -8305,27 +9100,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8305 break; 9100 break;
8306 9101
8307 case (int)ScriptBaseClass.PRIM_TEXGEN: 9102 case (int)ScriptBaseClass.PRIM_TEXGEN:
9103 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8308 if (remain < 1) 9104 if (remain < 1)
8309 return null; 9105 return null;
8310 9106
8311 face=(int)rules.GetLSLIntegerItem(idx++); 9107 face = (int)rules.GetLSLIntegerItem(idx++);
8312 9108
8313 tex = part.Shape.Textures; 9109 tex = part.Shape.Textures;
8314 if (face == ScriptBaseClass.ALL_SIDES) 9110 if (face == ScriptBaseClass.ALL_SIDES)
8315 { 9111 {
8316 for (face = 0; face < GetNumberOfSides(part); face++) 9112 for (face = 0; face < GetNumberOfSides(part); face++)
8317 { 9113 {
8318 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9114 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8319 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9115 {
8320 res.Add(new LSL_Integer((uint)texgen >> 1)); 9116 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9117 }
9118 else
9119 {
9120 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9121 }
8321 } 9122 }
8322 } 9123 }
8323 else 9124 else
8324 { 9125 {
8325 if (face >= 0 && face < GetNumberOfSides(part)) 9126 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8326 { 9127 {
8327 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9128 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8328 res.Add(new LSL_Integer((uint)texgen >> 1)); 9129 }
9130 else
9131 {
9132 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8329 } 9133 }
8330 } 9134 }
8331 break; 9135 break;
@@ -8349,24 +9153,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8349 if (remain < 1) 9153 if (remain < 1)
8350 return null; 9154 return null;
8351 9155
8352 face=(int)rules.GetLSLIntegerItem(idx++); 9156 face = (int)rules.GetLSLIntegerItem(idx++);
8353 9157
8354 tex = part.Shape.Textures; 9158 tex = part.Shape.Textures;
9159 float primglow;
8355 if (face == ScriptBaseClass.ALL_SIDES) 9160 if (face == ScriptBaseClass.ALL_SIDES)
8356 { 9161 {
8357 for (face = 0; face < GetNumberOfSides(part); face++) 9162 for (face = 0; face < GetNumberOfSides(part); face++)
8358 { 9163 {
8359 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9164 primglow = tex.GetFace((uint)face).Glow;
8360 res.Add(new LSL_Float(texface.Glow)); 9165 res.Add(new LSL_Float(primglow));
8361 } 9166 }
8362 } 9167 }
8363 else 9168 else
8364 { 9169 {
8365 if (face >= 0 && face < GetNumberOfSides(part)) 9170 primglow = tex.GetFace((uint)face).Glow;
8366 { 9171 res.Add(new LSL_Float(primglow));
8367 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8368 res.Add(new LSL_Float(texface.Glow));
8369 }
8370 } 9172 }
8371 break; 9173 break;
8372 9174
@@ -8378,15 +9180,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8378 textColor.B)); 9180 textColor.B));
8379 res.Add(new LSL_Float(textColor.A)); 9181 res.Add(new LSL_Float(textColor.A));
8380 break; 9182 break;
9183
8381 case (int)ScriptBaseClass.PRIM_NAME: 9184 case (int)ScriptBaseClass.PRIM_NAME:
8382 res.Add(new LSL_String(part.Name)); 9185 res.Add(new LSL_String(part.Name));
8383 break; 9186 break;
9187
8384 case (int)ScriptBaseClass.PRIM_DESC: 9188 case (int)ScriptBaseClass.PRIM_DESC:
8385 res.Add(new LSL_String(part.Description)); 9189 res.Add(new LSL_String(part.Description));
8386 break; 9190 break;
9191
8387 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9192 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8388 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9193 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8389 break; 9194 break;
9195
8390 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9196 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8391 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9197 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8392 break; 9198 break;
@@ -8997,8 +9803,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8997 // The function returns an ordered list 9803 // The function returns an ordered list
8998 // representing the tokens found in the supplied 9804 // representing the tokens found in the supplied
8999 // sources string. If two successive tokenizers 9805 // sources string. If two successive tokenizers
9000 // are encountered, then a NULL entry is added 9806 // are encountered, then a null-string entry is
9001 // to the list. 9807 // added to the list.
9002 // 9808 //
9003 // It is a precondition that the source and 9809 // It is a precondition that the source and
9004 // toekizer lisst are non-null. If they are null, 9810 // toekizer lisst are non-null. If they are null,
@@ -9006,7 +9812,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9006 // while their lengths are being determined. 9812 // while their lengths are being determined.
9007 // 9813 //
9008 // A small amount of working memoryis required 9814 // A small amount of working memoryis required
9009 // of approximately 8*#tokenizers. 9815 // of approximately 8*#tokenizers + 8*srcstrlen.
9010 // 9816 //
9011 // There are many ways in which this function 9817 // There are many ways in which this function
9012 // can be implemented, this implementation is 9818 // can be implemented, this implementation is
@@ -9022,155 +9828,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9022 // and eliminates redundant tokenizers as soon 9828 // and eliminates redundant tokenizers as soon
9023 // as is possible. 9829 // as is possible.
9024 // 9830 //
9025 // The implementation tries to avoid any copying 9831 // The implementation tries to minimize temporary
9026 // of arrays or other objects. 9832 // garbage generation.
9027 // </remarks> 9833 // </remarks>
9028 9834
9029 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9835 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9030 { 9836 {
9031 int beginning = 0; 9837 return ParseString2List(src, separators, spacers, true);
9032 int srclen = src.Length; 9838 }
9033 int seplen = separators.Length;
9034 object[] separray = separators.Data;
9035 int spclen = spacers.Length;
9036 object[] spcarray = spacers.Data;
9037 int mlen = seplen+spclen;
9038
9039 int[] offset = new int[mlen+1];
9040 bool[] active = new bool[mlen];
9041
9042 int best;
9043 int j;
9044
9045 // Initial capacity reduces resize cost
9046 9839
9047 LSL_List tokens = new LSL_List(); 9840 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9841 {
9842 int srclen = src.Length;
9843 int seplen = separators.Length;
9844 object[] separray = separators.Data;
9845 int spclen = spacers.Length;
9846 object[] spcarray = spacers.Data;
9847 int dellen = 0;
9848 string[] delarray = new string[seplen+spclen];
9048 9849
9049 // All entries are initially valid 9850 int outlen = 0;
9851 string[] outarray = new string[srclen*2+1];
9050 9852
9051 for (int i = 0; i < mlen; i++) 9853 int i, j;
9052 active[i] = true; 9854 string d;
9053 9855
9054 offset[mlen] = srclen; 9856 m_host.AddScriptLPS(1);
9055 9857
9056 while (beginning < srclen) 9858 /*
9859 * Convert separator and spacer lists to C# strings.
9860 * Also filter out null strings so we don't hang.
9861 */
9862 for (i = 0; i < seplen; i ++)
9057 { 9863 {
9864 d = separray[i].ToString();
9865 if (d.Length > 0)
9866 {
9867 delarray[dellen++] = d;
9868 }
9869 }
9870 seplen = dellen;
9058 9871
9059 best = mlen; // as bad as it gets 9872 for (i = 0; i < spclen; i ++)
9873 {
9874 d = spcarray[i].ToString();
9875 if (d.Length > 0)
9876 {
9877 delarray[dellen++] = d;
9878 }
9879 }
9060 9880
9061 // Scan for separators 9881 /*
9882 * Scan through source string from beginning to end.
9883 */
9884 for (i = 0;;)
9885 {
9062 9886
9063 for (j = 0; j < seplen; j++) 9887 /*
9888 * Find earliest delimeter in src starting at i (if any).
9889 */
9890 int earliestDel = -1;
9891 int earliestSrc = srclen;
9892 string earliestStr = null;
9893 for (j = 0; j < dellen; j ++)
9064 { 9894 {
9065 if (separray[j].ToString() == String.Empty) 9895 d = delarray[j];
9066 active[j] = false; 9896 if (d != null)
9067
9068 if (active[j])
9069 { 9897 {
9070 // scan all of the markers 9898 int index = src.IndexOf(d, i);
9071 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9899 if (index < 0)
9072 { 9900 {
9073 // not present at all 9901 delarray[j] = null; // delim nowhere in src, don't check it anymore
9074 active[j] = false;
9075 } 9902 }
9076 else 9903 else if (index < earliestSrc)
9077 { 9904 {
9078 // present and correct 9905 earliestSrc = index; // where delimeter starts in source string
9079 if (offset[j] < offset[best]) 9906 earliestDel = j; // where delimeter is in delarray[]
9080 { 9907 earliestStr = d; // the delimeter string from delarray[]
9081 // closest so far 9908 if (index == i) break; // can't do any better than found at beg of string
9082 best = j;
9083 if (offset[best] == beginning)
9084 break;
9085 }
9086 } 9909 }
9087 } 9910 }
9088 } 9911 }
9089 9912
9090 // Scan for spacers 9913 /*
9091 9914 * Output source string starting at i through start of earliest delimeter.
9092 if (offset[best] != beginning) 9915 */
9916 if (keepNulls || (earliestSrc > i))
9093 { 9917 {
9094 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9918 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9095 {
9096 if (spcarray[j-seplen].ToString() == String.Empty)
9097 active[j] = false;
9098
9099 if (active[j])
9100 {
9101 // scan all of the markers
9102 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9103 {
9104 // not present at all
9105 active[j] = false;
9106 }
9107 else
9108 {
9109 // present and correct
9110 if (offset[j] < offset[best])
9111 {
9112 // closest so far
9113 best = j;
9114 }
9115 }
9116 }
9117 }
9118 } 9919 }
9119 9920
9120 // This is the normal exit from the scanning loop 9921 /*
9922 * If no delimeter found at or after i, we're done scanning.
9923 */
9924 if (earliestDel < 0) break;
9121 9925
9122 if (best == mlen) 9926 /*
9927 * If delimeter was a spacer, output the spacer.
9928 */
9929 if (earliestDel >= seplen)
9123 { 9930 {
9124 // no markers were found on this pass 9931 outarray[outlen++] = earliestStr;
9125 // so we're pretty much done
9126 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9127 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9128 break;
9129 } 9932 }
9130 9933
9131 // Otherwise we just add the newly delimited token 9934 /*
9132 // and recalculate where the search should continue. 9935 * Look at rest of src string following delimeter.
9133 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9936 */
9134 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9937 i = earliestSrc + earliestStr.Length;
9135
9136 if (best < seplen)
9137 {
9138 beginning = offset[best] + (separray[best].ToString()).Length;
9139 }
9140 else
9141 {
9142 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9143 string str = spcarray[best - seplen].ToString();
9144 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9145 tokens.Add(new LSL_String(str));
9146 }
9147 } 9938 }
9148 9939
9149 // This an awkward an not very intuitive boundary case. If the 9940 /*
9150 // last substring is a tokenizer, then there is an implied trailing 9941 * Make up an exact-sized output array suitable for an LSL_List object.
9151 // null list entry. Hopefully the single comparison will not be too 9942 */
9152 // arduous. Alternatively the 'break' could be replced with a return 9943 object[] outlist = new object[outlen];
9153 // but that's shabby programming. 9944 for (i = 0; i < outlen; i ++)
9154
9155 if ((beginning == srclen) && (keepNulls))
9156 { 9945 {
9157 if (srclen != 0) 9946 outlist[i] = new LSL_String(outarray[i]);
9158 tokens.Add(new LSL_String(""));
9159 } 9947 }
9160 9948 return new LSL_List(outlist);
9161 return tokens;
9162 }
9163
9164 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9165 {
9166 m_host.AddScriptLPS(1);
9167 return this.ParseString(src, separators, spacers, false);
9168 }
9169
9170 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9171 {
9172 m_host.AddScriptLPS(1);
9173 return this.ParseString(src, separators, spacers, true);
9174 } 9949 }
9175 9950
9176 public LSL_Integer llGetObjectPermMask(int mask) 9951 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9265,6 +10040,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9265 case 4: 10040 case 4:
9266 return (int)item.NextPermissions; 10041 return (int)item.NextPermissions;
9267 } 10042 }
10043 m_host.TaskInventory.LockItemsForRead(false);
9268 10044
9269 return -1; 10045 return -1;
9270 } 10046 }
@@ -9468,31 +10244,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9468 UUID key = new UUID(); 10244 UUID key = new UUID();
9469 if (UUID.TryParse(id, out key)) 10245 if (UUID.TryParse(id, out key))
9470 { 10246 {
9471 try 10247 // return total object mass
9472 { 10248 SceneObjectPart part = World.GetSceneObjectPart(key);
9473 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10249 if (part != null)
9474 if (obj != null) 10250 return part.ParentGroup.GetMass();
9475 return (double)obj.GetMass(); 10251
9476 // the object is null so the key is for an avatar 10252 // the object is null so the key is for an avatar
9477 ScenePresence avatar = World.GetScenePresence(key); 10253 ScenePresence avatar = World.GetScenePresence(key);
9478 if (avatar != null) 10254 if (avatar != null)
9479 if (avatar.IsChildAgent)
9480 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9481 // child agents have a mass of 1.0
9482 return 1;
9483 else
9484 return (double)avatar.GetMass();
9485 }
9486 catch (KeyNotFoundException)
9487 { 10255 {
9488 return 0; // The Object/Agent not in the region so just return zero 10256 if (avatar.IsChildAgent)
10257 {
10258 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10259 // child agents have a mass of 1.0
10260 return 1;
10261 }
10262 else
10263 {
10264 return (double)avatar.GetMass();
10265 }
9489 } 10266 }
9490 } 10267 }
9491 return 0; 10268 return 0;
9492 } 10269 }
9493 10270
9494 /// <summary> 10271 /// <summary>
9495 /// illListReplaceList removes the sub-list defined by the inclusive indices 10272 /// llListReplaceList removes the sub-list defined by the inclusive indices
9496 /// start and end and inserts the src list in its place. The inclusive 10273 /// start and end and inserts the src list in its place. The inclusive
9497 /// nature of the indices means that at least one element must be deleted 10274 /// nature of the indices means that at least one element must be deleted
9498 /// if the indices are within the bounds of the existing list. I.e. 2,2 10275 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9549,16 +10326,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9549 // based upon end. Note that if end exceeds the upper 10326 // based upon end. Note that if end exceeds the upper
9550 // bound in this case, the entire destination list 10327 // bound in this case, the entire destination list
9551 // is removed. 10328 // is removed.
9552 else 10329 else if (start == 0)
9553 { 10330 {
9554 if (end + 1 < dest.Length) 10331 if (end + 1 < dest.Length)
9555 {
9556 return src + dest.GetSublist(end + 1, -1); 10332 return src + dest.GetSublist(end + 1, -1);
9557 }
9558 else 10333 else
9559 {
9560 return src; 10334 return src;
9561 } 10335 }
10336 else // Start < 0
10337 {
10338 if (end + 1 < dest.Length)
10339 return dest.GetSublist(end + 1, -1);
10340 else
10341 return new LSL_List();
9562 } 10342 }
9563 } 10343 }
9564 // Finally, if start > end, we strip away a prefix and 10344 // Finally, if start > end, we strip away a prefix and
@@ -9609,17 +10389,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9609 int width = 0; 10389 int width = 0;
9610 int height = 0; 10390 int height = 0;
9611 10391
9612 ParcelMediaCommandEnum? commandToSend = null; 10392 uint commandToSend = 0;
9613 float time = 0.0f; // default is from start 10393 float time = 0.0f; // default is from start
9614 10394
9615 ScenePresence presence = null; 10395 ScenePresence presence = null;
9616 10396
9617 for (int i = 0; i < commandList.Data.Length; i++) 10397 for (int i = 0; i < commandList.Data.Length; i++)
9618 { 10398 {
9619 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10399 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9620 switch (command) 10400 switch (command)
9621 { 10401 {
9622 case ParcelMediaCommandEnum.Agent: 10402 case (uint)ParcelMediaCommandEnum.Agent:
9623 // we send only to one agent 10403 // we send only to one agent
9624 if ((i + 1) < commandList.Length) 10404 if ((i + 1) < commandList.Length)
9625 { 10405 {
@@ -9636,25 +10416,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9636 } 10416 }
9637 break; 10417 break;
9638 10418
9639 case ParcelMediaCommandEnum.Loop: 10419 case (uint)ParcelMediaCommandEnum.Loop:
9640 loop = 1; 10420 loop = 1;
9641 commandToSend = command; 10421 commandToSend = command;
9642 update = true; //need to send the media update packet to set looping 10422 update = true; //need to send the media update packet to set looping
9643 break; 10423 break;
9644 10424
9645 case ParcelMediaCommandEnum.Play: 10425 case (uint)ParcelMediaCommandEnum.Play:
9646 loop = 0; 10426 loop = 0;
9647 commandToSend = command; 10427 commandToSend = command;
9648 update = true; //need to send the media update packet to make sure it doesn't loop 10428 update = true; //need to send the media update packet to make sure it doesn't loop
9649 break; 10429 break;
9650 10430
9651 case ParcelMediaCommandEnum.Pause: 10431 case (uint)ParcelMediaCommandEnum.Pause:
9652 case ParcelMediaCommandEnum.Stop: 10432 case (uint)ParcelMediaCommandEnum.Stop:
9653 case ParcelMediaCommandEnum.Unload: 10433 case (uint)ParcelMediaCommandEnum.Unload:
9654 commandToSend = command; 10434 commandToSend = command;
9655 break; 10435 break;
9656 10436
9657 case ParcelMediaCommandEnum.Url: 10437 case (uint)ParcelMediaCommandEnum.Url:
9658 if ((i + 1) < commandList.Length) 10438 if ((i + 1) < commandList.Length)
9659 { 10439 {
9660 if (commandList.Data[i + 1] is LSL_String) 10440 if (commandList.Data[i + 1] is LSL_String)
@@ -9667,7 +10447,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9667 } 10447 }
9668 break; 10448 break;
9669 10449
9670 case ParcelMediaCommandEnum.Texture: 10450 case (uint)ParcelMediaCommandEnum.Texture:
9671 if ((i + 1) < commandList.Length) 10451 if ((i + 1) < commandList.Length)
9672 { 10452 {
9673 if (commandList.Data[i + 1] is LSL_String) 10453 if (commandList.Data[i + 1] is LSL_String)
@@ -9680,7 +10460,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9680 } 10460 }
9681 break; 10461 break;
9682 10462
9683 case ParcelMediaCommandEnum.Time: 10463 case (uint)ParcelMediaCommandEnum.Time:
9684 if ((i + 1) < commandList.Length) 10464 if ((i + 1) < commandList.Length)
9685 { 10465 {
9686 if (commandList.Data[i + 1] is LSL_Float) 10466 if (commandList.Data[i + 1] is LSL_Float)
@@ -9692,7 +10472,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9692 } 10472 }
9693 break; 10473 break;
9694 10474
9695 case ParcelMediaCommandEnum.AutoAlign: 10475 case (uint)ParcelMediaCommandEnum.AutoAlign:
9696 if ((i + 1) < commandList.Length) 10476 if ((i + 1) < commandList.Length)
9697 { 10477 {
9698 if (commandList.Data[i + 1] is LSL_Integer) 10478 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9706,7 +10486,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9706 } 10486 }
9707 break; 10487 break;
9708 10488
9709 case ParcelMediaCommandEnum.Type: 10489 case (uint)ParcelMediaCommandEnum.Type:
9710 if ((i + 1) < commandList.Length) 10490 if ((i + 1) < commandList.Length)
9711 { 10491 {
9712 if (commandList.Data[i + 1] is LSL_String) 10492 if (commandList.Data[i + 1] is LSL_String)
@@ -9719,7 +10499,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9719 } 10499 }
9720 break; 10500 break;
9721 10501
9722 case ParcelMediaCommandEnum.Desc: 10502 case (uint)ParcelMediaCommandEnum.Desc:
9723 if ((i + 1) < commandList.Length) 10503 if ((i + 1) < commandList.Length)
9724 { 10504 {
9725 if (commandList.Data[i + 1] is LSL_String) 10505 if (commandList.Data[i + 1] is LSL_String)
@@ -9732,7 +10512,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9732 } 10512 }
9733 break; 10513 break;
9734 10514
9735 case ParcelMediaCommandEnum.Size: 10515 case (uint)ParcelMediaCommandEnum.Size:
9736 if ((i + 2) < commandList.Length) 10516 if ((i + 2) < commandList.Length)
9737 { 10517 {
9738 if (commandList.Data[i + 1] is LSL_Integer) 10518 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9802,7 +10582,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9802 } 10582 }
9803 } 10583 }
9804 10584
9805 if (commandToSend != null) 10585 if (commandToSend != 0)
9806 { 10586 {
9807 // the commandList contained a start/stop/... command, too 10587 // the commandList contained a start/stop/... command, too
9808 if (presence == null) 10588 if (presence == null)
@@ -9839,7 +10619,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9839 10619
9840 if (aList.Data[i] != null) 10620 if (aList.Data[i] != null)
9841 { 10621 {
9842 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10622 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9843 { 10623 {
9844 case ParcelMediaCommandEnum.Url: 10624 case ParcelMediaCommandEnum.Url:
9845 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10625 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9896,15 +10676,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9896 10676
9897 if (quick_pay_buttons.Data.Length < 4) 10677 if (quick_pay_buttons.Data.Length < 4)
9898 { 10678 {
9899 LSLError("List must have at least 4 elements"); 10679 int x;
9900 return; 10680 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10681 {
10682 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10683 }
9901 } 10684 }
9902 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10685 int[] nPrice = new int[5];
9903 10686 nPrice[0] = price;
9904 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10687 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9905 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10688 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9906 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10689 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9907 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10690 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10691 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9908 m_host.ParentGroup.HasGroupChanged = true; 10692 m_host.ParentGroup.HasGroupChanged = true;
9909 } 10693 }
9910 10694
@@ -9921,7 +10705,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9921 return new LSL_Vector(); 10705 return new LSL_Vector();
9922 } 10706 }
9923 10707
9924 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10708// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10709 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9925 if (presence != null) 10710 if (presence != null)
9926 { 10711 {
9927 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10712 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9943,7 +10728,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9943 return new LSL_Rotation(); 10728 return new LSL_Rotation();
9944 } 10729 }
9945 10730
9946 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10731// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10732 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9947 if (presence != null) 10733 if (presence != null)
9948 { 10734 {
9949 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10735 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -10003,14 +10789,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10003 { 10789 {
10004 m_host.AddScriptLPS(1); 10790 m_host.AddScriptLPS(1);
10005 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10791 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10006 if (detectedParams == null) return; // only works on the first detected avatar 10792 if (detectedParams == null)
10007 10793 {
10794 if (m_host.ParentGroup.IsAttachment == true)
10795 {
10796 detectedParams = new DetectParams();
10797 detectedParams.Key = m_host.OwnerID;
10798 }
10799 else
10800 {
10801 return;
10802 }
10803 }
10804
10008 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10805 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10009 if (avatar != null) 10806 if (avatar != null)
10010 { 10807 {
10011 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10808 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10012 simname, pos, lookAt); 10809 simname, pos, lookAt);
10013 } 10810 }
10811
10014 ScriptSleep(1000); 10812 ScriptSleep(1000);
10015 } 10813 }
10016 10814
@@ -10134,12 +10932,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10134 10932
10135 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10933 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10136 object[] data = rules.Data; 10934 object[] data = rules.Data;
10137 for (int i = 0; i < data.Length; ++i) { 10935 for (int i = 0; i < data.Length; ++i)
10936 {
10138 int type = Convert.ToInt32(data[i++].ToString()); 10937 int type = Convert.ToInt32(data[i++].ToString());
10139 if (i >= data.Length) break; // odd number of entries => ignore the last 10938 if (i >= data.Length) break; // odd number of entries => ignore the last
10140 10939
10141 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10940 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10142 switch (type) { 10941 switch (type)
10942 {
10143 case ScriptBaseClass.CAMERA_FOCUS: 10943 case ScriptBaseClass.CAMERA_FOCUS:
10144 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10944 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10145 case ScriptBaseClass.CAMERA_POSITION: 10945 case ScriptBaseClass.CAMERA_POSITION:
@@ -10244,19 +11044,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10244 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11044 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10245 { 11045 {
10246 m_host.AddScriptLPS(1); 11046 m_host.AddScriptLPS(1);
10247 string ret = String.Empty; 11047
10248 string src1 = llBase64ToString(str1); 11048 if (str1 == String.Empty)
10249 string src2 = llBase64ToString(str2); 11049 return String.Empty;
10250 int c = 0; 11050 if (str2 == String.Empty)
10251 for (int i = 0; i < src1.Length; i++) 11051 return str1;
11052
11053 int len = str2.Length;
11054 if ((len % 4) != 0) // LL is EVIL!!!!
11055 {
11056 while (str2.EndsWith("="))
11057 str2 = str2.Substring(0, str2.Length - 1);
11058
11059 len = str2.Length;
11060 int mod = len % 4;
11061
11062 if (mod == 1)
11063 str2 = str2.Substring(0, str2.Length - 1);
11064 else if (mod == 2)
11065 str2 += "==";
11066 else if (mod == 3)
11067 str2 += "=";
11068 }
11069
11070 byte[] data1;
11071 byte[] data2;
11072 try
11073 {
11074 data1 = Convert.FromBase64String(str1);
11075 data2 = Convert.FromBase64String(str2);
11076 }
11077 catch (Exception)
10252 { 11078 {
10253 ret += (char) (src1[i] ^ src2[c]); 11079 return new LSL_String(String.Empty);
11080 }
10254 11081
10255 c++; 11082 byte[] d2 = new Byte[data1.Length];
10256 if (c >= src2.Length) 11083 int pos = 0;
10257 c = 0; 11084
11085 if (data1.Length <= data2.Length)
11086 {
11087 Array.Copy(data2, 0, d2, 0, data1.Length);
10258 } 11088 }
10259 return llStringToBase64(ret); 11089 else
11090 {
11091 while (pos < data1.Length)
11092 {
11093 len = data1.Length - pos;
11094 if (len > data2.Length)
11095 len = data2.Length;
11096
11097 Array.Copy(data2, 0, d2, pos, len);
11098 pos += len;
11099 }
11100 }
11101
11102 for (pos = 0 ; pos < data1.Length ; pos++ )
11103 data1[pos] ^= d2[pos];
11104
11105 return Convert.ToBase64String(data1);
10260 } 11106 }
10261 11107
10262 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11108 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10309,16 +11155,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10309 if (userAgent != null) 11155 if (userAgent != null)
10310 httpHeaders["User-Agent"] = userAgent; 11156 httpHeaders["User-Agent"] = userAgent;
10311 11157
11158 // See if the URL contains any header hacks
11159 string[] urlParts = url.Split(new char[] {'\n'});
11160 if (urlParts.Length > 1)
11161 {
11162 // Iterate the passed headers and parse them
11163 for (int i = 1 ; i < urlParts.Length ; i++ )
11164 {
11165 // The rest of those would be added to the body in SL.
11166 // Let's not do that.
11167 if (urlParts[i] == String.Empty)
11168 break;
11169
11170 // See if this could be a valid header
11171 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11172 if (headerParts.Length != 2)
11173 continue;
11174
11175 string headerName = headerParts[0].Trim();
11176 string headerValue = headerParts[1].Trim();
11177
11178 // Filter out headers that could be used to abuse
11179 // another system or cloak the request
11180 if (headerName.ToLower() == "x-secondlife-shard" ||
11181 headerName.ToLower() == "x-secondlife-object-name" ||
11182 headerName.ToLower() == "x-secondlife-object-key" ||
11183 headerName.ToLower() == "x-secondlife-region" ||
11184 headerName.ToLower() == "x-secondlife-local-position" ||
11185 headerName.ToLower() == "x-secondlife-local-velocity" ||
11186 headerName.ToLower() == "x-secondlife-local-rotation" ||
11187 headerName.ToLower() == "x-secondlife-owner-name" ||
11188 headerName.ToLower() == "x-secondlife-owner-key" ||
11189 headerName.ToLower() == "connection" ||
11190 headerName.ToLower() == "content-length" ||
11191 headerName.ToLower() == "from" ||
11192 headerName.ToLower() == "host" ||
11193 headerName.ToLower() == "proxy-authorization" ||
11194 headerName.ToLower() == "referer" ||
11195 headerName.ToLower() == "trailer" ||
11196 headerName.ToLower() == "transfer-encoding" ||
11197 headerName.ToLower() == "via" ||
11198 headerName.ToLower() == "authorization")
11199 continue;
11200
11201 httpHeaders[headerName] = headerValue;
11202 }
11203
11204 // Finally, strip any protocol specifier from the URL
11205 url = urlParts[0].Trim();
11206 int idx = url.IndexOf(" HTTP/");
11207 if (idx != -1)
11208 url = url.Substring(0, idx);
11209 }
11210
10312 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11211 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10313 Regex r = new Regex(authregex); 11212 Regex r = new Regex(authregex);
10314 int[] gnums = r.GetGroupNumbers(); 11213 int[] gnums = r.GetGroupNumbers();
10315 Match m = r.Match(url); 11214 Match m = r.Match(url);
10316 if (m.Success) { 11215 if (m.Success)
10317 for (int i = 1; i < gnums.Length; i++) { 11216 {
11217 for (int i = 1; i < gnums.Length; i++)
11218 {
10318 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11219 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10319 //CaptureCollection cc = g.Captures; 11220 //CaptureCollection cc = g.Captures;
10320 } 11221 }
10321 if (m.Groups.Count == 5) { 11222 if (m.Groups.Count == 5)
11223 {
10322 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11224 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10323 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11225 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10324 } 11226 }
@@ -10521,6 +11423,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10521 11423
10522 LSL_List ret = new LSL_List(); 11424 LSL_List ret = new LSL_List();
10523 UUID key = new UUID(); 11425 UUID key = new UUID();
11426
11427
10524 if (UUID.TryParse(id, out key)) 11428 if (UUID.TryParse(id, out key))
10525 { 11429 {
10526 ScenePresence av = World.GetScenePresence(key); 11430 ScenePresence av = World.GetScenePresence(key);
@@ -10538,13 +11442,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10538 ret.Add(new LSL_String("")); 11442 ret.Add(new LSL_String(""));
10539 break; 11443 break;
10540 case ScriptBaseClass.OBJECT_POS: 11444 case ScriptBaseClass.OBJECT_POS:
10541 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11445 Vector3 avpos;
11446
11447 if (av.ParentID != 0 && av.ParentPart != null)
11448 {
11449 avpos = av.OffsetPosition;
11450
11451 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11452 avpos -= sitOffset;
11453
11454 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11455 }
11456 else
11457 avpos = av.AbsolutePosition;
11458
11459 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10542 break; 11460 break;
10543 case ScriptBaseClass.OBJECT_ROT: 11461 case ScriptBaseClass.OBJECT_ROT:
10544 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 11462 Quaternion avrot = av.Rotation;
11463 if (av.ParentID != 0 && av.ParentPart != null)
11464 {
11465 avrot = av.ParentPart.GetWorldRotation() * avrot;
11466 }
11467 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10545 break; 11468 break;
10546 case ScriptBaseClass.OBJECT_VELOCITY: 11469 case ScriptBaseClass.OBJECT_VELOCITY:
10547 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11470 Vector3 avvel = av.Velocity;
11471 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10548 break; 11472 break;
10549 case ScriptBaseClass.OBJECT_OWNER: 11473 case ScriptBaseClass.OBJECT_OWNER:
10550 ret.Add(new LSL_String(id)); 11474 ret.Add(new LSL_String(id));
@@ -10629,11 +11553,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10629 case ScriptBaseClass.OBJECT_NAME: 11553 case ScriptBaseClass.OBJECT_NAME:
10630 ret.Add(new LSL_String(obj.Name)); 11554 ret.Add(new LSL_String(obj.Name));
10631 break; 11555 break;
10632 case ScriptBaseClass.OBJECT_DESC: 11556 case ScriptBaseClass.OBJECT_DESC:
10633 ret.Add(new LSL_String(obj.Description)); 11557 ret.Add(new LSL_String(obj.Description));
10634 break; 11558 break;
10635 case ScriptBaseClass.OBJECT_POS: 11559 case ScriptBaseClass.OBJECT_POS:
10636 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11560 Vector3 opos = obj.AbsolutePosition;
11561 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10637 break; 11562 break;
10638 case ScriptBaseClass.OBJECT_ROT: 11563 case ScriptBaseClass.OBJECT_ROT:
10639 { 11564 {
@@ -10683,9 +11608,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10683 // The value returned in SL for normal prims is prim count 11608 // The value returned in SL for normal prims is prim count
10684 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11609 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10685 break; 11610 break;
10686 // The following 3 costs I have intentionaly coded to return zero. They are part of 11611
10687 // "Land Impact" calculations. These calculations are probably not applicable 11612 // costs below may need to be diferent for root parts, need to check
10688 // to OpenSim and are not yet complete in SL
10689 case ScriptBaseClass.OBJECT_SERVER_COST: 11613 case ScriptBaseClass.OBJECT_SERVER_COST:
10690 // The linden calculation is here 11614 // The linden calculation is here
10691 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11615 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10693,16 +11617,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10693 ret.Add(new LSL_Float(0)); 11617 ret.Add(new LSL_Float(0));
10694 break; 11618 break;
10695 case ScriptBaseClass.OBJECT_STREAMING_COST: 11619 case ScriptBaseClass.OBJECT_STREAMING_COST:
10696 // The linden calculation is here 11620 // The value returned in SL for normal prims is prim count * 0.06
10697 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11621 ret.Add(new LSL_Float(obj.StreamingCost));
10698 // The value returned in SL for normal prims looks like the prim count * 0.06
10699 ret.Add(new LSL_Float(0));
10700 break; 11622 break;
10701 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11623 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10702 // The linden calculation is here 11624 // The value returned in SL for normal prims is prim count
10703 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11625 ret.Add(new LSL_Float(obj.PhysicsCost));
10704 // The value returned in SL for normal prims looks like the prim count
10705 ret.Add(new LSL_Float(0));
10706 break; 11626 break;
10707 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11627 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
10708 ret.Add(new LSL_Float(0)); 11628 ret.Add(new LSL_Float(0));
@@ -10961,15 +11881,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10961 return result; 11881 return result;
10962 } 11882 }
10963 11883
10964 public void print(string str) 11884 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10965 { 11885 {
10966 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11886 List<SceneObjectPart> parts = GetLinkParts(link);
10967 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11887 if (parts.Count < 1)
10968 if (ossl != null) 11888 return 0;
10969 { 11889
10970 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11890 return GetNumberOfSides(parts[0]);
10971 m_log.Info("LSL print():" + str);
10972 }
10973 } 11891 }
10974 11892
10975 private string Name2Username(string name) 11893 private string Name2Username(string name)
@@ -11014,7 +11932,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11014 11932
11015 return rq.ToString(); 11933 return rq.ToString();
11016 } 11934 }
11017 11935/*
11936 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11937 {
11938 m_SayShoutCount = 0;
11939 }
11940*/
11018 private struct Tri 11941 private struct Tri
11019 { 11942 {
11020 public Vector3 p1; 11943 public Vector3 p1;
@@ -11163,9 +12086,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11163 12086
11164 ContactResult result = new ContactResult (); 12087 ContactResult result = new ContactResult ();
11165 result.ConsumerID = group.LocalId; 12088 result.ConsumerID = group.LocalId;
11166 result.Depth = intersection.distance; 12089// result.Depth = intersection.distance;
11167 result.Normal = intersection.normal; 12090 result.Normal = intersection.normal;
11168 result.Pos = intersection.ipoint; 12091 result.Pos = intersection.ipoint;
12092 result.Depth = Vector3.Mag(rayStart - result.Pos);
11169 12093
11170 contacts.Add(result); 12094 contacts.Add(result);
11171 }); 12095 });
@@ -11298,6 +12222,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11298 12222
11299 return contacts[0]; 12223 return contacts[0];
11300 } 12224 }
12225/*
12226 // not done:
12227 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12228 {
12229 ContactResult[] contacts = null;
12230 World.ForEachSOG(delegate(SceneObjectGroup group)
12231 {
12232 if (m_host.ParentGroup == group)
12233 return;
12234
12235 if (group.IsAttachment)
12236 return;
12237
12238 if(group.RootPart.PhysActor != null)
12239 return;
12240
12241 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12242 });
12243 return contacts;
12244 }
12245*/
11301 12246
11302 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12247 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11303 { 12248 {
@@ -11421,18 +12366,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11421 } 12366 }
11422 } 12367 }
11423 12368
12369 // Double check this
11424 if (checkTerrain) 12370 if (checkTerrain)
11425 { 12371 {
11426 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12372 bool skipGroundCheck = false;
11427 if (groundContact != null) 12373
11428 results.Add((ContactResult)groundContact); 12374 foreach (ContactResult c in results)
12375 {
12376 if (c.ConsumerID == 0) // Physics gave us a ground collision
12377 skipGroundCheck = true;
12378 }
12379
12380 if (!skipGroundCheck)
12381 {
12382 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12383 if (groundContact != null)
12384 results.Add((ContactResult)groundContact);
12385 }
11429 } 12386 }
11430 12387
11431 results.Sort(delegate(ContactResult a, ContactResult b) 12388 results.Sort(delegate(ContactResult a, ContactResult b)
11432 { 12389 {
11433 return a.Depth.CompareTo(b.Depth); 12390 return a.Depth.CompareTo(b.Depth);
11434 }); 12391 });
11435 12392
11436 int values = 0; 12393 int values = 0;
11437 SceneObjectGroup thisgrp = m_host.ParentGroup; 12394 SceneObjectGroup thisgrp = m_host.ParentGroup;
11438 12395
@@ -11525,7 +12482,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11525 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12482 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11526 if (!isAccount) return 0; 12483 if (!isAccount) return 0;
11527 if (estate.HasAccess(id)) return 1; 12484 if (estate.HasAccess(id)) return 1;
11528 if (estate.IsBanned(id)) 12485 if (estate.IsBanned(id, World.GetUserFlags(id)))
11529 estate.RemoveBan(id); 12486 estate.RemoveBan(id);
11530 estate.AddEstateUser(id); 12487 estate.AddEstateUser(id);
11531 break; 12488 break;
@@ -11544,14 +12501,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11544 break; 12501 break;
11545 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12502 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11546 if (!isAccount) return 0; 12503 if (!isAccount) return 0;
11547 if (estate.IsBanned(id)) return 1; 12504 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11548 EstateBan ban = new EstateBan(); 12505 EstateBan ban = new EstateBan();
11549 ban.EstateID = estate.EstateID; 12506 ban.EstateID = estate.EstateID;
11550 ban.BannedUserID = id; 12507 ban.BannedUserID = id;
11551 estate.AddBan(ban); 12508 estate.AddBan(ban);
11552 break; 12509 break;
11553 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12510 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11554 if (!isAccount || !estate.IsBanned(id)) return 0; 12511 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11555 estate.RemoveBan(id); 12512 estate.RemoveBan(id);
11556 break; 12513 break;
11557 default: return 0; 12514 default: return 0;
@@ -11580,7 +12537,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11580 return 16384; 12537 return 16384;
11581 } 12538 }
11582 12539
11583 public LSL_Integer llGetUsedMemory() 12540 public virtual LSL_Integer llGetUsedMemory()
11584 { 12541 {
11585 m_host.AddScriptLPS(1); 12542 m_host.AddScriptLPS(1);
11586 // The value returned for LSO scripts in SL 12543 // The value returned for LSO scripts in SL
@@ -11608,19 +12565,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11608 public void llSetSoundQueueing(int queue) 12565 public void llSetSoundQueueing(int queue)
11609 { 12566 {
11610 m_host.AddScriptLPS(1); 12567 m_host.AddScriptLPS(1);
11611 NotImplemented("llSetSoundQueueing");
11612 } 12568 }
11613 12569
11614 public void llCollisionSprite(string impact_sprite) 12570 public void llCollisionSprite(string impact_sprite)
11615 { 12571 {
11616 m_host.AddScriptLPS(1); 12572 m_host.AddScriptLPS(1);
11617 NotImplemented("llCollisionSprite"); 12573 // Viewer 2.0 broke this and it's likely LL has no intention
12574 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11618 } 12575 }
11619 12576
11620 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12577 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11621 { 12578 {
11622 m_host.AddScriptLPS(1); 12579 m_host.AddScriptLPS(1);
11623 NotImplemented("llGodLikeRezObject"); 12580
12581 if (!World.Permissions.IsGod(m_host.OwnerID))
12582 NotImplemented("llGodLikeRezObject");
12583
12584 AssetBase rezAsset = World.AssetService.Get(inventory);
12585 if (rezAsset == null)
12586 {
12587 llSay(0, "Asset not found");
12588 return;
12589 }
12590
12591 SceneObjectGroup group = null;
12592
12593 try
12594 {
12595 string xmlData = Utils.BytesToString(rezAsset.Data);
12596 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12597 }
12598 catch
12599 {
12600 llSay(0, "Asset not found");
12601 return;
12602 }
12603
12604 if (group == null)
12605 {
12606 llSay(0, "Asset not found");
12607 return;
12608 }
12609
12610 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12611 group.RootPart.AttachOffset = group.AbsolutePosition;
12612
12613 group.ResetIDs();
12614
12615 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12616 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12617 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12618 group.ScheduleGroupForFullUpdate();
12619
12620 // objects rezzed with this method are die_at_edge by default.
12621 group.RootPart.SetDieAtEdge(true);
12622
12623 group.ResumeScripts();
12624
12625 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12626 "object_rez", new Object[] {
12627 new LSL_String(
12628 group.RootPart.UUID.ToString()) },
12629 new DetectParams[0]));
11624 } 12630 }
11625 12631
11626 public LSL_String llTransferLindenDollars(string destination, int amount) 12632 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -11672,7 +12678,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11672 } 12678 }
11673 12679
11674 bool result = money.ObjectGiveMoney( 12680 bool result = money.ObjectGiveMoney(
11675 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12681 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn);
11676 12682
11677 if (result) 12683 if (result)
11678 { 12684 {
@@ -11697,6 +12703,598 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11697 } 12703 }
11698 12704
11699 #endregion 12705 #endregion
12706
12707 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12708 {
12709 SceneObjectGroup group = m_host.ParentGroup;
12710
12711 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12712 return;
12713 if (group.IsAttachment)
12714 return;
12715
12716 if (frames.Data.Length > 0) // We are getting a new motion
12717 {
12718 if (group.RootPart.KeyframeMotion != null)
12719 group.RootPart.KeyframeMotion.Delete();
12720 group.RootPart.KeyframeMotion = null;
12721
12722 int idx = 0;
12723
12724 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12725 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12726
12727 while (idx < options.Data.Length)
12728 {
12729 int option = (int)options.GetLSLIntegerItem(idx++);
12730 int remain = options.Data.Length - idx;
12731
12732 switch (option)
12733 {
12734 case ScriptBaseClass.KFM_MODE:
12735 if (remain < 1)
12736 break;
12737 int modeval = (int)options.GetLSLIntegerItem(idx++);
12738 switch(modeval)
12739 {
12740 case ScriptBaseClass.KFM_FORWARD:
12741 mode = KeyframeMotion.PlayMode.Forward;
12742 break;
12743 case ScriptBaseClass.KFM_REVERSE:
12744 mode = KeyframeMotion.PlayMode.Reverse;
12745 break;
12746 case ScriptBaseClass.KFM_LOOP:
12747 mode = KeyframeMotion.PlayMode.Loop;
12748 break;
12749 case ScriptBaseClass.KFM_PING_PONG:
12750 mode = KeyframeMotion.PlayMode.PingPong;
12751 break;
12752 }
12753 break;
12754 case ScriptBaseClass.KFM_DATA:
12755 if (remain < 1)
12756 break;
12757 int dataval = (int)options.GetLSLIntegerItem(idx++);
12758 data = (KeyframeMotion.DataFormat)dataval;
12759 break;
12760 }
12761 }
12762
12763 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12764
12765 idx = 0;
12766
12767 int elemLength = 2;
12768 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12769 elemLength = 3;
12770
12771 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12772 while (idx < frames.Data.Length)
12773 {
12774 int remain = frames.Data.Length - idx;
12775
12776 if (remain < elemLength)
12777 break;
12778
12779 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12780 frame.Position = null;
12781 frame.Rotation = null;
12782
12783 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12784 {
12785 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12786 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12787 }
12788 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12789 {
12790 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12791 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12792 q.Normalize();
12793 frame.Rotation = q;
12794 }
12795
12796 float tempf = (float)frames.GetLSLFloatItem(idx++);
12797 frame.TimeMS = (int)(tempf * 1000.0f);
12798
12799 keyframes.Add(frame);
12800 }
12801
12802 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12803 group.RootPart.KeyframeMotion.Start();
12804 }
12805 else
12806 {
12807 if (group.RootPart.KeyframeMotion == null)
12808 return;
12809
12810 if (options.Data.Length == 0)
12811 {
12812 group.RootPart.KeyframeMotion.Stop();
12813 return;
12814 }
12815
12816 int code = (int)options.GetLSLIntegerItem(0);
12817
12818 int idx = 0;
12819
12820 while (idx < options.Data.Length)
12821 {
12822 int option = (int)options.GetLSLIntegerItem(idx++);
12823 int remain = options.Data.Length - idx;
12824
12825 switch (option)
12826 {
12827 case ScriptBaseClass.KFM_COMMAND:
12828 int cmd = (int)options.GetLSLIntegerItem(idx++);
12829 switch (cmd)
12830 {
12831 case ScriptBaseClass.KFM_CMD_PLAY:
12832 group.RootPart.KeyframeMotion.Start();
12833 break;
12834 case ScriptBaseClass.KFM_CMD_STOP:
12835 group.RootPart.KeyframeMotion.Stop();
12836 break;
12837 case ScriptBaseClass.KFM_CMD_PAUSE:
12838 group.RootPart.KeyframeMotion.Pause();
12839 break;
12840 }
12841 break;
12842 }
12843 }
12844 }
12845 }
12846
12847 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12848 {
12849 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12850
12851 int idx = 0;
12852 int idxStart = 0;
12853
12854 bool positionChanged = false;
12855 Vector3 finalPos = Vector3.Zero;
12856
12857 try
12858 {
12859 while (idx < rules.Length)
12860 {
12861 ++rulesParsed;
12862 int code = rules.GetLSLIntegerItem(idx++);
12863
12864 int remain = rules.Length - idx;
12865 idxStart = idx;
12866
12867 switch (code)
12868 {
12869 case (int)ScriptBaseClass.PRIM_POSITION:
12870 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12871 {
12872 if (remain < 1)
12873 return null;
12874
12875 LSL_Vector v;
12876 v = rules.GetVector3Item(idx++);
12877
12878 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12879 if (part == null)
12880 break;
12881
12882 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12883 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12884 if (part.LinkNum > 1)
12885 {
12886 localRot = GetPartLocalRot(part);
12887 localPos = GetPartLocalPos(part);
12888 }
12889
12890 v -= localPos;
12891 v /= localRot;
12892
12893 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12894
12895 v = v + 2 * sitOffset;
12896
12897 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12898 av.SendAvatarDataToAllAgents();
12899
12900 }
12901 break;
12902
12903 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12904 case (int)ScriptBaseClass.PRIM_ROTATION:
12905 {
12906 if (remain < 1)
12907 return null;
12908
12909 LSL_Rotation r;
12910 r = rules.GetQuaternionItem(idx++);
12911
12912 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12913 if (part == null)
12914 break;
12915
12916 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12917 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12918
12919 if (part.LinkNum > 1)
12920 localRot = GetPartLocalRot(part);
12921
12922 r = r * llGetRootRotation() / localRot;
12923 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12924 av.SendAvatarDataToAllAgents();
12925 }
12926 break;
12927
12928 // parse rest doing nothing but number of parameters error check
12929 case (int)ScriptBaseClass.PRIM_SIZE:
12930 case (int)ScriptBaseClass.PRIM_MATERIAL:
12931 case (int)ScriptBaseClass.PRIM_PHANTOM:
12932 case (int)ScriptBaseClass.PRIM_PHYSICS:
12933 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12934 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12935 case (int)ScriptBaseClass.PRIM_NAME:
12936 case (int)ScriptBaseClass.PRIM_DESC:
12937 if (remain < 1)
12938 return null;
12939 idx++;
12940 break;
12941
12942 case (int)ScriptBaseClass.PRIM_GLOW:
12943 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12944 case (int)ScriptBaseClass.PRIM_TEXGEN:
12945 if (remain < 2)
12946 return null;
12947 idx += 2;
12948 break;
12949
12950 case (int)ScriptBaseClass.PRIM_TYPE:
12951 if (remain < 3)
12952 return null;
12953 code = (int)rules.GetLSLIntegerItem(idx++);
12954 remain = rules.Length - idx;
12955 switch (code)
12956 {
12957 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12958 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12959 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12960 if (remain < 6)
12961 return null;
12962 idx += 6;
12963 break;
12964
12965 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12966 if (remain < 5)
12967 return null;
12968 idx += 5;
12969 break;
12970
12971 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12972 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12973 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12974 if (remain < 11)
12975 return null;
12976 idx += 11;
12977 break;
12978
12979 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12980 if (remain < 2)
12981 return null;
12982 idx += 2;
12983 break;
12984 }
12985 break;
12986
12987 case (int)ScriptBaseClass.PRIM_COLOR:
12988 case (int)ScriptBaseClass.PRIM_TEXT:
12989 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12990 case (int)ScriptBaseClass.PRIM_OMEGA:
12991 if (remain < 3)
12992 return null;
12993 idx += 3;
12994 break;
12995
12996 case (int)ScriptBaseClass.PRIM_TEXTURE:
12997 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12998 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12999 if (remain < 5)
13000 return null;
13001 idx += 5;
13002 break;
13003
13004 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13005 if (remain < 7)
13006 return null;
13007
13008 idx += 7;
13009 break;
13010
13011 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13012 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13013 return null;
13014
13015 return rules.GetSublist(idx, -1);
13016 }
13017 }
13018 }
13019 catch (InvalidCastException e)
13020 {
13021 ShoutError(string.Format(
13022 "{0} error running rule #{1}: arg #{2} ",
13023 originFunc, rulesParsed, idx - idxStart) + e.Message);
13024 }
13025 finally
13026 {
13027 if (positionChanged)
13028 {
13029 av.OffsetPosition = finalPos;
13030// av.SendAvatarDataToAllAgents();
13031 av.SendTerseUpdateToAllClients();
13032 positionChanged = false;
13033 }
13034 }
13035 return null;
13036 }
13037
13038 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13039 {
13040 // avatars case
13041 // replies as SL wiki
13042
13043// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13044 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13045
13046 int idx = 0;
13047 while (idx < rules.Length)
13048 {
13049 int code = (int)rules.GetLSLIntegerItem(idx++);
13050 int remain = rules.Length - idx;
13051
13052 switch (code)
13053 {
13054 case (int)ScriptBaseClass.PRIM_MATERIAL:
13055 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13056 break;
13057
13058 case (int)ScriptBaseClass.PRIM_PHYSICS:
13059 res.Add(new LSL_Integer(0));
13060 break;
13061
13062 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13063 res.Add(new LSL_Integer(0));
13064 break;
13065
13066 case (int)ScriptBaseClass.PRIM_PHANTOM:
13067 res.Add(new LSL_Integer(0));
13068 break;
13069
13070 case (int)ScriptBaseClass.PRIM_POSITION:
13071
13072 Vector3 pos = avatar.OffsetPosition;
13073
13074 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13075 pos -= sitOffset;
13076
13077 if( sitPart != null)
13078 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13079
13080 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13081 break;
13082
13083 case (int)ScriptBaseClass.PRIM_SIZE:
13084 // as in llGetAgentSize above
13085// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13086 Vector3 s = avatar.Appearance.AvatarSize;
13087 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13088
13089 break;
13090
13091 case (int)ScriptBaseClass.PRIM_ROTATION:
13092 Quaternion rot = avatar.Rotation;
13093 if (sitPart != null)
13094 {
13095 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13096 }
13097
13098 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13099 break;
13100
13101 case (int)ScriptBaseClass.PRIM_TYPE:
13102 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13103 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13104 res.Add(new LSL_Vector(0f,1.0f,0f));
13105 res.Add(new LSL_Float(0.0f));
13106 res.Add(new LSL_Vector(0, 0, 0));
13107 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13108 res.Add(new LSL_Vector(0, 0, 0));
13109 break;
13110
13111 case (int)ScriptBaseClass.PRIM_TEXTURE:
13112 if (remain < 1)
13113 return null;
13114
13115 int face = (int)rules.GetLSLIntegerItem(idx++);
13116 if (face == ScriptBaseClass.ALL_SIDES)
13117 {
13118 for (face = 0; face < 21; face++)
13119 {
13120 res.Add(new LSL_String(""));
13121 res.Add(new LSL_Vector(0,0,0));
13122 res.Add(new LSL_Vector(0,0,0));
13123 res.Add(new LSL_Float(0.0));
13124 }
13125 }
13126 else
13127 {
13128 if (face >= 0 && face < 21)
13129 {
13130 res.Add(new LSL_String(""));
13131 res.Add(new LSL_Vector(0,0,0));
13132 res.Add(new LSL_Vector(0,0,0));
13133 res.Add(new LSL_Float(0.0));
13134 }
13135 }
13136 break;
13137
13138 case (int)ScriptBaseClass.PRIM_COLOR:
13139 if (remain < 1)
13140 return null;
13141
13142 face = (int)rules.GetLSLIntegerItem(idx++);
13143
13144 if (face == ScriptBaseClass.ALL_SIDES)
13145 {
13146 for (face = 0; face < 21; face++)
13147 {
13148 res.Add(new LSL_Vector(0,0,0));
13149 res.Add(new LSL_Float(0));
13150 }
13151 }
13152 else
13153 {
13154 res.Add(new LSL_Vector(0,0,0));
13155 res.Add(new LSL_Float(0));
13156 }
13157 break;
13158
13159 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13160 if (remain < 1)
13161 return null;
13162 face = (int)rules.GetLSLIntegerItem(idx++);
13163
13164 if (face == ScriptBaseClass.ALL_SIDES)
13165 {
13166 for (face = 0; face < 21; face++)
13167 {
13168 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13169 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13170 }
13171 }
13172 else
13173 {
13174 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13175 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13176 }
13177 break;
13178
13179 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13180 if (remain < 1)
13181 return null;
13182 face = (int)rules.GetLSLIntegerItem(idx++);
13183
13184 if (face == ScriptBaseClass.ALL_SIDES)
13185 {
13186 for (face = 0; face < 21; face++)
13187 {
13188 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13189 }
13190 }
13191 else
13192 {
13193 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13194 }
13195 break;
13196
13197 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13198 res.Add(new LSL_Integer(0));
13199 res.Add(new LSL_Integer(0));// softness
13200 res.Add(new LSL_Float(0.0f)); // gravity
13201 res.Add(new LSL_Float(0.0f)); // friction
13202 res.Add(new LSL_Float(0.0f)); // wind
13203 res.Add(new LSL_Float(0.0f)); // tension
13204 res.Add(new LSL_Vector(0f,0f,0f));
13205 break;
13206
13207 case (int)ScriptBaseClass.PRIM_TEXGEN:
13208 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13209 if (remain < 1)
13210 return null;
13211 face = (int)rules.GetLSLIntegerItem(idx++);
13212
13213 if (face == ScriptBaseClass.ALL_SIDES)
13214 {
13215 for (face = 0; face < 21; face++)
13216 {
13217 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13218 }
13219 }
13220 else
13221 {
13222 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13223 }
13224 break;
13225
13226 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13227 res.Add(new LSL_Integer(0));
13228 res.Add(new LSL_Vector(0f,0f,0f));
13229 res.Add(new LSL_Float(0f)); // intensity
13230 res.Add(new LSL_Float(0f)); // radius
13231 res.Add(new LSL_Float(0f)); // falloff
13232 break;
13233
13234 case (int)ScriptBaseClass.PRIM_GLOW:
13235 if (remain < 1)
13236 return null;
13237 face = (int)rules.GetLSLIntegerItem(idx++);
13238
13239 if (face == ScriptBaseClass.ALL_SIDES)
13240 {
13241 for (face = 0; face < 21; face++)
13242 {
13243 res.Add(new LSL_Float(0f));
13244 }
13245 }
13246 else
13247 {
13248 res.Add(new LSL_Float(0f));
13249 }
13250 break;
13251
13252 case (int)ScriptBaseClass.PRIM_TEXT:
13253 res.Add(new LSL_String(""));
13254 res.Add(new LSL_Vector(0f,0f,0f));
13255 res.Add(new LSL_Float(1.0f));
13256 break;
13257
13258 case (int)ScriptBaseClass.PRIM_NAME:
13259 res.Add(new LSL_String(avatar.Name));
13260 break;
13261
13262 case (int)ScriptBaseClass.PRIM_DESC:
13263 res.Add(new LSL_String(""));
13264 break;
13265
13266 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13267 Quaternion lrot = avatar.Rotation;
13268
13269 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13270 {
13271 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13272 }
13273 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13274 break;
13275
13276 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13277 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13278 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13279 lpos -= lsitOffset;
13280
13281 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13282 {
13283 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13284 }
13285 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13286 break;
13287
13288 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13289 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13290 return null;
13291
13292 return rules.GetSublist(idx, -1);
13293 }
13294 }
13295
13296 return null;
13297 }
11700 } 13298 }
11701 13299
11702 public class NotecardCache 13300 public class NotecardCache
@@ -11810,4 +13408,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11810 } 13408 }
11811 } 13409 }
11812 } 13410 }
11813} \ No newline at end of file 13411}
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 bd83f02..a214935 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -138,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
139 internal float m_ScriptDelayFactor = 1.0f; 139 internal float m_ScriptDelayFactor = 1.0f;
140 internal float m_ScriptDistanceFactor = 1.0f; 140 internal float m_ScriptDistanceFactor = 1.0f;
141 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 143
143 protected IUrlModule m_UrlModule = null; 144 protected IUrlModule m_UrlModule = null;
@@ -148,6 +149,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
148 m_ScriptEngine = scriptEngine; 149 m_ScriptEngine = scriptEngine;
149 m_host = host; 150 m_host = host;
150 m_item = item; 151 m_item = item;
152 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
151 153
152 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 154 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
153 155
@@ -211,7 +213,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
211 213
212 internal void OSSLError(string msg) 214 internal void OSSLError(string msg)
213 { 215 {
214 throw new ScriptException("OSSL Runtime Error: " + msg); 216 if (m_debuggerSafe)
217 {
218 OSSLShoutError(msg);
219 }
220 else
221 {
222 throw new ScriptException("OSSL Runtime Error: " + msg);
223 }
215 } 224 }
216 225
217 /// <summary> 226 /// <summary>
@@ -930,18 +939,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
930 if (target != null) 939 if (target != null)
931 { 940 {
932 UUID animID=UUID.Zero; 941 UUID animID=UUID.Zero;
933 lock (m_host.TaskInventory) 942 m_host.TaskInventory.LockItemsForRead(true);
943 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
934 { 944 {
935 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 945 if (inv.Value.Name == animation)
936 { 946 {
937 if (inv.Value.Name == animation) 947 if (inv.Value.Type == (int)AssetType.Animation)
938 { 948 animID = inv.Value.AssetID;
939 if (inv.Value.Type == (int)AssetType.Animation) 949 continue;
940 animID = inv.Value.AssetID;
941 continue;
942 }
943 } 950 }
944 } 951 }
952 m_host.TaskInventory.LockItemsForRead(false);
945 if (animID == UUID.Zero) 953 if (animID == UUID.Zero)
946 target.Animator.AddAnimation(animation, m_host.UUID); 954 target.Animator.AddAnimation(animation, m_host.UUID);
947 else 955 else
@@ -982,6 +990,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
982 else 990 else
983 animID = UUID.Zero; 991 animID = UUID.Zero;
984 } 992 }
993 m_host.TaskInventory.LockItemsForRead(false);
985 994
986 if (animID == UUID.Zero) 995 if (animID == UUID.Zero)
987 target.Animator.RemoveAnimation(animation); 996 target.Animator.RemoveAnimation(animation);
@@ -1646,7 +1655,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1646 } 1655 }
1647 } 1656 }
1648 1657
1649 public Object osParseJSONNew(string JSON) 1658 private Object osParseJSONNew(string JSON)
1650 { 1659 {
1651 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew"); 1660 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew");
1652 1661
@@ -1848,15 +1857,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1848 { 1857 {
1849 UUID assetID = UUID.Zero; 1858 UUID assetID = UUID.Zero;
1850 1859
1851 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1860 bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID);
1861
1862 if (!notecardNameIsUUID)
1852 { 1863 {
1853 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1864 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1854 {
1855 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1856 {
1857 assetID = item.AssetID;
1858 }
1859 }
1860 } 1865 }
1861 1866
1862 if (assetID == UUID.Zero) 1867 if (assetID == UUID.Zero)
@@ -1867,7 +1872,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1867 AssetBase a = World.AssetService.Get(assetID.ToString()); 1872 AssetBase a = World.AssetService.Get(assetID.ToString());
1868 1873
1869 if (a == null) 1874 if (a == null)
1870 return UUID.Zero; 1875 {
1876 // Whoops, it's still possible here that the notecard name was properly
1877 // formatted like a UUID but isn't an asset UUID so lets look it up by name after all
1878 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1879 if (assetID == UUID.Zero)
1880 return UUID.Zero;
1881
1882 if (!NotecardCache.IsCached(assetID))
1883 {
1884 a = World.AssetService.Get(assetID.ToString());
1885
1886 if (a == null)
1887 {
1888 return UUID.Zero;
1889 }
1890 }
1891 }
1871 1892
1872 string data = Encoding.UTF8.GetString(a.Data); 1893 string data = Encoding.UTF8.GetString(a.Data);
1873 NotecardCache.Cache(assetID, data); 1894 NotecardCache.Cache(assetID, data);
@@ -1875,6 +1896,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1875 1896
1876 return assetID; 1897 return assetID;
1877 } 1898 }
1899 protected UUID SearchTaskInventoryForAssetId(string name)
1900 {
1901 UUID assetId = UUID.Zero;
1902 m_host.TaskInventory.LockItemsForRead(true);
1903 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1904 {
1905 if (item.Type == 7 && item.Name == name)
1906 {
1907 assetId = item.AssetID;
1908 }
1909 }
1910 m_host.TaskInventory.LockItemsForRead(false);
1911 return assetId;
1912 }
1878 1913
1879 /// <summary> 1914 /// <summary>
1880 /// Directly get an entire notecard at once. 1915 /// Directly get an entire notecard at once.
@@ -2352,7 +2387,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2352 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2387 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2353 m_host.AddScriptLPS(1); 2388 m_host.AddScriptLPS(1);
2354 2389
2355 return NpcCreate(firstname, lastname, position, notecard, false, false); 2390 return NpcCreate(firstname, lastname, position, notecard, true, false);
2356 } 2391 }
2357 2392
2358 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2393 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2363,24 +2398,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2363 return NpcCreate( 2398 return NpcCreate(
2364 firstname, lastname, position, notecard, 2399 firstname, lastname, position, notecard,
2365 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2400 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2366 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2401 false);
2402// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2367 } 2403 }
2368 2404
2369 private LSL_Key NpcCreate( 2405 private LSL_Key NpcCreate(
2370 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2406 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2371 { 2407 {
2408 if (!owned)
2409 OSSLError("Unowned NPCs are unsupported");
2410
2411 string groupTitle = String.Empty;
2412
2413 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2414 return new LSL_Key(UUID.Zero.ToString());
2415
2416 if (firstname != String.Empty || lastname != String.Empty)
2417 {
2418 if (firstname != "Shown outfit:")
2419 groupTitle = "- NPC -";
2420 }
2421
2372 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2422 INPCModule module = World.RequestModuleInterface<INPCModule>();
2373 if (module != null) 2423 if (module != null)
2374 { 2424 {
2375 AvatarAppearance appearance = null; 2425 AvatarAppearance appearance = null;
2376 2426
2377 UUID id; 2427// UUID id;
2378 if (UUID.TryParse(notecard, out id)) 2428// if (UUID.TryParse(notecard, out id))
2379 { 2429// {
2380 ScenePresence clonePresence = World.GetScenePresence(id); 2430// ScenePresence clonePresence = World.GetScenePresence(id);
2381 if (clonePresence != null) 2431// if (clonePresence != null)
2382 appearance = clonePresence.Appearance; 2432// appearance = clonePresence.Appearance;
2383 } 2433// }
2384 2434
2385 if (appearance == null) 2435 if (appearance == null)
2386 { 2436 {
@@ -2388,9 +2438,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2388 2438
2389 if (appearanceSerialized != null) 2439 if (appearanceSerialized != null)
2390 { 2440 {
2391 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2441 try
2392 appearance = new AvatarAppearance(); 2442 {
2393 appearance.Unpack(appearanceOsd); 2443 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2444 appearance = new AvatarAppearance();
2445 appearance.Unpack(appearanceOsd);
2446 }
2447 catch
2448 {
2449 return UUID.Zero.ToString();
2450 }
2394 } 2451 }
2395 else 2452 else
2396 { 2453 {
@@ -2409,6 +2466,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2409 World, 2466 World,
2410 appearance); 2467 appearance);
2411 2468
2469 ScenePresence sp;
2470 if (World.TryGetScenePresence(x, out sp))
2471 {
2472 sp.Grouptitle = groupTitle;
2473 sp.SendAvatarDataToAllAgents();
2474 }
2412 return new LSL_Key(x.ToString()); 2475 return new LSL_Key(x.ToString());
2413 } 2476 }
2414 2477
@@ -2709,16 +2772,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2709 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2772 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2710 m_host.AddScriptLPS(1); 2773 m_host.AddScriptLPS(1);
2711 2774
2712 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2775 ManualResetEvent ev = new ManualResetEvent(false);
2713 if (module != null)
2714 {
2715 UUID npcId = new UUID(npc.m_string);
2716 2776
2717 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2777 Util.FireAndForget(delegate(object x) {
2718 return; 2778 try
2779 {
2780 INPCModule module = World.RequestModuleInterface<INPCModule>();
2781 if (module != null)
2782 {
2783 UUID npcId = new UUID(npc.m_string);
2719 2784
2720 module.DeleteNPC(npcId, World); 2785 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2721 } 2786 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2787 {
2788 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2789 return;
2790 }
2791
2792 module.DeleteNPC(npcId, World);
2793 }
2794 }
2795 finally
2796 {
2797 ev.Set();
2798 }
2799 });
2800 ev.WaitOne();
2722 } 2801 }
2723 2802
2724 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2803 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..2e61fb8 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
@@ -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 {