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.cs3142
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs155
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.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/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
19 files changed, 3232 insertions, 1104 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 be6ac0a..f9ee590 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
@@ -2183,14 +2450,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2183 q = part.ParentGroup.GroupRotation; // just the group rotation 2450 q = part.ParentGroup.GroupRotation; // just the group rotation
2184 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2451 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2185 } 2452 }
2453
2186 q = part.GetWorldRotation(); 2454 q = part.GetWorldRotation();
2455 if (part.ParentGroup.AttachmentPoint != 0)
2456 {
2457 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2458 if (avatar != null)
2459 {
2460 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2461 q = avatar.CameraRotation * q; // Mouselook
2462 else
2463 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2464 }
2465 }
2466
2187 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2467 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2188 } 2468 }
2189 2469
2190 public LSL_Rotation llGetLocalRot() 2470 public LSL_Rotation llGetLocalRot()
2191 { 2471 {
2472 return GetPartLocalRot(m_host);
2473 }
2474
2475 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2476 {
2192 m_host.AddScriptLPS(1); 2477 m_host.AddScriptLPS(1);
2193 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2478 Quaternion rot = part.RotationOffset;
2479 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2194 } 2480 }
2195 2481
2196 public void llSetForce(LSL_Vector force, int local) 2482 public void llSetForce(LSL_Vector force, int local)
@@ -2270,16 +2556,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2270 m_host.ApplyImpulse(v, local != 0); 2556 m_host.ApplyImpulse(v, local != 0);
2271 } 2557 }
2272 2558
2559
2273 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2560 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2274 { 2561 {
2275 m_host.AddScriptLPS(1); 2562 m_host.AddScriptLPS(1);
2276 m_host.ApplyAngularImpulse(force, local != 0); 2563 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2277 } 2564 }
2278 2565
2279 public void llSetTorque(LSL_Vector torque, int local) 2566 public void llSetTorque(LSL_Vector torque, int local)
2280 { 2567 {
2281 m_host.AddScriptLPS(1); 2568 m_host.AddScriptLPS(1);
2282 m_host.SetAngularImpulse(torque, local != 0); 2569 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2283 } 2570 }
2284 2571
2285 public LSL_Vector llGetTorque() 2572 public LSL_Vector llGetTorque()
@@ -2296,20 +2583,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2296 llSetTorque(torque, local); 2583 llSetTorque(torque, local);
2297 } 2584 }
2298 2585
2586 public void llSetVelocity(LSL_Vector vel, int local)
2587 {
2588 m_host.AddScriptLPS(1);
2589 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2590 }
2591
2299 public LSL_Vector llGetVel() 2592 public LSL_Vector llGetVel()
2300 { 2593 {
2301 m_host.AddScriptLPS(1); 2594 m_host.AddScriptLPS(1);
2302 2595
2303 Vector3 vel; 2596 Vector3 vel = Vector3.Zero;
2304 2597
2305 if (m_host.ParentGroup.IsAttachment) 2598 if (m_host.ParentGroup.IsAttachment)
2306 { 2599 {
2307 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2600 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2308 vel = avatar.Velocity; 2601 if (avatar != null)
2602 vel = avatar.Velocity;
2309 } 2603 }
2310 else 2604 else
2311 { 2605 {
2312 vel = m_host.Velocity; 2606 vel = m_host.ParentGroup.RootPart.Velocity;
2313 } 2607 }
2314 2608
2315 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2609 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2321,10 +2615,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2321 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2615 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2322 } 2616 }
2323 2617
2618 public void llSetAngularVelocity(LSL_Vector avel, int local)
2619 {
2620 m_host.AddScriptLPS(1);
2621 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2622 }
2623
2324 public LSL_Vector llGetOmega() 2624 public LSL_Vector llGetOmega()
2325 { 2625 {
2326 m_host.AddScriptLPS(1); 2626 m_host.AddScriptLPS(1);
2327 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2627 Vector3 avel = m_host.AngularVelocity;
2628 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2328 } 2629 }
2329 2630
2330 public LSL_Float llGetTimeOfDay() 2631 public LSL_Float llGetTimeOfDay()
@@ -2683,7 +2984,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2683 return src.ToLower(); 2984 return src.ToLower();
2684 } 2985 }
2685 2986
2686 public void llGiveMoney(string destination, int amount) 2987 public LSL_Integer llGiveMoney(string destination, int amount)
2687 { 2988 {
2688 Util.FireAndForget(x => 2989 Util.FireAndForget(x =>
2689 { 2990 {
@@ -2715,8 +3016,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2715 } 3016 }
2716 3017
2717 money.ObjectGiveMoney( 3018 money.ObjectGiveMoney(
2718 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3019 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2719 }); 3020 });
3021
3022 return 0;
2720 } 3023 }
2721 3024
2722 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3025 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -2795,13 +3098,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2795 new_group.RootPart.UUID.ToString()) }, 3098 new_group.RootPart.UUID.ToString()) },
2796 new DetectParams[0])); 3099 new DetectParams[0]));
2797 3100
2798 float groupmass = new_group.GetMass(); 3101 // do recoil
3102 SceneObjectGroup hostgrp = m_host.ParentGroup;
3103 if (hostgrp == null)
3104 return;
3105
3106 if (hostgrp.IsAttachment) // don't recoil avatars
3107 return;
2799 3108
2800 PhysicsActor pa = new_group.RootPart.PhysActor; 3109 PhysicsActor pa = new_group.RootPart.PhysActor;
2801 3110
2802 //Recoil. 3111 //Recoil.
2803 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3112 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2804 { 3113 {
3114 float groupmass = new_group.GetMass();
2805 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3115 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2806 if (recoil != Vector3.Zero) 3116 if (recoil != Vector3.Zero)
2807 { 3117 {
@@ -2809,6 +3119,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2809 } 3119 }
2810 } 3120 }
2811 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3121 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3122 return;
3123
2812 }); 3124 });
2813 3125
2814 //ScriptSleep((int)((groupmass * velmag) / 10)); 3126 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2823,35 +3135,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2823 public void llLookAt(LSL_Vector target, double strength, double damping) 3135 public void llLookAt(LSL_Vector target, double strength, double damping)
2824 { 3136 {
2825 m_host.AddScriptLPS(1); 3137 m_host.AddScriptLPS(1);
2826 // Determine where we are looking from
2827 LSL_Vector from = llGetPos();
2828 3138
2829 // Work out the normalised vector from the source to the target 3139 // Get the normalized vector to the target
2830 LSL_Vector delta = llVecNorm(target - from); 3140 LSL_Vector d1 = llVecNorm(target - llGetPos());
2831 LSL_Vector angle = new LSL_Vector(0,0,0);
2832 3141
2833 // Calculate the yaw 3142 // Get the bearing (yaw)
2834 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3143 LSL_Vector a1 = new LSL_Vector(0,0,0);
2835 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3144 a1.z = llAtan2(d1.y, d1.x);
2836 3145
2837 // Calculate pitch 3146 // Get the elevation (pitch)
2838 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3147 LSL_Vector a2 = new LSL_Vector(0,0,0);
3148 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2839 3149
2840 // we need to convert from a vector describing 3150 LSL_Rotation r1 = llEuler2Rot(a1);
2841 // the angles of rotation in radians into rotation value 3151 LSL_Rotation r2 = llEuler2Rot(a2);
2842 LSL_Rotation rot = llEuler2Rot(angle); 3152 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2843
2844 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2845 // set the rotation of the object, copy that behavior
2846 PhysicsActor pa = m_host.PhysActor;
2847 3153
2848 if (strength == 0 || pa == null || !pa.IsPhysical) 3154 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2849 { 3155 {
2850 llSetRot(rot); 3156 // Do nothing if either value is 0 (this has been checked in SL)
3157 if (strength <= 0.0 || damping <= 0.0)
3158 return;
3159
3160 llSetRot(r3 * r2 * r1);
2851 } 3161 }
2852 else 3162 else
2853 { 3163 {
2854 m_host.StartLookAt(rot, (float)strength, (float)damping); 3164 if (strength == 0)
3165 {
3166 llSetRot(r3 * r2 * r1);
3167 return;
3168 }
3169
3170 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2855 } 3171 }
2856 } 3172 }
2857 3173
@@ -2898,17 +3214,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2898 } 3214 }
2899 else 3215 else
2900 { 3216 {
2901 if (m_host.IsRoot) 3217 // new SL always returns object mass
2902 { 3218// if (m_host.IsRoot)
3219// {
2903 return m_host.ParentGroup.GetMass(); 3220 return m_host.ParentGroup.GetMass();
2904 } 3221// }
2905 else 3222// else
2906 { 3223// {
2907 return m_host.GetMass(); 3224// return m_host.GetMass();
2908 } 3225// }
2909 } 3226 }
2910 } 3227 }
2911 3228
3229
3230 public LSL_Float llGetMassMKS()
3231 {
3232 return 100f * llGetMass();
3233 }
3234
2912 public void llCollisionFilter(string name, string id, int accept) 3235 public void llCollisionFilter(string name, string id, int accept)
2913 { 3236 {
2914 m_host.AddScriptLPS(1); 3237 m_host.AddScriptLPS(1);
@@ -2956,8 +3279,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2956 { 3279 {
2957 // Unregister controls from Presence 3280 // Unregister controls from Presence
2958 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3281 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2959 // Remove Take Control permission.
2960 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
2961 } 3282 }
2962 } 3283 }
2963 } 3284 }
@@ -2985,7 +3306,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2985 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3306 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
2986 3307
2987 if (attachmentsModule != null) 3308 if (attachmentsModule != null)
2988 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3309 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
2989 else 3310 else
2990 return false; 3311 return false;
2991 } 3312 }
@@ -3015,9 +3336,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3015 { 3336 {
3016 m_host.AddScriptLPS(1); 3337 m_host.AddScriptLPS(1);
3017 3338
3018// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3019// return;
3020
3021 if (m_item.PermsGranter != m_host.OwnerID) 3339 if (m_item.PermsGranter != m_host.OwnerID)
3022 return; 3340 return;
3023 3341
@@ -3060,6 +3378,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3060 3378
3061 public void llInstantMessage(string user, string message) 3379 public void llInstantMessage(string user, string message)
3062 { 3380 {
3381 UUID result;
3382 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3383 {
3384 ShoutError("An invalid key was passed to llInstantMessage");
3385 ScriptSleep(2000);
3386 return;
3387 }
3388
3389
3063 m_host.AddScriptLPS(1); 3390 m_host.AddScriptLPS(1);
3064 3391
3065 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3392 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3074,14 +3401,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3074 UUID friendTransactionID = UUID.Random(); 3401 UUID friendTransactionID = UUID.Random();
3075 3402
3076 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3403 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3077 3404
3078 GridInstantMessage msg = new GridInstantMessage(); 3405 GridInstantMessage msg = new GridInstantMessage();
3079 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3406 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3080 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3407 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3081 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3408 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3082// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3409// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3083// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3410// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3084 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3411// DateTime dt = DateTime.UtcNow;
3412//
3413// // Ticks from UtcNow, but make it look like local. Evil, huh?
3414// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3415//
3416// try
3417// {
3418// // Convert that to the PST timezone
3419// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3420// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3421// }
3422// catch
3423// {
3424// // No logging here, as it could be VERY spammy
3425// }
3426//
3427// // And make it look local again to fool the unix time util
3428// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3429
3430 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3431
3085 //if (client != null) 3432 //if (client != null)
3086 //{ 3433 //{
3087 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3434 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3095,12 +3442,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3095 msg.message = message.Substring(0, 1024); 3442 msg.message = message.Substring(0, 1024);
3096 else 3443 else
3097 msg.message = message; 3444 msg.message = message;
3098 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3445 msg.dialog = (byte)19; // MessageFromObject
3099 msg.fromGroup = false;// fromGroup; 3446 msg.fromGroup = false;// fromGroup;
3100 msg.offline = (byte)0; //offline; 3447 msg.offline = (byte)0; //offline;
3101 msg.ParentEstateID = 0; //ParentEstateID; 3448 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3102 msg.Position = new Vector3(m_host.AbsolutePosition); 3449 msg.Position = new Vector3(m_host.AbsolutePosition);
3103 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3450 msg.RegionID = World.RegionInfo.RegionID.Guid;
3104 msg.binaryBucket 3451 msg.binaryBucket
3105 = Util.StringToBytes256( 3452 = Util.StringToBytes256(
3106 "{0}/{1}/{2}/{3}", 3453 "{0}/{1}/{2}/{3}",
@@ -3128,7 +3475,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3128 } 3475 }
3129 3476
3130 emailModule.SendEmail(m_host.UUID, address, subject, message); 3477 emailModule.SendEmail(m_host.UUID, address, subject, message);
3131 llSleep(EMAIL_PAUSE_TIME); 3478 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3132 } 3479 }
3133 3480
3134 public void llGetNextEmail(string address, string subject) 3481 public void llGetNextEmail(string address, string subject)
@@ -3374,7 +3721,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3374 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3721 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3375 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3722 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3376 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3723 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3724 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3377 ScriptBaseClass.PERMISSION_ATTACH; 3725 ScriptBaseClass.PERMISSION_ATTACH;
3726
3378 } 3727 }
3379 else 3728 else
3380 { 3729 {
@@ -3391,15 +3740,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3391 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3740 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3392 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3741 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3393 } 3742 }
3743 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3744 {
3745 implicitPerms = perm;
3746 }
3394 } 3747 }
3395 3748
3396 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3749 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3397 { 3750 {
3398 lock (m_host.TaskInventory) 3751 m_host.TaskInventory.LockItemsForWrite(true);
3399 { 3752 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3400 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3753 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3401 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3754 m_host.TaskInventory.LockItemsForWrite(false);
3402 }
3403 3755
3404 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3756 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3405 "run_time_permissions", new Object[] { 3757 "run_time_permissions", new Object[] {
@@ -3442,11 +3794,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3442 3794
3443 if (!m_waitingForScriptAnswer) 3795 if (!m_waitingForScriptAnswer)
3444 { 3796 {
3445 lock (m_host.TaskInventory) 3797 m_host.TaskInventory.LockItemsForWrite(true);
3446 { 3798 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3447 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3799 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3448 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3800 m_host.TaskInventory.LockItemsForWrite(false);
3449 }
3450 3801
3451 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3802 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3452 m_waitingForScriptAnswer=true; 3803 m_waitingForScriptAnswer=true;
@@ -3475,14 +3826,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3475 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3826 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3476 llReleaseControls(); 3827 llReleaseControls();
3477 3828
3478 lock (m_host.TaskInventory) 3829 m_host.TaskInventory.LockItemsForWrite(true);
3479 { 3830 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3480 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3831 m_host.TaskInventory.LockItemsForWrite(false);
3481 } 3832
3482 3833 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3483 m_ScriptEngine.PostScriptEvent( 3834 "run_time_permissions", new Object[] {
3484 m_item.ItemID, 3835 new LSL_Integer(answer) },
3485 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3836 new DetectParams[0]));
3486 } 3837 }
3487 3838
3488 public LSL_String llGetPermissionsKey() 3839 public LSL_String llGetPermissionsKey()
@@ -3521,14 +3872,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3521 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3872 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3522 { 3873 {
3523 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3874 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3524 3875 if (parts.Count > 0)
3525 foreach (SceneObjectPart part in parts) 3876 {
3526 part.SetFaceColorAlpha(face, color, null); 3877 try
3878 {
3879 foreach (SceneObjectPart part in parts)
3880 part.SetFaceColorAlpha(face, color, null);
3881 }
3882 finally
3883 {
3884 }
3885 }
3527 } 3886 }
3528 3887
3529 public void llCreateLink(string target, int parent) 3888 public void llCreateLink(string target, int parent)
3530 { 3889 {
3531 m_host.AddScriptLPS(1); 3890 m_host.AddScriptLPS(1);
3891
3532 UUID targetID; 3892 UUID targetID;
3533 3893
3534 if (!UUID.TryParse(target, out targetID)) 3894 if (!UUID.TryParse(target, out targetID))
@@ -3634,10 +3994,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3634 // Restructuring Multiple Prims. 3994 // Restructuring Multiple Prims.
3635 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3995 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3636 parts.Remove(parentPrim.RootPart); 3996 parts.Remove(parentPrim.RootPart);
3637 foreach (SceneObjectPart part in parts) 3997 if (parts.Count > 0)
3638 { 3998 {
3639 parentPrim.DelinkFromGroup(part.LocalId, true); 3999 try
4000 {
4001 foreach (SceneObjectPart part in parts)
4002 {
4003 parentPrim.DelinkFromGroup(part.LocalId, true);
4004 }
4005 }
4006 finally
4007 {
4008 }
3640 } 4009 }
4010
3641 parentPrim.HasGroupChanged = true; 4011 parentPrim.HasGroupChanged = true;
3642 parentPrim.ScheduleGroupForFullUpdate(); 4012 parentPrim.ScheduleGroupForFullUpdate();
3643 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4013 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3646,12 +4016,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3646 { 4016 {
3647 SceneObjectPart newRoot = parts[0]; 4017 SceneObjectPart newRoot = parts[0];
3648 parts.Remove(newRoot); 4018 parts.Remove(newRoot);
3649 foreach (SceneObjectPart part in parts) 4019
4020 try
3650 { 4021 {
3651 // Required for linking 4022 foreach (SceneObjectPart part in parts)
3652 part.ClearUpdateSchedule(); 4023 {
3653 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4024 part.ClearUpdateSchedule();
4025 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4026 }
3654 } 4027 }
4028 finally
4029 {
4030 }
4031
4032
3655 newRoot.ParentGroup.HasGroupChanged = true; 4033 newRoot.ParentGroup.HasGroupChanged = true;
3656 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4034 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3657 } 4035 }
@@ -3671,6 +4049,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3671 public void llBreakAllLinks() 4049 public void llBreakAllLinks()
3672 { 4050 {
3673 m_host.AddScriptLPS(1); 4051 m_host.AddScriptLPS(1);
4052
4053 TaskInventoryItem item = m_item;
4054
4055 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4056 && !m_automaticLinkPermission)
4057 {
4058 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4059 return;
4060 }
4061
3674 SceneObjectGroup parentPrim = m_host.ParentGroup; 4062 SceneObjectGroup parentPrim = m_host.ParentGroup;
3675 if (parentPrim.AttachmentPoint != 0) 4063 if (parentPrim.AttachmentPoint != 0)
3676 return; // Fail silently if attached 4064 return; // Fail silently if attached
@@ -3690,47 +4078,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3690 public LSL_String llGetLinkKey(int linknum) 4078 public LSL_String llGetLinkKey(int linknum)
3691 { 4079 {
3692 m_host.AddScriptLPS(1); 4080 m_host.AddScriptLPS(1);
3693 4081 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3694 if (linknum < 0) 4082 if (part != null)
3695 {
3696 if (linknum == ScriptBaseClass.LINK_THIS)
3697 return m_host.UUID.ToString();
3698 else
3699 return ScriptBaseClass.NULL_KEY;
3700 }
3701
3702 int actualPrimCount = m_host.ParentGroup.PrimCount;
3703 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
3704 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
3705
3706 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
3707 // prim that has any avatars sat upon it (in which case the root prim is link 1).
3708 if (linknum == 0)
3709 {
3710 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
3711 return m_host.UUID.ToString();
3712
3713 return ScriptBaseClass.NULL_KEY;
3714 }
3715 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
3716 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
3717 else if (linknum == 1 && actualPrimCount == 1)
3718 {
3719 if (sittingAvatarIds.Count > 0)
3720 return m_host.ParentGroup.RootPart.UUID.ToString();
3721 else
3722 return ScriptBaseClass.NULL_KEY;
3723 }
3724 else if (linknum <= adjustedPrimCount)
3725 { 4083 {
3726 if (linknum <= actualPrimCount) 4084 return part.UUID.ToString();
3727 return m_host.ParentGroup.GetLinkNumPart(linknum).UUID.ToString();
3728 else
3729 return sittingAvatarIds[linknum - actualPrimCount - 1].ToString();
3730 } 4085 }
3731 else 4086 else
3732 { 4087 {
3733 return ScriptBaseClass.NULL_KEY; 4088 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4089 {
4090 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4091
4092 if (linknum < 0)
4093 return UUID.Zero.ToString();
4094
4095 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4096 if (avatars.Count > linknum)
4097 {
4098 return avatars[linknum].UUID.ToString();
4099 }
4100 }
4101 return UUID.Zero.ToString();
3734 } 4102 }
3735 } 4103 }
3736 4104
@@ -3833,17 +4201,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3833 m_host.AddScriptLPS(1); 4201 m_host.AddScriptLPS(1);
3834 int count = 0; 4202 int count = 0;
3835 4203
3836 lock (m_host.TaskInventory) 4204 m_host.TaskInventory.LockItemsForRead(true);
4205 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3837 { 4206 {
3838 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4207 if (inv.Value.Type == type || type == -1)
3839 { 4208 {
3840 if (inv.Value.Type == type || type == -1) 4209 count = count + 1;
3841 {
3842 count = count + 1;
3843 }
3844 } 4210 }
3845 } 4211 }
3846 4212
4213 m_host.TaskInventory.LockItemsForRead(false);
3847 return count; 4214 return count;
3848 } 4215 }
3849 4216
@@ -3852,16 +4219,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3852 m_host.AddScriptLPS(1); 4219 m_host.AddScriptLPS(1);
3853 ArrayList keys = new ArrayList(); 4220 ArrayList keys = new ArrayList();
3854 4221
3855 lock (m_host.TaskInventory) 4222 m_host.TaskInventory.LockItemsForRead(true);
4223 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3856 { 4224 {
3857 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4225 if (inv.Value.Type == type || type == -1)
3858 { 4226 {
3859 if (inv.Value.Type == type || type == -1) 4227 keys.Add(inv.Value.Name);
3860 {
3861 keys.Add(inv.Value.Name);
3862 }
3863 } 4228 }
3864 } 4229 }
4230 m_host.TaskInventory.LockItemsForRead(false);
3865 4231
3866 if (keys.Count == 0) 4232 if (keys.Count == 0)
3867 { 4233 {
@@ -3899,7 +4265,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3899 if (item == null) 4265 if (item == null)
3900 { 4266 {
3901 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4267 llSay(0, String.Format("Could not find object '{0}'", inventory));
3902 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4268 return;
4269// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3903 } 4270 }
3904 4271
3905 UUID objId = item.ItemID; 4272 UUID objId = item.ItemID;
@@ -3927,33 +4294,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3927 return; 4294 return;
3928 } 4295 }
3929 } 4296 }
4297
3930 // destination is an avatar 4298 // destination is an avatar
3931 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4299 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3932 4300
3933 if (agentItem == null) 4301 if (agentItem == null)
3934 return; 4302 return;
3935 4303
3936 if (m_TransferModule != null) 4304 byte[] bucket = new byte[1];
3937 { 4305 bucket[0] = (byte)item.Type;
3938 byte[] bucket = new byte[1]; 4306 //byte[] objBytes = agentItem.ID.GetBytes();
3939 bucket[0] = (byte)item.Type; 4307 //Array.Copy(objBytes, 0, bucket, 1, 16);
4308
4309 GridInstantMessage msg = new GridInstantMessage(World,
4310 m_host.OwnerID, m_host.Name, destId,
4311 (byte)InstantMessageDialog.TaskInventoryOffered,
4312 false, item.Name+". "+m_host.Name+" is located at "+
4313 World.RegionInfo.RegionName+" "+
4314 m_host.AbsolutePosition.ToString(),
4315 agentItem.ID, true, m_host.AbsolutePosition,
4316 bucket, true);
3940 4317
3941 GridInstantMessage msg = new GridInstantMessage(World, 4318 ScenePresence sp;
3942 m_host.OwnerID, m_host.Name, destId,
3943 (byte)InstantMessageDialog.TaskInventoryOffered,
3944 false, item.Name+". "+m_host.Name+" is located at "+
3945 World.RegionInfo.RegionName+" "+
3946 m_host.AbsolutePosition.ToString(),
3947 agentItem.ID, true, m_host.AbsolutePosition,
3948 bucket, true);
3949 4319
3950 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4320 if (World.TryGetScenePresence(destId, out sp))
4321 {
4322 sp.ControllingClient.SendInstantMessage(msg);
3951 } 4323 }
3952 4324 else
4325 {
4326 if (m_TransferModule != null)
4327 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4328 }
4329
4330 //This delay should only occur when giving inventory to avatars.
3953 ScriptSleep(3000); 4331 ScriptSleep(3000);
3954 } 4332 }
3955 } 4333 }
3956 4334
4335 [DebuggerNonUserCode]
3957 public void llRemoveInventory(string name) 4336 public void llRemoveInventory(string name)
3958 { 4337 {
3959 m_host.AddScriptLPS(1); 4338 m_host.AddScriptLPS(1);
@@ -4008,109 +4387,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4008 { 4387 {
4009 m_host.AddScriptLPS(1); 4388 m_host.AddScriptLPS(1);
4010 4389
4011 UUID uuid = (UUID)id; 4390 UUID uuid;
4012 PresenceInfo pinfo = null; 4391 if (UUID.TryParse(id, out uuid))
4013 UserAccount account;
4014
4015 UserInfoCacheEntry ce;
4016 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4017 { 4392 {
4018 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4393 PresenceInfo pinfo = null;
4019 if (account == null) 4394 UserAccount account;
4395
4396 UserInfoCacheEntry ce;
4397 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4020 { 4398 {
4021 m_userInfoCache[uuid] = null; // Cache negative 4399 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4022 return UUID.Zero.ToString(); 4400 if (account == null)
4023 } 4401 {
4402 m_userInfoCache[uuid] = null; // Cache negative
4403 return UUID.Zero.ToString();
4404 }
4024 4405
4025 4406
4026 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4407 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4027 if (pinfos != null && pinfos.Length > 0) 4408 if (pinfos != null && pinfos.Length > 0)
4028 {
4029 foreach (PresenceInfo p in pinfos)
4030 { 4409 {
4031 if (p.RegionID != UUID.Zero) 4410 foreach (PresenceInfo p in pinfos)
4032 { 4411 {
4033 pinfo = p; 4412 if (p.RegionID != UUID.Zero)
4413 {
4414 pinfo = p;
4415 }
4034 } 4416 }
4035 } 4417 }
4036 }
4037 4418
4038 ce = new UserInfoCacheEntry(); 4419 ce = new UserInfoCacheEntry();
4039 ce.time = Util.EnvironmentTickCount(); 4420 ce.time = Util.EnvironmentTickCount();
4040 ce.account = account; 4421 ce.account = account;
4041 ce.pinfo = pinfo; 4422 ce.pinfo = pinfo;
4042 } 4423 m_userInfoCache[uuid] = ce;
4043 else 4424 }
4044 { 4425 else
4045 if (ce == null) 4426 {
4046 return UUID.Zero.ToString(); 4427 if (ce == null)
4428 return UUID.Zero.ToString();
4047 4429
4048 account = ce.account; 4430 account = ce.account;
4049 pinfo = ce.pinfo; 4431 pinfo = ce.pinfo;
4050 } 4432 }
4051 4433
4052 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4434 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4053 {
4054 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4055 if (pinfos != null && pinfos.Length > 0)
4056 { 4435 {
4057 foreach (PresenceInfo p in pinfos) 4436 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4437 if (pinfos != null && pinfos.Length > 0)
4058 { 4438 {
4059 if (p.RegionID != UUID.Zero) 4439 foreach (PresenceInfo p in pinfos)
4060 { 4440 {
4061 pinfo = p; 4441 if (p.RegionID != UUID.Zero)
4442 {
4443 pinfo = p;
4444 }
4062 } 4445 }
4063 } 4446 }
4064 } 4447 else
4065 else 4448 pinfo = null;
4066 pinfo = null;
4067 4449
4068 ce.time = Util.EnvironmentTickCount(); 4450 ce.time = Util.EnvironmentTickCount();
4069 ce.pinfo = pinfo; 4451 ce.pinfo = pinfo;
4070 } 4452 }
4071 4453
4072 string reply = String.Empty; 4454 string reply = String.Empty;
4073 4455
4074 switch (data) 4456 switch (data)
4075 { 4457 {
4076 case 1: // DATA_ONLINE (0|1) 4458 case 1: // DATA_ONLINE (0|1)
4077 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4459 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4078 reply = "1"; 4460 reply = "1";
4079 else 4461 else
4080 reply = "0"; 4462 reply = "0";
4081 break; 4463 break;
4082 case 2: // DATA_NAME (First Last) 4464 case 2: // DATA_NAME (First Last)
4083 reply = account.FirstName + " " + account.LastName; 4465 reply = account.FirstName + " " + account.LastName;
4084 break; 4466 break;
4085 case 3: // DATA_BORN (YYYY-MM-DD) 4467 case 3: // DATA_BORN (YYYY-MM-DD)
4086 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4468 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4087 born = born.AddSeconds(account.Created); 4469 born = born.AddSeconds(account.Created);
4088 reply = born.ToString("yyyy-MM-dd"); 4470 reply = born.ToString("yyyy-MM-dd");
4089 break; 4471 break;
4090 case 4: // DATA_RATING (0,0,0,0,0,0) 4472 case 4: // DATA_RATING (0,0,0,0,0,0)
4091 reply = "0,0,0,0,0,0"; 4473 reply = "0,0,0,0,0,0";
4092 break; 4474 break;
4093 case 7: // DATA_USERLEVEL (integer) 4475 case 8: // DATA_PAYINFO (0|1|2|3)
4094 reply = account.UserLevel.ToString(); 4476 reply = "0";
4095 break; 4477 break;
4096 case 8: // DATA_PAYINFO (0|1|2|3) 4478 default:
4097 reply = "0"; 4479 return UUID.Zero.ToString(); // Raise no event
4098 break; 4480 }
4099 default:
4100 return UUID.Zero.ToString(); // Raise no event
4101 }
4102 4481
4103 UUID rq = UUID.Random(); 4482 UUID rq = UUID.Random();
4104 4483
4105 UUID tid = AsyncCommands. 4484 UUID tid = AsyncCommands.
4106 DataserverPlugin.RegisterRequest(m_host.LocalId, 4485 DataserverPlugin.RegisterRequest(m_host.LocalId,
4107 m_item.ItemID, rq.ToString()); 4486 m_item.ItemID, rq.ToString());
4108 4487
4109 AsyncCommands. 4488 AsyncCommands.
4110 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4489 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4111 4490
4112 ScriptSleep(100); 4491 ScriptSleep(100);
4113 return tid.ToString(); 4492 return tid.ToString();
4493 }
4494 else
4495 {
4496 ShoutError("Invalid UUID passed to llRequestAgentData.");
4497 }
4498 return "";
4114 } 4499 }
4115 4500
4116 public LSL_String llRequestInventoryData(string name) 4501 public LSL_String llRequestInventoryData(string name)
@@ -4167,13 +4552,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4167 if (UUID.TryParse(agent, out agentId)) 4552 if (UUID.TryParse(agent, out agentId))
4168 { 4553 {
4169 ScenePresence presence = World.GetScenePresence(agentId); 4554 ScenePresence presence = World.GetScenePresence(agentId);
4170 if (presence != null) 4555 if (presence != null && presence.PresenceType != PresenceType.Npc)
4171 { 4556 {
4557 // agent must not be a god
4558 if (presence.UserLevel >= 200) return;
4559
4172 // agent must be over the owners land 4560 // agent must be over the owners land
4173 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4561 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4174 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4562 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4175 { 4563 {
4176 World.TeleportClientHome(agentId, presence.ControllingClient); 4564 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4565 {
4566 // They can't be teleported home for some reason
4567 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4568 if (regionInfo != null)
4569 {
4570 World.RequestTeleportLocation(
4571 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4572 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4573 }
4574 }
4177 } 4575 }
4178 } 4576 }
4179 } 4577 }
@@ -4280,7 +4678,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4280 UUID av = new UUID(); 4678 UUID av = new UUID();
4281 if (!UUID.TryParse(agent,out av)) 4679 if (!UUID.TryParse(agent,out av))
4282 { 4680 {
4283 LSLError("First parameter to llDialog needs to be a key");
4284 return; 4681 return;
4285 } 4682 }
4286 4683
@@ -4312,10 +4709,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4312 public void llCollisionSound(string impact_sound, double impact_volume) 4709 public void llCollisionSound(string impact_sound, double impact_volume)
4313 { 4710 {
4314 m_host.AddScriptLPS(1); 4711 m_host.AddScriptLPS(1);
4315 4712
4713 if(impact_sound == "")
4714 {
4715 m_host.CollisionSoundVolume = (float)impact_volume;
4716 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4717 m_host.CollisionSoundType = 0;
4718 return;
4719 }
4316 // TODO: Parameter check logic required. 4720 // TODO: Parameter check logic required.
4317 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 4721 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4318 m_host.CollisionSoundVolume = (float)impact_volume; 4722 m_host.CollisionSoundVolume = (float)impact_volume;
4723 m_host.CollisionSoundType = 1;
4319 } 4724 }
4320 4725
4321 public LSL_String llGetAnimation(string id) 4726 public LSL_String llGetAnimation(string id)
@@ -4329,14 +4734,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4329 4734
4330 if (m_host.RegionHandle == presence.RegionHandle) 4735 if (m_host.RegionHandle == presence.RegionHandle)
4331 { 4736 {
4332 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4333
4334 if (presence != null) 4737 if (presence != null)
4335 { 4738 {
4336 AnimationSet currentAnims = presence.Animator.Animations; 4739 if (presence.SitGround)
4337 string currentAnimationState = String.Empty; 4740 return "Sitting on Ground";
4338 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4741 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4339 return currentAnimationState; 4742 return "Sitting";
4743
4744 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4745 string lslMovementAnimation;
4746
4747 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4748 return lslMovementAnimation;
4340 } 4749 }
4341 } 4750 }
4342 4751
@@ -4483,7 +4892,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4483 { 4892 {
4484 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4893 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4485 float distance_term = distance * distance * distance; // Script Energy 4894 float distance_term = distance * distance * distance; // Script Energy
4486 float pusher_mass = m_host.GetMass(); 4895 // use total object mass and not part
4896 float pusher_mass = m_host.ParentGroup.GetMass();
4487 4897
4488 float PUSH_ATTENUATION_DISTANCE = 17f; 4898 float PUSH_ATTENUATION_DISTANCE = 17f;
4489 float PUSH_ATTENUATION_SCALE = 5f; 4899 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4733,6 +5143,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4733 { 5143 {
4734 return item.AssetID.ToString(); 5144 return item.AssetID.ToString();
4735 } 5145 }
5146 m_host.TaskInventory.LockItemsForRead(false);
4736 5147
4737 return UUID.Zero.ToString(); 5148 return UUID.Zero.ToString();
4738 } 5149 }
@@ -4885,14 +5296,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4885 { 5296 {
4886 m_host.AddScriptLPS(1); 5297 m_host.AddScriptLPS(1);
4887 5298
4888 if (src == null) 5299 return src.Length;
4889 {
4890 return 0;
4891 }
4892 else
4893 {
4894 return src.Length;
4895 }
4896 } 5300 }
4897 5301
4898 public LSL_Integer llList2Integer(LSL_List src, int index) 5302 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4963,7 +5367,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4963 else if (src.Data[index] is LSL_Float) 5367 else if (src.Data[index] is LSL_Float)
4964 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5368 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4965 else if (src.Data[index] is LSL_String) 5369 else if (src.Data[index] is LSL_String)
4966 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5370 {
5371 string str = ((LSL_String) src.Data[index]).m_string;
5372 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5373 if (m != Match.Empty)
5374 {
5375 str = m.Value;
5376 double d = 0.0;
5377 if (!Double.TryParse(str, out d))
5378 return 0.0;
5379
5380 return d;
5381 }
5382 return 0.0;
5383 }
4967 return Convert.ToDouble(src.Data[index]); 5384 return Convert.ToDouble(src.Data[index]);
4968 } 5385 }
4969 catch (FormatException) 5386 catch (FormatException)
@@ -5005,7 +5422,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5005 // for completion and should LSL_Key ever be implemented 5422 // for completion and should LSL_Key ever be implemented
5006 // as it's own struct 5423 // as it's own struct
5007 else if (!(src.Data[index] is LSL_String || 5424 else if (!(src.Data[index] is LSL_String ||
5008 src.Data[index] is LSL_Key)) 5425 src.Data[index] is LSL_Key ||
5426 src.Data[index] is String))
5009 { 5427 {
5010 return ""; 5428 return "";
5011 } 5429 }
@@ -5263,7 +5681,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5263 } 5681 }
5264 } 5682 }
5265 } 5683 }
5266 else { 5684 else
5685 {
5267 object[] array = new object[src.Length]; 5686 object[] array = new object[src.Length];
5268 Array.Copy(src.Data, 0, array, 0, src.Length); 5687 Array.Copy(src.Data, 0, array, 0, src.Length);
5269 result = new LSL_List(array); 5688 result = new LSL_List(array);
@@ -5370,7 +5789,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5370 public LSL_Integer llGetRegionAgentCount() 5789 public LSL_Integer llGetRegionAgentCount()
5371 { 5790 {
5372 m_host.AddScriptLPS(1); 5791 m_host.AddScriptLPS(1);
5373 return new LSL_Integer(World.GetRootAgentCount()); 5792
5793 int count = 0;
5794 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5795 count++;
5796 });
5797
5798 return new LSL_Integer(count);
5374 } 5799 }
5375 5800
5376 public LSL_Vector llGetRegionCorner() 5801 public LSL_Vector llGetRegionCorner()
@@ -5611,6 +6036,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5611 flags |= ScriptBaseClass.AGENT_AWAY; 6036 flags |= ScriptBaseClass.AGENT_AWAY;
5612 } 6037 }
5613 6038
6039 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6040 UUID[] anims = agent.Animator.GetAnimationArray();
6041 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6042 {
6043 flags |= ScriptBaseClass.AGENT_BUSY;
6044 }
6045
5614 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6046 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5615 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6047 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5616 { 6048 {
@@ -5658,6 +6090,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5658 flags |= ScriptBaseClass.AGENT_SITTING; 6090 flags |= ScriptBaseClass.AGENT_SITTING;
5659 } 6091 }
5660 6092
6093 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6094 {
6095 flags |= ScriptBaseClass.AGENT_MALE;
6096 }
6097
5661 return flags; 6098 return flags;
5662 } 6099 }
5663 6100
@@ -5805,9 +6242,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5805 6242
5806 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6243 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5807 6244
5808 foreach (SceneObjectPart part in parts) 6245 try
6246 {
6247 foreach (SceneObjectPart part in parts)
6248 {
6249 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6250 }
6251 }
6252 finally
5809 { 6253 {
5810 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5811 } 6254 }
5812 } 6255 }
5813 6256
@@ -5861,13 +6304,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5861 6304
5862 if (m_host.OwnerID == land.LandData.OwnerID) 6305 if (m_host.OwnerID == land.LandData.OwnerID)
5863 { 6306 {
5864 World.TeleportClientHome(agentID, presence.ControllingClient); 6307 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6308 presence.TeleportWithMomentum(pos, null);
6309 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5865 } 6310 }
5866 } 6311 }
5867 } 6312 }
5868 ScriptSleep(5000); 6313 ScriptSleep(5000);
5869 } 6314 }
5870 6315
6316 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6317 {
6318 return ParseString2List(str, separators, in_spacers, false);
6319 }
6320
5871 public LSL_Integer llOverMyLand(string id) 6321 public LSL_Integer llOverMyLand(string id)
5872 { 6322 {
5873 m_host.AddScriptLPS(1); 6323 m_host.AddScriptLPS(1);
@@ -5921,25 +6371,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5921 } 6371 }
5922 else 6372 else
5923 { 6373 {
5924 agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); 6374// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6375 Vector3 s = avatar.Appearance.AvatarSize;
6376 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5925 } 6377 }
5926 return agentSize; 6378 return agentSize;
5927 } 6379 }
5928 6380
5929 public LSL_Integer llSameGroup(string agent) 6381 public LSL_Integer llSameGroup(string id)
5930 { 6382 {
5931 m_host.AddScriptLPS(1); 6383 m_host.AddScriptLPS(1);
5932 UUID agentId = new UUID(); 6384 UUID uuid = new UUID();
5933 if (!UUID.TryParse(agent, out agentId)) 6385 if (!UUID.TryParse(id, out uuid))
5934 return new LSL_Integer(0); 6386 return new LSL_Integer(0);
5935 ScenePresence presence = World.GetScenePresence(agentId); 6387
5936 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6388 // Check if it's a group key
5937 return new LSL_Integer(0); 6389 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5938 IClientAPI client = presence.ControllingClient;
5939 if (m_host.GroupID == client.ActiveGroupId)
5940 return new LSL_Integer(1); 6390 return new LSL_Integer(1);
5941 else 6391
6392 // We got passed a UUID.Zero
6393 if (uuid == UUID.Zero)
6394 return new LSL_Integer(0);
6395
6396 // Handle the case where id names an avatar
6397 ScenePresence presence = World.GetScenePresence(uuid);
6398 if (presence != null)
6399 {
6400 if (presence.IsChildAgent)
6401 return new LSL_Integer(0);
6402
6403 IClientAPI client = presence.ControllingClient;
6404 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6405 return new LSL_Integer(1);
6406
6407 return new LSL_Integer(0);
6408 }
6409
6410 // Handle object case
6411 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6412 if (part != null)
6413 {
6414 // This will handle both deed and non-deed and also the no
6415 // group case
6416 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6417 return new LSL_Integer(1);
6418
5942 return new LSL_Integer(0); 6419 return new LSL_Integer(0);
6420 }
6421
6422 return new LSL_Integer(0);
5943 } 6423 }
5944 6424
5945 public void llUnSit(string id) 6425 public void llUnSit(string id)
@@ -6064,7 +6544,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6064 return m_host.ParentGroup.AttachmentPoint; 6544 return m_host.ParentGroup.AttachmentPoint;
6065 } 6545 }
6066 6546
6067 public LSL_Integer llGetFreeMemory() 6547 public virtual LSL_Integer llGetFreeMemory()
6068 { 6548 {
6069 m_host.AddScriptLPS(1); 6549 m_host.AddScriptLPS(1);
6070 // Make scripts designed for LSO happy 6550 // Make scripts designed for LSO happy
@@ -6496,6 +6976,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6496 6976
6497 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6977 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6498 { 6978 {
6979 // LSL quaternions can normalize to 0, normal Quaternions can't.
6980 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6981 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6982
6499 part.SitTargetPosition = offset; 6983 part.SitTargetPosition = offset;
6500 part.SitTargetOrientation = rot; 6984 part.SitTargetOrientation = rot;
6501 part.ParentGroup.HasGroupChanged = true; 6985 part.ParentGroup.HasGroupChanged = true;
@@ -6681,30 +7165,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6681 UUID av = new UUID(); 7165 UUID av = new UUID();
6682 if (!UUID.TryParse(avatar,out av)) 7166 if (!UUID.TryParse(avatar,out av))
6683 { 7167 {
6684 LSLError("First parameter to llDialog needs to be a key"); 7168 //LSLError("First parameter to llDialog needs to be a key");
6685 return; 7169 return;
6686 } 7170 }
6687 if (buttons.Length < 1) 7171 if (buttons.Length < 1)
6688 { 7172 {
6689 LSLError("No less than 1 button can be shown"); 7173 buttons.Add("OK");
6690 return;
6691 } 7174 }
6692 if (buttons.Length > 12) 7175 if (buttons.Length > 12)
6693 { 7176 {
6694 LSLError("No more than 12 buttons can be shown"); 7177 ShoutError("button list too long, must be 12 or fewer entries");
6695 return;
6696 } 7178 }
6697 string[] buts = new string[buttons.Length]; 7179 int length = buttons.Length;
6698 for (int i = 0; i < buttons.Length; i++) 7180 if (length > 12)
7181 length = 12;
7182
7183 string[] buts = new string[length];
7184 for (int i = 0; i < length; i++)
6699 { 7185 {
6700 if (buttons.Data[i].ToString() == String.Empty) 7186 if (buttons.Data[i].ToString() == String.Empty)
6701 { 7187 {
6702 LSLError("button label cannot be blank"); 7188 ShoutError("button label cannot be blank");
6703 return; 7189 return;
6704 } 7190 }
6705 if (buttons.Data[i].ToString().Length > 24) 7191 if (buttons.Data[i].ToString().Length > 24)
6706 { 7192 {
6707 LSLError("button label cannot be longer than 24 characters"); 7193 ShoutError("button label cannot be longer than 24 characters");
6708 return; 7194 return;
6709 } 7195 }
6710 buts[i] = buttons.Data[i].ToString(); 7196 buts[i] = buttons.Data[i].ToString();
@@ -6771,9 +7257,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6771 return; 7257 return;
6772 } 7258 }
6773 7259
6774 // the rest of the permission checks are done in RezScript, so check the pin there as well 7260 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6775 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7261 if (dest != null)
7262 {
7263 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7264 {
7265 // the rest of the permission checks are done in RezScript, so check the pin there as well
7266 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6776 7267
7268 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7269 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7270 }
7271 }
6777 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7272 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6778 ScriptSleep(3000); 7273 ScriptSleep(3000);
6779 } 7274 }
@@ -6847,19 +7342,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6847 public LSL_String llMD5String(string src, int nonce) 7342 public LSL_String llMD5String(string src, int nonce)
6848 { 7343 {
6849 m_host.AddScriptLPS(1); 7344 m_host.AddScriptLPS(1);
6850 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7345 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6851 } 7346 }
6852 7347
6853 public LSL_String llSHA1String(string src) 7348 public LSL_String llSHA1String(string src)
6854 { 7349 {
6855 m_host.AddScriptLPS(1); 7350 m_host.AddScriptLPS(1);
6856 return Util.SHA1Hash(src).ToLower(); 7351 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6857 } 7352 }
6858 7353
6859 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7354 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6860 { 7355 {
6861 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7356 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6862 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7357 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7358 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7359 return shapeBlock;
6863 7360
6864 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7361 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6865 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7362 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6964,6 +7461,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6964 // Prim type box, cylinder and prism. 7461 // Prim type box, cylinder and prism.
6965 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) 7462 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)
6966 { 7463 {
7464 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7465 return;
7466
6967 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7467 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6968 ObjectShapePacket.ObjectDataBlock shapeBlock; 7468 ObjectShapePacket.ObjectDataBlock shapeBlock;
6969 7469
@@ -7017,6 +7517,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7017 // Prim type sphere. 7517 // Prim type sphere.
7018 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7518 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7019 { 7519 {
7520 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7521 return;
7522
7020 ObjectShapePacket.ObjectDataBlock shapeBlock; 7523 ObjectShapePacket.ObjectDataBlock shapeBlock;
7021 7524
7022 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7525 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7058,6 +7561,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7058 // Prim type torus, tube and ring. 7561 // Prim type torus, tube and ring.
7059 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) 7562 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)
7060 { 7563 {
7564 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7565 return;
7566
7061 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7567 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7062 ObjectShapePacket.ObjectDataBlock shapeBlock; 7568 ObjectShapePacket.ObjectDataBlock shapeBlock;
7063 7569
@@ -7193,6 +7699,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7193 // Prim type sculpt. 7699 // Prim type sculpt.
7194 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7700 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7195 { 7701 {
7702 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7703 return;
7704
7196 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7705 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7197 UUID sculptId; 7706 UUID sculptId;
7198 7707
@@ -7215,7 +7724,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7215 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7724 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7216 { 7725 {
7217 // default 7726 // default
7218 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7727 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7219 } 7728 }
7220 7729
7221 part.Shape.SetSculptProperties((byte)type, sculptId); 7730 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7232,48 +7741,130 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7232 ScriptSleep(200); 7741 ScriptSleep(200);
7233 } 7742 }
7234 7743
7235 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7744 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7236 { 7745 {
7237 m_host.AddScriptLPS(1); 7746 m_host.AddScriptLPS(1);
7238 7747
7239 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7748 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7749 }
7240 7750
7241 ScriptSleep(200); 7751 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7752 {
7753 List<object> parts = new List<object>();
7754 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7755 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7756 foreach (SceneObjectPart p in prims)
7757 parts.Add(p);
7758 foreach (ScenePresence p in avatars)
7759 parts.Add(p);
7760
7761 LSL_List remaining = null;
7762 uint rulesParsed = 0;
7763
7764 if (parts.Count > 0)
7765 {
7766 foreach (object part in parts)
7767 {
7768 if (part is SceneObjectPart)
7769 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7770 else
7771 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7772 }
7773
7774 while ((object)remaining != null && remaining.Length > 2)
7775 {
7776 linknumber = remaining.GetLSLIntegerItem(0);
7777 rules = remaining.GetSublist(1, -1);
7778 parts.Clear();
7779 prims = GetLinkParts(linknumber);
7780 avatars = GetLinkAvatars(linknumber);
7781 foreach (SceneObjectPart p in prims)
7782 parts.Add(p);
7783 foreach (ScenePresence p in avatars)
7784 parts.Add(p);
7785
7786 remaining = null;
7787 foreach (object part in parts)
7788 {
7789 if (part is SceneObjectPart)
7790 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7791 else
7792 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7793 }
7794 }
7795 }
7242 } 7796 }
7243 7797
7244 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7798 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7799 float material_density, float material_friction,
7800 float material_restitution, float material_gravity_modifier)
7245 { 7801 {
7246 m_host.AddScriptLPS(1); 7802 ExtraPhysicsData physdata = new ExtraPhysicsData();
7803 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7804 physdata.Density = part.Density;
7805 physdata.Friction = part.Friction;
7806 physdata.Bounce = part.Restitution;
7807 physdata.GravitationModifier = part.GravityModifier;
7247 7808
7248 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7809 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7810 physdata.Density = material_density;
7811 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7812 physdata.Friction = material_friction;
7813 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7814 physdata.Bounce = material_restitution;
7815 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7816 physdata.GravitationModifier = material_gravity_modifier;
7817
7818 part.UpdateExtraPhysics(physdata);
7249 } 7819 }
7250 7820
7251 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7821 public void llSetPhysicsMaterial(int material_bits,
7822 float material_gravity_modifier, float material_restitution,
7823 float material_friction, float material_density)
7252 { 7824 {
7253 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7825 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7826 }
7254 7827
7255 LSL_List remaining = null; 7828 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7256 uint rulesParsed = 0; 7829 {
7830 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7831 llSetLinkPrimitiveParamsFast(linknumber, rules);
7832 ScriptSleep(200);
7833 }
7257 7834
7258 foreach (SceneObjectPart part in parts) 7835 // vector up using libomv (c&p from sop )
7259 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7836 // vector up rotated by r
7837 private Vector3 Zrot(Quaternion r)
7838 {
7839 double x, y, z, m;
7260 7840
7261 while (remaining != null && remaining.Length > 2) 7841 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7842 if (Math.Abs(1.0 - m) > 0.000001)
7262 { 7843 {
7263 linknumber = remaining.GetLSLIntegerItem(0); 7844 m = 1.0 / Math.Sqrt(m);
7264 rules = remaining.GetSublist(1, -1); 7845 r.X *= (float)m;
7265 parts = GetLinkParts(linknumber); 7846 r.Y *= (float)m;
7266 7847 r.Z *= (float)m;
7267 foreach (SceneObjectPart part in parts) 7848 r.W *= (float)m;
7268 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7269 } 7849 }
7850
7851 x = 2 * (r.X * r.Z + r.Y * r.W);
7852 y = 2 * (-r.X * r.W + r.Y * r.Z);
7853 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7854
7855 return new Vector3((float)x, (float)y, (float)z);
7270 } 7856 }
7271 7857
7272 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7858 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7273 { 7859 {
7860 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7861 return null;
7862
7274 int idx = 0; 7863 int idx = 0;
7275 int idxStart = 0; 7864 int idxStart = 0;
7276 7865
7866 SceneObjectGroup parentgrp = part.ParentGroup;
7867
7277 bool positionChanged = false; 7868 bool positionChanged = false;
7278 LSL_Vector currentPosition = GetPartLocalPos(part); 7869 LSL_Vector currentPosition = GetPartLocalPos(part);
7279 7870
@@ -7298,8 +7889,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7298 return null; 7889 return null;
7299 7890
7300 v=rules.GetVector3Item(idx++); 7891 v=rules.GetVector3Item(idx++);
7892 if (part.IsRoot && !part.ParentGroup.IsAttachment)
7893 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
7894 else
7895 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7301 positionChanged = true; 7896 positionChanged = true;
7302 currentPosition = GetSetPosTarget(part, v, currentPosition);
7303 7897
7304 break; 7898 break;
7305 case (int)ScriptBaseClass.PRIM_SIZE: 7899 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7316,7 +7910,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7316 7910
7317 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7911 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7318 // try to let this work as in SL... 7912 // try to let this work as in SL...
7319 if (part.ParentID == 0) 7913 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7320 { 7914 {
7321 // special case: If we are root, rotate complete SOG to new rotation 7915 // special case: If we are root, rotate complete SOG to new rotation
7322 SetRot(part, q); 7916 SetRot(part, q);
@@ -7576,7 +8170,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7576 return null; 8170 return null;
7577 8171
7578 string ph = rules.Data[idx++].ToString(); 8172 string ph = rules.Data[idx++].ToString();
7579 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8173 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7580 8174
7581 break; 8175 break;
7582 8176
@@ -7610,12 +8204,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7610 8204
7611 break; 8205 break;
7612 8206
8207 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8208 if (remain < 5)
8209 return null;
8210
8211 int material_bits = rules.GetLSLIntegerItem(idx++);
8212 float material_density = (float)rules.GetLSLFloatItem(idx++);
8213 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8214 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8215 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8216
8217 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8218
8219 break;
8220
7613 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8221 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7614 if (remain < 1) 8222 if (remain < 1)
7615 return null; 8223 return null;
7616 string temp = rules.Data[idx++].ToString(); 8224 string temp = rules.Data[idx++].ToString();
7617 8225
7618 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8226 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7619 8227
7620 break; 8228 break;
7621 8229
@@ -7689,14 +8297,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7689 if (part.ParentGroup.RootPart == part) 8297 if (part.ParentGroup.RootPart == part)
7690 { 8298 {
7691 SceneObjectGroup parent = part.ParentGroup; 8299 SceneObjectGroup parent = part.ParentGroup;
7692 parent.UpdateGroupPosition(currentPosition); 8300 Util.FireAndForget(delegate(object x) {
8301 parent.UpdateGroupPosition(currentPosition);
8302 });
7693 } 8303 }
7694 else 8304 else
7695 { 8305 {
7696 part.OffsetPosition = currentPosition; 8306 part.OffsetPosition = currentPosition;
7697 SceneObjectGroup parent = part.ParentGroup; 8307// SceneObjectGroup parent = part.ParentGroup;
7698 parent.HasGroupChanged = true; 8308// parent.HasGroupChanged = true;
7699 parent.ScheduleGroupForTerseUpdate(); 8309// parent.ScheduleGroupForTerseUpdate();
8310 part.ScheduleTerseUpdate();
7700 } 8311 }
7701 } 8312 }
7702 } 8313 }
@@ -7734,10 +8345,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7734 8345
7735 public LSL_String llXorBase64Strings(string str1, string str2) 8346 public LSL_String llXorBase64Strings(string str1, string str2)
7736 { 8347 {
7737 m_host.AddScriptLPS(1); 8348 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7738 Deprecated("llXorBase64Strings"); 8349
7739 ScriptSleep(300); 8350 ScriptSleep(300);
7740 return String.Empty; 8351 m_host.AddScriptLPS(1);
8352
8353 if (str1 == String.Empty)
8354 return String.Empty;
8355 if (str2 == String.Empty)
8356 return str1;
8357
8358 int len = str2.Length;
8359 if ((len % 4) != 0) // LL is EVIL!!!!
8360 {
8361 while (str2.EndsWith("="))
8362 str2 = str2.Substring(0, str2.Length - 1);
8363
8364 len = str2.Length;
8365 int mod = len % 4;
8366
8367 if (mod == 1)
8368 str2 = str2.Substring(0, str2.Length - 1);
8369 else if (mod == 2)
8370 str2 += "==";
8371 else if (mod == 3)
8372 str2 += "=";
8373 }
8374
8375 byte[] data1;
8376 byte[] data2;
8377 try
8378 {
8379 data1 = Convert.FromBase64String(str1);
8380 data2 = Convert.FromBase64String(str2);
8381 }
8382 catch (Exception)
8383 {
8384 return new LSL_String(String.Empty);
8385 }
8386
8387 // For cases where the decoded length of s2 is greater
8388 // than the decoded length of s1, simply perform a normal
8389 // decode and XOR
8390 //
8391 if (data2.Length >= data1.Length)
8392 {
8393 for (int pos = 0 ; pos < data1.Length ; pos++ )
8394 data1[pos] ^= data2[pos];
8395
8396 return Convert.ToBase64String(data1);
8397 }
8398
8399 // Remove padding
8400 while (str1.EndsWith("="))
8401 str1 = str1.Substring(0, str1.Length - 1);
8402 while (str2.EndsWith("="))
8403 str2 = str2.Substring(0, str2.Length - 1);
8404
8405 byte[] d1 = new byte[str1.Length];
8406 byte[] d2 = new byte[str2.Length];
8407
8408 for (int i = 0 ; i < str1.Length ; i++)
8409 {
8410 int idx = b64.IndexOf(str1.Substring(i, 1));
8411 if (idx == -1)
8412 idx = 0;
8413 d1[i] = (byte)idx;
8414 }
8415
8416 for (int i = 0 ; i < str2.Length ; i++)
8417 {
8418 int idx = b64.IndexOf(str2.Substring(i, 1));
8419 if (idx == -1)
8420 idx = 0;
8421 d2[i] = (byte)idx;
8422 }
8423
8424 string output = String.Empty;
8425
8426 for (int pos = 0 ; pos < d1.Length ; pos++)
8427 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8428
8429 while (output.Length % 3 > 0)
8430 output += "=";
8431
8432 return output;
7741 } 8433 }
7742 8434
7743 public void llRemoteDataSetRegion() 8435 public void llRemoteDataSetRegion()
@@ -7861,8 +8553,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7861 public LSL_Integer llGetNumberOfPrims() 8553 public LSL_Integer llGetNumberOfPrims()
7862 { 8554 {
7863 m_host.AddScriptLPS(1); 8555 m_host.AddScriptLPS(1);
7864 8556 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7865 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8557
8558 return m_host.ParentGroup.PrimCount + avatarCount;
7866 } 8559 }
7867 8560
7868 /// <summary> 8561 /// <summary>
@@ -7877,55 +8570,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7877 m_host.AddScriptLPS(1); 8570 m_host.AddScriptLPS(1);
7878 UUID objID = UUID.Zero; 8571 UUID objID = UUID.Zero;
7879 LSL_List result = new LSL_List(); 8572 LSL_List result = new LSL_List();
8573
8574 // If the ID is not valid, return null result
7880 if (!UUID.TryParse(obj, out objID)) 8575 if (!UUID.TryParse(obj, out objID))
7881 { 8576 {
7882 result.Add(new LSL_Vector()); 8577 result.Add(new LSL_Vector());
7883 result.Add(new LSL_Vector()); 8578 result.Add(new LSL_Vector());
7884 return result; 8579 return result;
7885 } 8580 }
8581
8582 // Check if this is an attached prim. If so, replace
8583 // the UUID with the avatar UUID and report it's bounding box
8584 SceneObjectPart part = World.GetSceneObjectPart(objID);
8585 if (part != null && part.ParentGroup.IsAttachment)
8586 objID = part.ParentGroup.AttachedAvatar;
8587
8588 // Find out if this is an avatar ID. If so, return it's box
7886 ScenePresence presence = World.GetScenePresence(objID); 8589 ScenePresence presence = World.GetScenePresence(objID);
7887 if (presence != null) 8590 if (presence != null)
7888 { 8591 {
7889 if (presence.ParentID == 0) // not sat on an object 8592 // As per LSL Wiki, there is no difference between sitting
8593 // and standing avatar since server 1.36
8594 LSL_Vector lower;
8595 LSL_Vector upper;
8596
8597 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8598
8599 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8600 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8601/*
7890 { 8602 {
7891 LSL_Vector lower; 8603 // This is for ground sitting avatars
7892 LSL_Vector upper; 8604 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7893 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8605 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7894 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8606 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7895 {
7896 // This is for ground sitting avatars
7897 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7898 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7899 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7900 }
7901 else
7902 {
7903 // This is for standing/flying avatars
7904 float height = presence.Appearance.AvatarHeight / 2.0f;
7905 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7906 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7907 }
7908 result.Add(lower);
7909 result.Add(upper);
7910 return result;
7911 } 8607 }
7912 else 8608 else
7913 { 8609 {
7914 // sitting on an object so we need the bounding box of that 8610 // This is for standing/flying avatars
7915 // which should include the avatar so set the UUID to the 8611 float height = presence.Appearance.AvatarHeight / 2.0f;
7916 // UUID of the object the avatar is sat on and allow it to fall through 8612 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7917 // to processing an object 8613 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7918 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7919 objID = p.UUID;
7920 } 8614 }
8615
8616 // Adjust to the documented error offsets (see LSL Wiki)
8617 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8618 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8619*/
8620 {
8621 // This is for ground sitting avatars TODO!
8622 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8623 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
8624 }
8625 else
8626 {
8627 // This is for standing/flying avatars
8628 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8629 upper = new LSL_Vector(box.X, box.Y, box.Z);
8630 }
8631
8632 if (lower.x > upper.x)
8633 lower.x = upper.x;
8634 if (lower.y > upper.y)
8635 lower.y = upper.y;
8636 if (lower.z > upper.z)
8637 lower.z = upper.z;
8638
8639 result.Add(lower);
8640 result.Add(upper);
8641 return result;
7921 } 8642 }
7922 SceneObjectPart part = World.GetSceneObjectPart(objID); 8643
8644 part = World.GetSceneObjectPart(objID);
7923 // Currently only works for single prims without a sitting avatar 8645 // Currently only works for single prims without a sitting avatar
7924 if (part != null) 8646 if (part != null)
7925 { 8647 {
7926 Vector3 halfSize = part.Scale / 2.0f; 8648 float minX;
7927 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8649 float maxX;
7928 LSL_Vector upper = new LSL_Vector(halfSize); 8650 float minY;
8651 float maxY;
8652 float minZ;
8653 float maxZ;
8654
8655 // This BBox is in sim coordinates, with the offset being
8656 // a contained point.
8657 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8658 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8659
8660 minX -= offsets[0].X;
8661 maxX -= offsets[0].X;
8662 minY -= offsets[0].Y;
8663 maxY -= offsets[0].Y;
8664 minZ -= offsets[0].Z;
8665 maxZ -= offsets[0].Z;
8666
8667 LSL_Vector lower;
8668 LSL_Vector upper;
8669
8670 // Adjust to the documented error offsets (see LSL Wiki)
8671 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8672 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8673
8674 if (lower.x > upper.x)
8675 lower.x = upper.x;
8676 if (lower.y > upper.y)
8677 lower.y = upper.y;
8678 if (lower.z > upper.z)
8679 lower.z = upper.z;
8680
7929 result.Add(lower); 8681 result.Add(lower);
7930 result.Add(upper); 8682 result.Add(upper);
7931 return result; 8683 return result;
@@ -7939,7 +8691,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7939 8691
7940 public LSL_Vector llGetGeometricCenter() 8692 public LSL_Vector llGetGeometricCenter()
7941 { 8693 {
7942 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8694 Vector3 tmp = m_host.GetGeometricCenter();
8695 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7943 } 8696 }
7944 8697
7945 public LSL_List llGetPrimitiveParams(LSL_List rules) 8698 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7950,7 +8703,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7950 8703
7951 LSL_List remaining = GetPrimParams(m_host, rules, ref result); 8704 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
7952 8705
7953 while (remaining != null && remaining.Length > 2) 8706 while ((object)remaining != null && remaining.Length > 2)
7954 { 8707 {
7955 int linknumber = remaining.GetLSLIntegerItem(0); 8708 int linknumber = remaining.GetLSLIntegerItem(0);
7956 rules = remaining.GetSublist(1, -1); 8709 rules = remaining.GetSublist(1, -1);
@@ -7967,24 +8720,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7967 { 8720 {
7968 m_host.AddScriptLPS(1); 8721 m_host.AddScriptLPS(1);
7969 8722
7970 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8723 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8724 // keep other options as before
7971 8725
8726 List<SceneObjectPart> parts;
8727 List<ScenePresence> avatars;
8728
7972 LSL_List res = new LSL_List(); 8729 LSL_List res = new LSL_List();
7973 LSL_List remaining = null; 8730 LSL_List remaining = null;
7974 8731
7975 foreach (SceneObjectPart part in parts) 8732 while (rules.Length > 0)
7976 {
7977 remaining = GetPrimParams(part, rules, ref res);
7978 }
7979
7980 while (remaining != null && remaining.Length > 2)
7981 { 8733 {
7982 linknumber = remaining.GetLSLIntegerItem(0);
7983 rules = remaining.GetSublist(1, -1);
7984 parts = GetLinkParts(linknumber); 8734 parts = GetLinkParts(linknumber);
8735 avatars = GetLinkAvatars(linknumber);
7985 8736
8737 remaining = null;
7986 foreach (SceneObjectPart part in parts) 8738 foreach (SceneObjectPart part in parts)
8739 {
7987 remaining = GetPrimParams(part, rules, ref res); 8740 remaining = GetPrimParams(part, rules, ref res);
8741 }
8742 foreach (ScenePresence avatar in avatars)
8743 {
8744 remaining = GetPrimParams(avatar, rules, ref res);
8745 }
8746
8747 if ((object)remaining != null && remaining.Length > 0)
8748 {
8749 linknumber = remaining.GetLSLIntegerItem(0);
8750 rules = remaining.GetSublist(1, -1);
8751 }
8752 else
8753 break;
7988 } 8754 }
7989 8755
7990 return res; 8756 return res;
@@ -8029,13 +8795,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8029 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8795 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8030 part.AbsolutePosition.Y, 8796 part.AbsolutePosition.Y,
8031 part.AbsolutePosition.Z); 8797 part.AbsolutePosition.Z);
8032 // For some reason, the part.AbsolutePosition.* values do not change if the
8033 // linkset is rotated; they always reflect the child prim's world position
8034 // as though the linkset is unrotated. This is incompatible behavior with SL's
8035 // implementation, so will break scripts imported from there (not to mention it
8036 // makes it more difficult to determine a child prim's actual inworld position).
8037 if (part.ParentID != 0)
8038 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8039 res.Add(v); 8798 res.Add(v);
8040 break; 8799 break;
8041 8800
@@ -8207,30 +8966,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8207 if (remain < 1) 8966 if (remain < 1)
8208 return null; 8967 return null;
8209 8968
8210 face=(int)rules.GetLSLIntegerItem(idx++); 8969 face = (int)rules.GetLSLIntegerItem(idx++);
8211 8970
8212 tex = part.Shape.Textures; 8971 tex = part.Shape.Textures;
8972 int shiny;
8213 if (face == ScriptBaseClass.ALL_SIDES) 8973 if (face == ScriptBaseClass.ALL_SIDES)
8214 { 8974 {
8215 for (face = 0; face < GetNumberOfSides(part); face++) 8975 for (face = 0; face < GetNumberOfSides(part); face++)
8216 { 8976 {
8217 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8977 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8218 // Convert Shininess to PRIM_SHINY_* 8978 if (shinyness == Shininess.High)
8219 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8979 {
8220 // PRIM_BUMP_* 8980 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8221 res.Add(new LSL_Integer((int)texface.Bump)); 8981 }
8982 else if (shinyness == Shininess.Medium)
8983 {
8984 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8985 }
8986 else if (shinyness == Shininess.Low)
8987 {
8988 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8989 }
8990 else
8991 {
8992 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8993 }
8994 res.Add(new LSL_Integer(shiny));
8995 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8222 } 8996 }
8223 } 8997 }
8224 else 8998 else
8225 { 8999 {
8226 if (face >= 0 && face < GetNumberOfSides(part)) 9000 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9001 if (shinyness == Shininess.High)
8227 { 9002 {
8228 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9003 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8229 // Convert Shininess to PRIM_SHINY_* 9004 }
8230 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9005 else if (shinyness == Shininess.Medium)
8231 // PRIM_BUMP_* 9006 {
8232 res.Add(new LSL_Integer((int)texface.Bump)); 9007 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9008 }
9009 else if (shinyness == Shininess.Low)
9010 {
9011 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9012 }
9013 else
9014 {
9015 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8233 } 9016 }
9017 res.Add(new LSL_Integer(shiny));
9018 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8234 } 9019 }
8235 break; 9020 break;
8236 9021
@@ -8238,24 +9023,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8238 if (remain < 1) 9023 if (remain < 1)
8239 return null; 9024 return null;
8240 9025
8241 face=(int)rules.GetLSLIntegerItem(idx++); 9026 face = (int)rules.GetLSLIntegerItem(idx++);
8242 9027
8243 tex = part.Shape.Textures; 9028 tex = part.Shape.Textures;
9029 int fullbright;
8244 if (face == ScriptBaseClass.ALL_SIDES) 9030 if (face == ScriptBaseClass.ALL_SIDES)
8245 { 9031 {
8246 for (face = 0; face < GetNumberOfSides(part); face++) 9032 for (face = 0; face < GetNumberOfSides(part); face++)
8247 { 9033 {
8248 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9034 if (tex.GetFace((uint)face).Fullbright == true)
8249 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9035 {
9036 fullbright = ScriptBaseClass.TRUE;
9037 }
9038 else
9039 {
9040 fullbright = ScriptBaseClass.FALSE;
9041 }
9042 res.Add(new LSL_Integer(fullbright));
8250 } 9043 }
8251 } 9044 }
8252 else 9045 else
8253 { 9046 {
8254 if (face >= 0 && face < GetNumberOfSides(part)) 9047 if (tex.GetFace((uint)face).Fullbright == true)
8255 { 9048 {
8256 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9049 fullbright = ScriptBaseClass.TRUE;
8257 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9050 }
9051 else
9052 {
9053 fullbright = ScriptBaseClass.FALSE;
8258 } 9054 }
9055 res.Add(new LSL_Integer(fullbright));
8259 } 9056 }
8260 break; 9057 break;
8261 9058
@@ -8277,27 +9074,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8277 break; 9074 break;
8278 9075
8279 case (int)ScriptBaseClass.PRIM_TEXGEN: 9076 case (int)ScriptBaseClass.PRIM_TEXGEN:
9077 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8280 if (remain < 1) 9078 if (remain < 1)
8281 return null; 9079 return null;
8282 9080
8283 face=(int)rules.GetLSLIntegerItem(idx++); 9081 face = (int)rules.GetLSLIntegerItem(idx++);
8284 9082
8285 tex = part.Shape.Textures; 9083 tex = part.Shape.Textures;
8286 if (face == ScriptBaseClass.ALL_SIDES) 9084 if (face == ScriptBaseClass.ALL_SIDES)
8287 { 9085 {
8288 for (face = 0; face < GetNumberOfSides(part); face++) 9086 for (face = 0; face < GetNumberOfSides(part); face++)
8289 { 9087 {
8290 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9088 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8291 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9089 {
8292 res.Add(new LSL_Integer((uint)texgen >> 1)); 9090 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9091 }
9092 else
9093 {
9094 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9095 }
8293 } 9096 }
8294 } 9097 }
8295 else 9098 else
8296 { 9099 {
8297 if (face >= 0 && face < GetNumberOfSides(part)) 9100 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8298 { 9101 {
8299 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9102 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8300 res.Add(new LSL_Integer((uint)texgen >> 1)); 9103 }
9104 else
9105 {
9106 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8301 } 9107 }
8302 } 9108 }
8303 break; 9109 break;
@@ -8321,24 +9127,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8321 if (remain < 1) 9127 if (remain < 1)
8322 return null; 9128 return null;
8323 9129
8324 face=(int)rules.GetLSLIntegerItem(idx++); 9130 face = (int)rules.GetLSLIntegerItem(idx++);
8325 9131
8326 tex = part.Shape.Textures; 9132 tex = part.Shape.Textures;
9133 float primglow;
8327 if (face == ScriptBaseClass.ALL_SIDES) 9134 if (face == ScriptBaseClass.ALL_SIDES)
8328 { 9135 {
8329 for (face = 0; face < GetNumberOfSides(part); face++) 9136 for (face = 0; face < GetNumberOfSides(part); face++)
8330 { 9137 {
8331 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9138 primglow = tex.GetFace((uint)face).Glow;
8332 res.Add(new LSL_Float(texface.Glow)); 9139 res.Add(new LSL_Float(primglow));
8333 } 9140 }
8334 } 9141 }
8335 else 9142 else
8336 { 9143 {
8337 if (face >= 0 && face < GetNumberOfSides(part)) 9144 primglow = tex.GetFace((uint)face).Glow;
8338 { 9145 res.Add(new LSL_Float(primglow));
8339 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8340 res.Add(new LSL_Float(texface.Glow));
8341 }
8342 } 9146 }
8343 break; 9147 break;
8344 9148
@@ -8350,15 +9154,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8350 textColor.B)); 9154 textColor.B));
8351 res.Add(new LSL_Float(textColor.A)); 9155 res.Add(new LSL_Float(textColor.A));
8352 break; 9156 break;
9157
8353 case (int)ScriptBaseClass.PRIM_NAME: 9158 case (int)ScriptBaseClass.PRIM_NAME:
8354 res.Add(new LSL_String(part.Name)); 9159 res.Add(new LSL_String(part.Name));
8355 break; 9160 break;
9161
8356 case (int)ScriptBaseClass.PRIM_DESC: 9162 case (int)ScriptBaseClass.PRIM_DESC:
8357 res.Add(new LSL_String(part.Description)); 9163 res.Add(new LSL_String(part.Description));
8358 break; 9164 break;
9165
8359 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9166 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8360 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9167 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8361 break; 9168 break;
9169
8362 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9170 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8363 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9171 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8364 break; 9172 break;
@@ -8969,8 +9777,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8969 // The function returns an ordered list 9777 // The function returns an ordered list
8970 // representing the tokens found in the supplied 9778 // representing the tokens found in the supplied
8971 // sources string. If two successive tokenizers 9779 // sources string. If two successive tokenizers
8972 // are encountered, then a NULL entry is added 9780 // are encountered, then a null-string entry is
8973 // to the list. 9781 // added to the list.
8974 // 9782 //
8975 // It is a precondition that the source and 9783 // It is a precondition that the source and
8976 // toekizer lisst are non-null. If they are null, 9784 // toekizer lisst are non-null. If they are null,
@@ -8978,7 +9786,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8978 // while their lengths are being determined. 9786 // while their lengths are being determined.
8979 // 9787 //
8980 // A small amount of working memoryis required 9788 // A small amount of working memoryis required
8981 // of approximately 8*#tokenizers. 9789 // of approximately 8*#tokenizers + 8*srcstrlen.
8982 // 9790 //
8983 // There are many ways in which this function 9791 // There are many ways in which this function
8984 // can be implemented, this implementation is 9792 // can be implemented, this implementation is
@@ -8994,155 +9802,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8994 // and eliminates redundant tokenizers as soon 9802 // and eliminates redundant tokenizers as soon
8995 // as is possible. 9803 // as is possible.
8996 // 9804 //
8997 // The implementation tries to avoid any copying 9805 // The implementation tries to minimize temporary
8998 // of arrays or other objects. 9806 // garbage generation.
8999 // </remarks> 9807 // </remarks>
9000 9808
9001 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9809 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9002 { 9810 {
9003 int beginning = 0; 9811 return ParseString2List(src, separators, spacers, true);
9004 int srclen = src.Length; 9812 }
9005 int seplen = separators.Length;
9006 object[] separray = separators.Data;
9007 int spclen = spacers.Length;
9008 object[] spcarray = spacers.Data;
9009 int mlen = seplen+spclen;
9010
9011 int[] offset = new int[mlen+1];
9012 bool[] active = new bool[mlen];
9013
9014 int best;
9015 int j;
9016
9017 // Initial capacity reduces resize cost
9018 9813
9019 LSL_List tokens = new LSL_List(); 9814 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9815 {
9816 int srclen = src.Length;
9817 int seplen = separators.Length;
9818 object[] separray = separators.Data;
9819 int spclen = spacers.Length;
9820 object[] spcarray = spacers.Data;
9821 int dellen = 0;
9822 string[] delarray = new string[seplen+spclen];
9020 9823
9021 // All entries are initially valid 9824 int outlen = 0;
9825 string[] outarray = new string[srclen*2+1];
9022 9826
9023 for (int i = 0; i < mlen; i++) 9827 int i, j;
9024 active[i] = true; 9828 string d;
9025 9829
9026 offset[mlen] = srclen; 9830 m_host.AddScriptLPS(1);
9027 9831
9028 while (beginning < srclen) 9832 /*
9833 * Convert separator and spacer lists to C# strings.
9834 * Also filter out null strings so we don't hang.
9835 */
9836 for (i = 0; i < seplen; i ++)
9029 { 9837 {
9838 d = separray[i].ToString();
9839 if (d.Length > 0)
9840 {
9841 delarray[dellen++] = d;
9842 }
9843 }
9844 seplen = dellen;
9030 9845
9031 best = mlen; // as bad as it gets 9846 for (i = 0; i < spclen; i ++)
9847 {
9848 d = spcarray[i].ToString();
9849 if (d.Length > 0)
9850 {
9851 delarray[dellen++] = d;
9852 }
9853 }
9032 9854
9033 // Scan for separators 9855 /*
9856 * Scan through source string from beginning to end.
9857 */
9858 for (i = 0;;)
9859 {
9034 9860
9035 for (j = 0; j < seplen; j++) 9861 /*
9862 * Find earliest delimeter in src starting at i (if any).
9863 */
9864 int earliestDel = -1;
9865 int earliestSrc = srclen;
9866 string earliestStr = null;
9867 for (j = 0; j < dellen; j ++)
9036 { 9868 {
9037 if (separray[j].ToString() == String.Empty) 9869 d = delarray[j];
9038 active[j] = false; 9870 if (d != null)
9039
9040 if (active[j])
9041 { 9871 {
9042 // scan all of the markers 9872 int index = src.IndexOf(d, i);
9043 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9873 if (index < 0)
9044 { 9874 {
9045 // not present at all 9875 delarray[j] = null; // delim nowhere in src, don't check it anymore
9046 active[j] = false;
9047 } 9876 }
9048 else 9877 else if (index < earliestSrc)
9049 { 9878 {
9050 // present and correct 9879 earliestSrc = index; // where delimeter starts in source string
9051 if (offset[j] < offset[best]) 9880 earliestDel = j; // where delimeter is in delarray[]
9052 { 9881 earliestStr = d; // the delimeter string from delarray[]
9053 // closest so far 9882 if (index == i) break; // can't do any better than found at beg of string
9054 best = j;
9055 if (offset[best] == beginning)
9056 break;
9057 }
9058 } 9883 }
9059 } 9884 }
9060 } 9885 }
9061 9886
9062 // Scan for spacers 9887 /*
9063 9888 * Output source string starting at i through start of earliest delimeter.
9064 if (offset[best] != beginning) 9889 */
9890 if (keepNulls || (earliestSrc > i))
9065 { 9891 {
9066 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9892 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9067 {
9068 if (spcarray[j-seplen].ToString() == String.Empty)
9069 active[j] = false;
9070
9071 if (active[j])
9072 {
9073 // scan all of the markers
9074 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9075 {
9076 // not present at all
9077 active[j] = false;
9078 }
9079 else
9080 {
9081 // present and correct
9082 if (offset[j] < offset[best])
9083 {
9084 // closest so far
9085 best = j;
9086 }
9087 }
9088 }
9089 }
9090 } 9893 }
9091 9894
9092 // This is the normal exit from the scanning loop 9895 /*
9896 * If no delimeter found at or after i, we're done scanning.
9897 */
9898 if (earliestDel < 0) break;
9093 9899
9094 if (best == mlen) 9900 /*
9901 * If delimeter was a spacer, output the spacer.
9902 */
9903 if (earliestDel >= seplen)
9095 { 9904 {
9096 // no markers were found on this pass 9905 outarray[outlen++] = earliestStr;
9097 // so we're pretty much done
9098 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9099 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9100 break;
9101 } 9906 }
9102 9907
9103 // Otherwise we just add the newly delimited token 9908 /*
9104 // and recalculate where the search should continue. 9909 * Look at rest of src string following delimeter.
9105 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9910 */
9106 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9911 i = earliestSrc + earliestStr.Length;
9107
9108 if (best < seplen)
9109 {
9110 beginning = offset[best] + (separray[best].ToString()).Length;
9111 }
9112 else
9113 {
9114 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9115 string str = spcarray[best - seplen].ToString();
9116 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9117 tokens.Add(new LSL_String(str));
9118 }
9119 } 9912 }
9120 9913
9121 // This an awkward an not very intuitive boundary case. If the 9914 /*
9122 // last substring is a tokenizer, then there is an implied trailing 9915 * Make up an exact-sized output array suitable for an LSL_List object.
9123 // null list entry. Hopefully the single comparison will not be too 9916 */
9124 // arduous. Alternatively the 'break' could be replced with a return 9917 object[] outlist = new object[outlen];
9125 // but that's shabby programming. 9918 for (i = 0; i < outlen; i ++)
9126
9127 if ((beginning == srclen) && (keepNulls))
9128 { 9919 {
9129 if (srclen != 0) 9920 outlist[i] = new LSL_String(outarray[i]);
9130 tokens.Add(new LSL_String(""));
9131 } 9921 }
9132 9922 return new LSL_List(outlist);
9133 return tokens;
9134 }
9135
9136 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9137 {
9138 m_host.AddScriptLPS(1);
9139 return this.ParseString(src, separators, spacers, false);
9140 }
9141
9142 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9143 {
9144 m_host.AddScriptLPS(1);
9145 return this.ParseString(src, separators, spacers, true);
9146 } 9923 }
9147 9924
9148 public LSL_Integer llGetObjectPermMask(int mask) 9925 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9237,6 +10014,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9237 case 4: 10014 case 4:
9238 return (int)item.NextPermissions; 10015 return (int)item.NextPermissions;
9239 } 10016 }
10017 m_host.TaskInventory.LockItemsForRead(false);
9240 10018
9241 return -1; 10019 return -1;
9242 } 10020 }
@@ -9439,31 +10217,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9439 UUID key = new UUID(); 10217 UUID key = new UUID();
9440 if (UUID.TryParse(id, out key)) 10218 if (UUID.TryParse(id, out key))
9441 { 10219 {
9442 try 10220 // return total object mass
9443 { 10221 SceneObjectPart part = World.GetSceneObjectPart(key);
9444 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10222 if (part != null)
9445 if (obj != null) 10223 return part.ParentGroup.GetMass();
9446 return (double)obj.GetMass(); 10224
9447 // the object is null so the key is for an avatar 10225 // the object is null so the key is for an avatar
9448 ScenePresence avatar = World.GetScenePresence(key); 10226 ScenePresence avatar = World.GetScenePresence(key);
9449 if (avatar != null) 10227 if (avatar != null)
9450 if (avatar.IsChildAgent)
9451 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9452 // child agents have a mass of 1.0
9453 return 1;
9454 else
9455 return (double)avatar.GetMass();
9456 }
9457 catch (KeyNotFoundException)
9458 { 10228 {
9459 return 0; // The Object/Agent not in the region so just return zero 10229 if (avatar.IsChildAgent)
10230 {
10231 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10232 // child agents have a mass of 1.0
10233 return 1;
10234 }
10235 else
10236 {
10237 return (double)avatar.GetMass();
10238 }
9460 } 10239 }
9461 } 10240 }
9462 return 0; 10241 return 0;
9463 } 10242 }
9464 10243
9465 /// <summary> 10244 /// <summary>
9466 /// illListReplaceList removes the sub-list defined by the inclusive indices 10245 /// llListReplaceList removes the sub-list defined by the inclusive indices
9467 /// start and end and inserts the src list in its place. The inclusive 10246 /// start and end and inserts the src list in its place. The inclusive
9468 /// nature of the indices means that at least one element must be deleted 10247 /// nature of the indices means that at least one element must be deleted
9469 /// if the indices are within the bounds of the existing list. I.e. 2,2 10248 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9520,16 +10299,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9520 // based upon end. Note that if end exceeds the upper 10299 // based upon end. Note that if end exceeds the upper
9521 // bound in this case, the entire destination list 10300 // bound in this case, the entire destination list
9522 // is removed. 10301 // is removed.
9523 else 10302 else if (start == 0)
9524 { 10303 {
9525 if (end + 1 < dest.Length) 10304 if (end + 1 < dest.Length)
9526 {
9527 return src + dest.GetSublist(end + 1, -1); 10305 return src + dest.GetSublist(end + 1, -1);
9528 }
9529 else 10306 else
9530 {
9531 return src; 10307 return src;
9532 } 10308 }
10309 else // Start < 0
10310 {
10311 if (end + 1 < dest.Length)
10312 return dest.GetSublist(end + 1, -1);
10313 else
10314 return new LSL_List();
9533 } 10315 }
9534 } 10316 }
9535 // Finally, if start > end, we strip away a prefix and 10317 // Finally, if start > end, we strip away a prefix and
@@ -9580,17 +10362,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9580 int width = 0; 10362 int width = 0;
9581 int height = 0; 10363 int height = 0;
9582 10364
9583 ParcelMediaCommandEnum? commandToSend = null; 10365 uint commandToSend = 0;
9584 float time = 0.0f; // default is from start 10366 float time = 0.0f; // default is from start
9585 10367
9586 ScenePresence presence = null; 10368 ScenePresence presence = null;
9587 10369
9588 for (int i = 0; i < commandList.Data.Length; i++) 10370 for (int i = 0; i < commandList.Data.Length; i++)
9589 { 10371 {
9590 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10372 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9591 switch (command) 10373 switch (command)
9592 { 10374 {
9593 case ParcelMediaCommandEnum.Agent: 10375 case (uint)ParcelMediaCommandEnum.Agent:
9594 // we send only to one agent 10376 // we send only to one agent
9595 if ((i + 1) < commandList.Length) 10377 if ((i + 1) < commandList.Length)
9596 { 10378 {
@@ -9607,25 +10389,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9607 } 10389 }
9608 break; 10390 break;
9609 10391
9610 case ParcelMediaCommandEnum.Loop: 10392 case (uint)ParcelMediaCommandEnum.Loop:
9611 loop = 1; 10393 loop = 1;
9612 commandToSend = command; 10394 commandToSend = command;
9613 update = true; //need to send the media update packet to set looping 10395 update = true; //need to send the media update packet to set looping
9614 break; 10396 break;
9615 10397
9616 case ParcelMediaCommandEnum.Play: 10398 case (uint)ParcelMediaCommandEnum.Play:
9617 loop = 0; 10399 loop = 0;
9618 commandToSend = command; 10400 commandToSend = command;
9619 update = true; //need to send the media update packet to make sure it doesn't loop 10401 update = true; //need to send the media update packet to make sure it doesn't loop
9620 break; 10402 break;
9621 10403
9622 case ParcelMediaCommandEnum.Pause: 10404 case (uint)ParcelMediaCommandEnum.Pause:
9623 case ParcelMediaCommandEnum.Stop: 10405 case (uint)ParcelMediaCommandEnum.Stop:
9624 case ParcelMediaCommandEnum.Unload: 10406 case (uint)ParcelMediaCommandEnum.Unload:
9625 commandToSend = command; 10407 commandToSend = command;
9626 break; 10408 break;
9627 10409
9628 case ParcelMediaCommandEnum.Url: 10410 case (uint)ParcelMediaCommandEnum.Url:
9629 if ((i + 1) < commandList.Length) 10411 if ((i + 1) < commandList.Length)
9630 { 10412 {
9631 if (commandList.Data[i + 1] is LSL_String) 10413 if (commandList.Data[i + 1] is LSL_String)
@@ -9638,7 +10420,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9638 } 10420 }
9639 break; 10421 break;
9640 10422
9641 case ParcelMediaCommandEnum.Texture: 10423 case (uint)ParcelMediaCommandEnum.Texture:
9642 if ((i + 1) < commandList.Length) 10424 if ((i + 1) < commandList.Length)
9643 { 10425 {
9644 if (commandList.Data[i + 1] is LSL_String) 10426 if (commandList.Data[i + 1] is LSL_String)
@@ -9651,7 +10433,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9651 } 10433 }
9652 break; 10434 break;
9653 10435
9654 case ParcelMediaCommandEnum.Time: 10436 case (uint)ParcelMediaCommandEnum.Time:
9655 if ((i + 1) < commandList.Length) 10437 if ((i + 1) < commandList.Length)
9656 { 10438 {
9657 if (commandList.Data[i + 1] is LSL_Float) 10439 if (commandList.Data[i + 1] is LSL_Float)
@@ -9663,7 +10445,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9663 } 10445 }
9664 break; 10446 break;
9665 10447
9666 case ParcelMediaCommandEnum.AutoAlign: 10448 case (uint)ParcelMediaCommandEnum.AutoAlign:
9667 if ((i + 1) < commandList.Length) 10449 if ((i + 1) < commandList.Length)
9668 { 10450 {
9669 if (commandList.Data[i + 1] is LSL_Integer) 10451 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9677,7 +10459,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9677 } 10459 }
9678 break; 10460 break;
9679 10461
9680 case ParcelMediaCommandEnum.Type: 10462 case (uint)ParcelMediaCommandEnum.Type:
9681 if ((i + 1) < commandList.Length) 10463 if ((i + 1) < commandList.Length)
9682 { 10464 {
9683 if (commandList.Data[i + 1] is LSL_String) 10465 if (commandList.Data[i + 1] is LSL_String)
@@ -9690,7 +10472,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9690 } 10472 }
9691 break; 10473 break;
9692 10474
9693 case ParcelMediaCommandEnum.Desc: 10475 case (uint)ParcelMediaCommandEnum.Desc:
9694 if ((i + 1) < commandList.Length) 10476 if ((i + 1) < commandList.Length)
9695 { 10477 {
9696 if (commandList.Data[i + 1] is LSL_String) 10478 if (commandList.Data[i + 1] is LSL_String)
@@ -9703,7 +10485,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9703 } 10485 }
9704 break; 10486 break;
9705 10487
9706 case ParcelMediaCommandEnum.Size: 10488 case (uint)ParcelMediaCommandEnum.Size:
9707 if ((i + 2) < commandList.Length) 10489 if ((i + 2) < commandList.Length)
9708 { 10490 {
9709 if (commandList.Data[i + 1] is LSL_Integer) 10491 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9773,7 +10555,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9773 } 10555 }
9774 } 10556 }
9775 10557
9776 if (commandToSend != null) 10558 if (commandToSend != 0)
9777 { 10559 {
9778 // the commandList contained a start/stop/... command, too 10560 // the commandList contained a start/stop/... command, too
9779 if (presence == null) 10561 if (presence == null)
@@ -9810,7 +10592,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9810 10592
9811 if (aList.Data[i] != null) 10593 if (aList.Data[i] != null)
9812 { 10594 {
9813 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10595 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9814 { 10596 {
9815 case ParcelMediaCommandEnum.Url: 10597 case ParcelMediaCommandEnum.Url:
9816 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10598 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9867,15 +10649,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9867 10649
9868 if (quick_pay_buttons.Data.Length < 4) 10650 if (quick_pay_buttons.Data.Length < 4)
9869 { 10651 {
9870 LSLError("List must have at least 4 elements"); 10652 int x;
9871 return; 10653 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10654 {
10655 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10656 }
9872 } 10657 }
9873 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10658 int[] nPrice = new int[5];
9874 10659 nPrice[0] = price;
9875 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10660 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9876 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10661 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9877 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10662 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9878 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10663 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10664 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9879 m_host.ParentGroup.HasGroupChanged = true; 10665 m_host.ParentGroup.HasGroupChanged = true;
9880 } 10666 }
9881 10667
@@ -9892,7 +10678,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9892 return new LSL_Vector(); 10678 return new LSL_Vector();
9893 } 10679 }
9894 10680
9895 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10681// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10682 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9896 if (presence != null) 10683 if (presence != null)
9897 { 10684 {
9898 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10685 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9914,7 +10701,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9914 return new LSL_Rotation(); 10701 return new LSL_Rotation();
9915 } 10702 }
9916 10703
9917 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10704// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10705 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9918 if (presence != null) 10706 if (presence != null)
9919 { 10707 {
9920 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10708 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9974,14 +10762,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9974 { 10762 {
9975 m_host.AddScriptLPS(1); 10763 m_host.AddScriptLPS(1);
9976 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10764 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9977 if (detectedParams == null) return; // only works on the first detected avatar 10765 if (detectedParams == null)
9978 10766 {
10767 if (m_host.ParentGroup.IsAttachment == true)
10768 {
10769 detectedParams = new DetectParams();
10770 detectedParams.Key = m_host.OwnerID;
10771 }
10772 else
10773 {
10774 return;
10775 }
10776 }
10777
9979 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10778 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9980 if (avatar != null) 10779 if (avatar != null)
9981 { 10780 {
9982 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10781 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9983 simname, pos, lookAt); 10782 simname, pos, lookAt);
9984 } 10783 }
10784
9985 ScriptSleep(1000); 10785 ScriptSleep(1000);
9986 } 10786 }
9987 10787
@@ -10105,12 +10905,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10105 10905
10106 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10906 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10107 object[] data = rules.Data; 10907 object[] data = rules.Data;
10108 for (int i = 0; i < data.Length; ++i) { 10908 for (int i = 0; i < data.Length; ++i)
10909 {
10109 int type = Convert.ToInt32(data[i++].ToString()); 10910 int type = Convert.ToInt32(data[i++].ToString());
10110 if (i >= data.Length) break; // odd number of entries => ignore the last 10911 if (i >= data.Length) break; // odd number of entries => ignore the last
10111 10912
10112 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10913 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10113 switch (type) { 10914 switch (type)
10915 {
10114 case ScriptBaseClass.CAMERA_FOCUS: 10916 case ScriptBaseClass.CAMERA_FOCUS:
10115 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10917 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10116 case ScriptBaseClass.CAMERA_POSITION: 10918 case ScriptBaseClass.CAMERA_POSITION:
@@ -10215,19 +11017,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10215 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11017 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10216 { 11018 {
10217 m_host.AddScriptLPS(1); 11019 m_host.AddScriptLPS(1);
10218 string ret = String.Empty; 11020
10219 string src1 = llBase64ToString(str1); 11021 if (str1 == String.Empty)
10220 string src2 = llBase64ToString(str2); 11022 return String.Empty;
10221 int c = 0; 11023 if (str2 == String.Empty)
10222 for (int i = 0; i < src1.Length; i++) 11024 return str1;
11025
11026 int len = str2.Length;
11027 if ((len % 4) != 0) // LL is EVIL!!!!
11028 {
11029 while (str2.EndsWith("="))
11030 str2 = str2.Substring(0, str2.Length - 1);
11031
11032 len = str2.Length;
11033 int mod = len % 4;
11034
11035 if (mod == 1)
11036 str2 = str2.Substring(0, str2.Length - 1);
11037 else if (mod == 2)
11038 str2 += "==";
11039 else if (mod == 3)
11040 str2 += "=";
11041 }
11042
11043 byte[] data1;
11044 byte[] data2;
11045 try
10223 { 11046 {
10224 ret += (char) (src1[i] ^ src2[c]); 11047 data1 = Convert.FromBase64String(str1);
11048 data2 = Convert.FromBase64String(str2);
11049 }
11050 catch (Exception)
11051 {
11052 return new LSL_String(String.Empty);
11053 }
10225 11054
10226 c++; 11055 byte[] d2 = new Byte[data1.Length];
10227 if (c >= src2.Length) 11056 int pos = 0;
10228 c = 0; 11057
11058 if (data1.Length <= data2.Length)
11059 {
11060 Array.Copy(data2, 0, d2, 0, data1.Length);
10229 } 11061 }
10230 return llStringToBase64(ret); 11062 else
11063 {
11064 while (pos < data1.Length)
11065 {
11066 len = data1.Length - pos;
11067 if (len > data2.Length)
11068 len = data2.Length;
11069
11070 Array.Copy(data2, 0, d2, pos, len);
11071 pos += len;
11072 }
11073 }
11074
11075 for (pos = 0 ; pos < data1.Length ; pos++ )
11076 data1[pos] ^= d2[pos];
11077
11078 return Convert.ToBase64String(data1);
10231 } 11079 }
10232 11080
10233 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11081 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10280,16 +11128,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10280 if (userAgent != null) 11128 if (userAgent != null)
10281 httpHeaders["User-Agent"] = userAgent; 11129 httpHeaders["User-Agent"] = userAgent;
10282 11130
11131 // See if the URL contains any header hacks
11132 string[] urlParts = url.Split(new char[] {'\n'});
11133 if (urlParts.Length > 1)
11134 {
11135 // Iterate the passed headers and parse them
11136 for (int i = 1 ; i < urlParts.Length ; i++ )
11137 {
11138 // The rest of those would be added to the body in SL.
11139 // Let's not do that.
11140 if (urlParts[i] == String.Empty)
11141 break;
11142
11143 // See if this could be a valid header
11144 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11145 if (headerParts.Length != 2)
11146 continue;
11147
11148 string headerName = headerParts[0].Trim();
11149 string headerValue = headerParts[1].Trim();
11150
11151 // Filter out headers that could be used to abuse
11152 // another system or cloak the request
11153 if (headerName.ToLower() == "x-secondlife-shard" ||
11154 headerName.ToLower() == "x-secondlife-object-name" ||
11155 headerName.ToLower() == "x-secondlife-object-key" ||
11156 headerName.ToLower() == "x-secondlife-region" ||
11157 headerName.ToLower() == "x-secondlife-local-position" ||
11158 headerName.ToLower() == "x-secondlife-local-velocity" ||
11159 headerName.ToLower() == "x-secondlife-local-rotation" ||
11160 headerName.ToLower() == "x-secondlife-owner-name" ||
11161 headerName.ToLower() == "x-secondlife-owner-key" ||
11162 headerName.ToLower() == "connection" ||
11163 headerName.ToLower() == "content-length" ||
11164 headerName.ToLower() == "from" ||
11165 headerName.ToLower() == "host" ||
11166 headerName.ToLower() == "proxy-authorization" ||
11167 headerName.ToLower() == "referer" ||
11168 headerName.ToLower() == "trailer" ||
11169 headerName.ToLower() == "transfer-encoding" ||
11170 headerName.ToLower() == "via" ||
11171 headerName.ToLower() == "authorization")
11172 continue;
11173
11174 httpHeaders[headerName] = headerValue;
11175 }
11176
11177 // Finally, strip any protocol specifier from the URL
11178 url = urlParts[0].Trim();
11179 int idx = url.IndexOf(" HTTP/");
11180 if (idx != -1)
11181 url = url.Substring(0, idx);
11182 }
11183
10283 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11184 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10284 Regex r = new Regex(authregex); 11185 Regex r = new Regex(authregex);
10285 int[] gnums = r.GetGroupNumbers(); 11186 int[] gnums = r.GetGroupNumbers();
10286 Match m = r.Match(url); 11187 Match m = r.Match(url);
10287 if (m.Success) { 11188 if (m.Success)
10288 for (int i = 1; i < gnums.Length; i++) { 11189 {
11190 for (int i = 1; i < gnums.Length; i++)
11191 {
10289 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11192 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10290 //CaptureCollection cc = g.Captures; 11193 //CaptureCollection cc = g.Captures;
10291 } 11194 }
10292 if (m.Groups.Count == 5) { 11195 if (m.Groups.Count == 5)
11196 {
10293 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11197 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10294 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11198 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10295 } 11199 }
@@ -10492,6 +11396,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10492 11396
10493 LSL_List ret = new LSL_List(); 11397 LSL_List ret = new LSL_List();
10494 UUID key = new UUID(); 11398 UUID key = new UUID();
11399
11400
10495 if (UUID.TryParse(id, out key)) 11401 if (UUID.TryParse(id, out key))
10496 { 11402 {
10497 ScenePresence av = World.GetScenePresence(key); 11403 ScenePresence av = World.GetScenePresence(key);
@@ -10509,13 +11415,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10509 ret.Add(new LSL_String("")); 11415 ret.Add(new LSL_String(""));
10510 break; 11416 break;
10511 case ScriptBaseClass.OBJECT_POS: 11417 case ScriptBaseClass.OBJECT_POS:
10512 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11418 Vector3 avpos;
11419
11420 if (av.ParentID != 0 && av.ParentPart != null)
11421 {
11422 avpos = av.OffsetPosition;
11423
11424 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11425 avpos -= sitOffset;
11426
11427 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11428 }
11429 else
11430 avpos = av.AbsolutePosition;
11431
11432 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10513 break; 11433 break;
10514 case ScriptBaseClass.OBJECT_ROT: 11434 case ScriptBaseClass.OBJECT_ROT:
10515 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11435 Quaternion avrot = av.Rotation;
11436 if (av.ParentID != 0 && av.ParentPart != null)
11437 {
11438 avrot = av.ParentPart.GetWorldRotation() * avrot;
11439 }
11440 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10516 break; 11441 break;
10517 case ScriptBaseClass.OBJECT_VELOCITY: 11442 case ScriptBaseClass.OBJECT_VELOCITY:
10518 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11443 Vector3 avvel = av.Velocity;
11444 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10519 break; 11445 break;
10520 case ScriptBaseClass.OBJECT_OWNER: 11446 case ScriptBaseClass.OBJECT_OWNER:
10521 ret.Add(new LSL_String(id)); 11447 ret.Add(new LSL_String(id));
@@ -10600,11 +11526,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10600 case ScriptBaseClass.OBJECT_NAME: 11526 case ScriptBaseClass.OBJECT_NAME:
10601 ret.Add(new LSL_String(obj.Name)); 11527 ret.Add(new LSL_String(obj.Name));
10602 break; 11528 break;
10603 case ScriptBaseClass.OBJECT_DESC: 11529 case ScriptBaseClass.OBJECT_DESC:
10604 ret.Add(new LSL_String(obj.Description)); 11530 ret.Add(new LSL_String(obj.Description));
10605 break; 11531 break;
10606 case ScriptBaseClass.OBJECT_POS: 11532 case ScriptBaseClass.OBJECT_POS:
10607 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11533 Vector3 opos = obj.AbsolutePosition;
11534 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10608 break; 11535 break;
10609 case ScriptBaseClass.OBJECT_ROT: 11536 case ScriptBaseClass.OBJECT_ROT:
10610 { 11537 {
@@ -10654,9 +11581,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10654 // The value returned in SL for normal prims is prim count 11581 // The value returned in SL for normal prims is prim count
10655 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11582 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10656 break; 11583 break;
10657 // The following 3 costs I have intentionaly coded to return zero. They are part of 11584
10658 // "Land Impact" calculations. These calculations are probably not applicable 11585 // costs below may need to be diferent for root parts, need to check
10659 // to OpenSim and are not yet complete in SL
10660 case ScriptBaseClass.OBJECT_SERVER_COST: 11586 case ScriptBaseClass.OBJECT_SERVER_COST:
10661 // The linden calculation is here 11587 // The linden calculation is here
10662 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11588 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10664,16 +11590,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10664 ret.Add(new LSL_Float(0)); 11590 ret.Add(new LSL_Float(0));
10665 break; 11591 break;
10666 case ScriptBaseClass.OBJECT_STREAMING_COST: 11592 case ScriptBaseClass.OBJECT_STREAMING_COST:
10667 // The linden calculation is here 11593 // The value returned in SL for normal prims is prim count * 0.06
10668 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11594 ret.Add(new LSL_Float(obj.StreamingCost));
10669 // The value returned in SL for normal prims looks like the prim count * 0.06
10670 ret.Add(new LSL_Float(0));
10671 break; 11595 break;
10672 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11596 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10673 // The linden calculation is here 11597 // The value returned in SL for normal prims is prim count
10674 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11598 ret.Add(new LSL_Float(obj.PhysicsCost));
10675 // The value returned in SL for normal prims looks like the prim count
10676 ret.Add(new LSL_Float(0));
10677 break; 11599 break;
10678 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11600 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
10679 ret.Add(new LSL_Float(0)); 11601 ret.Add(new LSL_Float(0));
@@ -10930,15 +11852,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10930 return result; 11852 return result;
10931 } 11853 }
10932 11854
10933 public void print(string str) 11855 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10934 { 11856 {
10935 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11857 List<SceneObjectPart> parts = GetLinkParts(link);
10936 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11858 if (parts.Count < 1)
10937 if (ossl != null) 11859 return 0;
10938 { 11860
10939 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11861 return GetNumberOfSides(parts[0]);
10940 m_log.Info("LSL print():" + str);
10941 }
10942 } 11862 }
10943 11863
10944 private string Name2Username(string name) 11864 private string Name2Username(string name)
@@ -10983,7 +11903,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10983 11903
10984 return rq.ToString(); 11904 return rq.ToString();
10985 } 11905 }
10986 11906/*
11907 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11908 {
11909 m_SayShoutCount = 0;
11910 }
11911*/
10987 private struct Tri 11912 private struct Tri
10988 { 11913 {
10989 public Vector3 p1; 11914 public Vector3 p1;
@@ -11132,9 +12057,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11132 12057
11133 ContactResult result = new ContactResult (); 12058 ContactResult result = new ContactResult ();
11134 result.ConsumerID = group.LocalId; 12059 result.ConsumerID = group.LocalId;
11135 result.Depth = intersection.distance; 12060// result.Depth = intersection.distance;
11136 result.Normal = intersection.normal; 12061 result.Normal = intersection.normal;
11137 result.Pos = intersection.ipoint; 12062 result.Pos = intersection.ipoint;
12063 result.Depth = Vector3.Mag(rayStart - result.Pos);
11138 12064
11139 contacts.Add(result); 12065 contacts.Add(result);
11140 }); 12066 });
@@ -11267,6 +12193,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11267 12193
11268 return contacts[0]; 12194 return contacts[0];
11269 } 12195 }
12196/*
12197 // not done:
12198 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12199 {
12200 ContactResult[] contacts = null;
12201 World.ForEachSOG(delegate(SceneObjectGroup group)
12202 {
12203 if (m_host.ParentGroup == group)
12204 return;
12205
12206 if (group.IsAttachment)
12207 return;
12208
12209 if(group.RootPart.PhysActor != null)
12210 return;
12211
12212 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12213 });
12214 return contacts;
12215 }
12216*/
11270 12217
11271 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12218 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11272 { 12219 {
@@ -11390,18 +12337,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11390 } 12337 }
11391 } 12338 }
11392 12339
12340 // Double check this
11393 if (checkTerrain) 12341 if (checkTerrain)
11394 { 12342 {
11395 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12343 bool skipGroundCheck = false;
11396 if (groundContact != null) 12344
11397 results.Add((ContactResult)groundContact); 12345 foreach (ContactResult c in results)
12346 {
12347 if (c.ConsumerID == 0) // Physics gave us a ground collision
12348 skipGroundCheck = true;
12349 }
12350
12351 if (!skipGroundCheck)
12352 {
12353 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12354 if (groundContact != null)
12355 results.Add((ContactResult)groundContact);
12356 }
11398 } 12357 }
11399 12358
11400 results.Sort(delegate(ContactResult a, ContactResult b) 12359 results.Sort(delegate(ContactResult a, ContactResult b)
11401 { 12360 {
11402 return a.Depth.CompareTo(b.Depth); 12361 return a.Depth.CompareTo(b.Depth);
11403 }); 12362 });
11404 12363
11405 int values = 0; 12364 int values = 0;
11406 SceneObjectGroup thisgrp = m_host.ParentGroup; 12365 SceneObjectGroup thisgrp = m_host.ParentGroup;
11407 12366
@@ -11494,7 +12453,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11494 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12453 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11495 if (!isAccount) return 0; 12454 if (!isAccount) return 0;
11496 if (estate.HasAccess(id)) return 1; 12455 if (estate.HasAccess(id)) return 1;
11497 if (estate.IsBanned(id)) 12456 if (estate.IsBanned(id, World.GetUserFlags(id)))
11498 estate.RemoveBan(id); 12457 estate.RemoveBan(id);
11499 estate.AddEstateUser(id); 12458 estate.AddEstateUser(id);
11500 break; 12459 break;
@@ -11513,14 +12472,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11513 break; 12472 break;
11514 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12473 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11515 if (!isAccount) return 0; 12474 if (!isAccount) return 0;
11516 if (estate.IsBanned(id)) return 1; 12475 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11517 EstateBan ban = new EstateBan(); 12476 EstateBan ban = new EstateBan();
11518 ban.EstateID = estate.EstateID; 12477 ban.EstateID = estate.EstateID;
11519 ban.BannedUserID = id; 12478 ban.BannedUserID = id;
11520 estate.AddBan(ban); 12479 estate.AddBan(ban);
11521 break; 12480 break;
11522 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12481 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11523 if (!isAccount || !estate.IsBanned(id)) return 0; 12482 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11524 estate.RemoveBan(id); 12483 estate.RemoveBan(id);
11525 break; 12484 break;
11526 default: return 0; 12485 default: return 0;
@@ -11549,7 +12508,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11549 return 16384; 12508 return 16384;
11550 } 12509 }
11551 12510
11552 public LSL_Integer llGetUsedMemory() 12511 public virtual LSL_Integer llGetUsedMemory()
11553 { 12512 {
11554 m_host.AddScriptLPS(1); 12513 m_host.AddScriptLPS(1);
11555 // The value returned for LSO scripts in SL 12514 // The value returned for LSO scripts in SL
@@ -11577,19 +12536,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11577 public void llSetSoundQueueing(int queue) 12536 public void llSetSoundQueueing(int queue)
11578 { 12537 {
11579 m_host.AddScriptLPS(1); 12538 m_host.AddScriptLPS(1);
11580 NotImplemented("llSetSoundQueueing");
11581 } 12539 }
11582 12540
11583 public void llCollisionSprite(string impact_sprite) 12541 public void llCollisionSprite(string impact_sprite)
11584 { 12542 {
11585 m_host.AddScriptLPS(1); 12543 m_host.AddScriptLPS(1);
11586 NotImplemented("llCollisionSprite"); 12544 // Viewer 2.0 broke this and it's likely LL has no intention
12545 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11587 } 12546 }
11588 12547
11589 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12548 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11590 { 12549 {
11591 m_host.AddScriptLPS(1); 12550 m_host.AddScriptLPS(1);
11592 NotImplemented("llGodLikeRezObject"); 12551
12552 if (!World.Permissions.IsGod(m_host.OwnerID))
12553 NotImplemented("llGodLikeRezObject");
12554
12555 AssetBase rezAsset = World.AssetService.Get(inventory);
12556 if (rezAsset == null)
12557 {
12558 llSay(0, "Asset not found");
12559 return;
12560 }
12561
12562 SceneObjectGroup group = null;
12563
12564 try
12565 {
12566 string xmlData = Utils.BytesToString(rezAsset.Data);
12567 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12568 }
12569 catch
12570 {
12571 llSay(0, "Asset not found");
12572 return;
12573 }
12574
12575 if (group == null)
12576 {
12577 llSay(0, "Asset not found");
12578 return;
12579 }
12580
12581 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12582 group.RootPart.AttachOffset = group.AbsolutePosition;
12583
12584 group.ResetIDs();
12585
12586 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12587 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12588 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12589 group.ScheduleGroupForFullUpdate();
12590
12591 // objects rezzed with this method are die_at_edge by default.
12592 group.RootPart.SetDieAtEdge(true);
12593
12594 group.ResumeScripts();
12595
12596 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12597 "object_rez", new Object[] {
12598 new LSL_String(
12599 group.RootPart.UUID.ToString()) },
12600 new DetectParams[0]));
11593 } 12601 }
11594 12602
11595 public LSL_String llTransferLindenDollars(string destination, int amount) 12603 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -11641,7 +12649,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11641 } 12649 }
11642 12650
11643 bool result = money.ObjectGiveMoney( 12651 bool result = money.ObjectGiveMoney(
11644 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12652 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn);
11645 12653
11646 if (result) 12654 if (result)
11647 { 12655 {
@@ -11666,6 +12674,598 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11666 } 12674 }
11667 12675
11668 #endregion 12676 #endregion
12677
12678 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12679 {
12680 SceneObjectGroup group = m_host.ParentGroup;
12681
12682 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12683 return;
12684 if (group.IsAttachment)
12685 return;
12686
12687 if (frames.Data.Length > 0) // We are getting a new motion
12688 {
12689 if (group.RootPart.KeyframeMotion != null)
12690 group.RootPart.KeyframeMotion.Delete();
12691 group.RootPart.KeyframeMotion = null;
12692
12693 int idx = 0;
12694
12695 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12696 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12697
12698 while (idx < options.Data.Length)
12699 {
12700 int option = (int)options.GetLSLIntegerItem(idx++);
12701 int remain = options.Data.Length - idx;
12702
12703 switch (option)
12704 {
12705 case ScriptBaseClass.KFM_MODE:
12706 if (remain < 1)
12707 break;
12708 int modeval = (int)options.GetLSLIntegerItem(idx++);
12709 switch(modeval)
12710 {
12711 case ScriptBaseClass.KFM_FORWARD:
12712 mode = KeyframeMotion.PlayMode.Forward;
12713 break;
12714 case ScriptBaseClass.KFM_REVERSE:
12715 mode = KeyframeMotion.PlayMode.Reverse;
12716 break;
12717 case ScriptBaseClass.KFM_LOOP:
12718 mode = KeyframeMotion.PlayMode.Loop;
12719 break;
12720 case ScriptBaseClass.KFM_PING_PONG:
12721 mode = KeyframeMotion.PlayMode.PingPong;
12722 break;
12723 }
12724 break;
12725 case ScriptBaseClass.KFM_DATA:
12726 if (remain < 1)
12727 break;
12728 int dataval = (int)options.GetLSLIntegerItem(idx++);
12729 data = (KeyframeMotion.DataFormat)dataval;
12730 break;
12731 }
12732 }
12733
12734 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12735
12736 idx = 0;
12737
12738 int elemLength = 2;
12739 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12740 elemLength = 3;
12741
12742 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12743 while (idx < frames.Data.Length)
12744 {
12745 int remain = frames.Data.Length - idx;
12746
12747 if (remain < elemLength)
12748 break;
12749
12750 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12751 frame.Position = null;
12752 frame.Rotation = null;
12753
12754 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12755 {
12756 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12757 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12758 }
12759 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12760 {
12761 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12762 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12763 q.Normalize();
12764 frame.Rotation = q;
12765 }
12766
12767 float tempf = (float)frames.GetLSLFloatItem(idx++);
12768 frame.TimeMS = (int)(tempf * 1000.0f);
12769
12770 keyframes.Add(frame);
12771 }
12772
12773 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12774 group.RootPart.KeyframeMotion.Start();
12775 }
12776 else
12777 {
12778 if (group.RootPart.KeyframeMotion == null)
12779 return;
12780
12781 if (options.Data.Length == 0)
12782 {
12783 group.RootPart.KeyframeMotion.Stop();
12784 return;
12785 }
12786
12787 int code = (int)options.GetLSLIntegerItem(0);
12788
12789 int idx = 0;
12790
12791 while (idx < options.Data.Length)
12792 {
12793 int option = (int)options.GetLSLIntegerItem(idx++);
12794 int remain = options.Data.Length - idx;
12795
12796 switch (option)
12797 {
12798 case ScriptBaseClass.KFM_COMMAND:
12799 int cmd = (int)options.GetLSLIntegerItem(idx++);
12800 switch (cmd)
12801 {
12802 case ScriptBaseClass.KFM_CMD_PLAY:
12803 group.RootPart.KeyframeMotion.Start();
12804 break;
12805 case ScriptBaseClass.KFM_CMD_STOP:
12806 group.RootPart.KeyframeMotion.Stop();
12807 break;
12808 case ScriptBaseClass.KFM_CMD_PAUSE:
12809 group.RootPart.KeyframeMotion.Pause();
12810 break;
12811 }
12812 break;
12813 }
12814 }
12815 }
12816 }
12817
12818 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12819 {
12820 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12821
12822 int idx = 0;
12823 int idxStart = 0;
12824
12825 bool positionChanged = false;
12826 Vector3 finalPos = Vector3.Zero;
12827
12828 try
12829 {
12830 while (idx < rules.Length)
12831 {
12832 ++rulesParsed;
12833 int code = rules.GetLSLIntegerItem(idx++);
12834
12835 int remain = rules.Length - idx;
12836 idxStart = idx;
12837
12838 switch (code)
12839 {
12840 case (int)ScriptBaseClass.PRIM_POSITION:
12841 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12842 {
12843 if (remain < 1)
12844 return null;
12845
12846 LSL_Vector v;
12847 v = rules.GetVector3Item(idx++);
12848
12849 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12850 if (part == null)
12851 break;
12852
12853 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12854 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12855 if (part.LinkNum > 1)
12856 {
12857 localRot = GetPartLocalRot(part);
12858 localPos = GetPartLocalPos(part);
12859 }
12860
12861 v -= localPos;
12862 v /= localRot;
12863
12864 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12865
12866 v = v + 2 * sitOffset;
12867
12868 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12869 av.SendAvatarDataToAllAgents();
12870
12871 }
12872 break;
12873
12874 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12875 case (int)ScriptBaseClass.PRIM_ROTATION:
12876 {
12877 if (remain < 1)
12878 return null;
12879
12880 LSL_Rotation r;
12881 r = rules.GetQuaternionItem(idx++);
12882
12883 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12884 if (part == null)
12885 break;
12886
12887 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12888 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12889
12890 if (part.LinkNum > 1)
12891 localRot = GetPartLocalRot(part);
12892
12893 r = r * llGetRootRotation() / localRot;
12894 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12895 av.SendAvatarDataToAllAgents();
12896 }
12897 break;
12898
12899 // parse rest doing nothing but number of parameters error check
12900 case (int)ScriptBaseClass.PRIM_SIZE:
12901 case (int)ScriptBaseClass.PRIM_MATERIAL:
12902 case (int)ScriptBaseClass.PRIM_PHANTOM:
12903 case (int)ScriptBaseClass.PRIM_PHYSICS:
12904 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12905 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12906 case (int)ScriptBaseClass.PRIM_NAME:
12907 case (int)ScriptBaseClass.PRIM_DESC:
12908 if (remain < 1)
12909 return null;
12910 idx++;
12911 break;
12912
12913 case (int)ScriptBaseClass.PRIM_GLOW:
12914 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12915 case (int)ScriptBaseClass.PRIM_TEXGEN:
12916 if (remain < 2)
12917 return null;
12918 idx += 2;
12919 break;
12920
12921 case (int)ScriptBaseClass.PRIM_TYPE:
12922 if (remain < 3)
12923 return null;
12924 code = (int)rules.GetLSLIntegerItem(idx++);
12925 remain = rules.Length - idx;
12926 switch (code)
12927 {
12928 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12929 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12930 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12931 if (remain < 6)
12932 return null;
12933 idx += 6;
12934 break;
12935
12936 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12937 if (remain < 5)
12938 return null;
12939 idx += 5;
12940 break;
12941
12942 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12943 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12944 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12945 if (remain < 11)
12946 return null;
12947 idx += 11;
12948 break;
12949
12950 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12951 if (remain < 2)
12952 return null;
12953 idx += 2;
12954 break;
12955 }
12956 break;
12957
12958 case (int)ScriptBaseClass.PRIM_COLOR:
12959 case (int)ScriptBaseClass.PRIM_TEXT:
12960 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12961 case (int)ScriptBaseClass.PRIM_OMEGA:
12962 if (remain < 3)
12963 return null;
12964 idx += 3;
12965 break;
12966
12967 case (int)ScriptBaseClass.PRIM_TEXTURE:
12968 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12969 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12970 if (remain < 5)
12971 return null;
12972 idx += 5;
12973 break;
12974
12975 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12976 if (remain < 7)
12977 return null;
12978
12979 idx += 7;
12980 break;
12981
12982 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12983 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12984 return null;
12985
12986 return rules.GetSublist(idx, -1);
12987 }
12988 }
12989 }
12990 catch (InvalidCastException e)
12991 {
12992 ShoutError(string.Format(
12993 "{0} error running rule #{1}: arg #{2} ",
12994 originFunc, rulesParsed, idx - idxStart) + e.Message);
12995 }
12996 finally
12997 {
12998 if (positionChanged)
12999 {
13000 av.OffsetPosition = finalPos;
13001// av.SendAvatarDataToAllAgents();
13002 av.SendTerseUpdateToAllClients();
13003 positionChanged = false;
13004 }
13005 }
13006 return null;
13007 }
13008
13009 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13010 {
13011 // avatars case
13012 // replies as SL wiki
13013
13014// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13015 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13016
13017 int idx = 0;
13018 while (idx < rules.Length)
13019 {
13020 int code = (int)rules.GetLSLIntegerItem(idx++);
13021 int remain = rules.Length - idx;
13022
13023 switch (code)
13024 {
13025 case (int)ScriptBaseClass.PRIM_MATERIAL:
13026 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13027 break;
13028
13029 case (int)ScriptBaseClass.PRIM_PHYSICS:
13030 res.Add(new LSL_Integer(0));
13031 break;
13032
13033 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13034 res.Add(new LSL_Integer(0));
13035 break;
13036
13037 case (int)ScriptBaseClass.PRIM_PHANTOM:
13038 res.Add(new LSL_Integer(0));
13039 break;
13040
13041 case (int)ScriptBaseClass.PRIM_POSITION:
13042
13043 Vector3 pos = avatar.OffsetPosition;
13044
13045 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13046 pos -= sitOffset;
13047
13048 if( sitPart != null)
13049 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13050
13051 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13052 break;
13053
13054 case (int)ScriptBaseClass.PRIM_SIZE:
13055 // as in llGetAgentSize above
13056// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13057 Vector3 s = avatar.Appearance.AvatarSize;
13058 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13059
13060 break;
13061
13062 case (int)ScriptBaseClass.PRIM_ROTATION:
13063 Quaternion rot = avatar.Rotation;
13064 if (sitPart != null)
13065 {
13066 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13067 }
13068
13069 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13070 break;
13071
13072 case (int)ScriptBaseClass.PRIM_TYPE:
13073 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13074 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13075 res.Add(new LSL_Vector(0f,1.0f,0f));
13076 res.Add(new LSL_Float(0.0f));
13077 res.Add(new LSL_Vector(0, 0, 0));
13078 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13079 res.Add(new LSL_Vector(0, 0, 0));
13080 break;
13081
13082 case (int)ScriptBaseClass.PRIM_TEXTURE:
13083 if (remain < 1)
13084 return null;
13085
13086 int face = (int)rules.GetLSLIntegerItem(idx++);
13087 if (face == ScriptBaseClass.ALL_SIDES)
13088 {
13089 for (face = 0; face < 21; face++)
13090 {
13091 res.Add(new LSL_String(""));
13092 res.Add(new LSL_Vector(0,0,0));
13093 res.Add(new LSL_Vector(0,0,0));
13094 res.Add(new LSL_Float(0.0));
13095 }
13096 }
13097 else
13098 {
13099 if (face >= 0 && face < 21)
13100 {
13101 res.Add(new LSL_String(""));
13102 res.Add(new LSL_Vector(0,0,0));
13103 res.Add(new LSL_Vector(0,0,0));
13104 res.Add(new LSL_Float(0.0));
13105 }
13106 }
13107 break;
13108
13109 case (int)ScriptBaseClass.PRIM_COLOR:
13110 if (remain < 1)
13111 return null;
13112
13113 face = (int)rules.GetLSLIntegerItem(idx++);
13114
13115 if (face == ScriptBaseClass.ALL_SIDES)
13116 {
13117 for (face = 0; face < 21; face++)
13118 {
13119 res.Add(new LSL_Vector(0,0,0));
13120 res.Add(new LSL_Float(0));
13121 }
13122 }
13123 else
13124 {
13125 res.Add(new LSL_Vector(0,0,0));
13126 res.Add(new LSL_Float(0));
13127 }
13128 break;
13129
13130 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13131 if (remain < 1)
13132 return null;
13133 face = (int)rules.GetLSLIntegerItem(idx++);
13134
13135 if (face == ScriptBaseClass.ALL_SIDES)
13136 {
13137 for (face = 0; face < 21; face++)
13138 {
13139 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13140 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13141 }
13142 }
13143 else
13144 {
13145 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13146 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13147 }
13148 break;
13149
13150 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13151 if (remain < 1)
13152 return null;
13153 face = (int)rules.GetLSLIntegerItem(idx++);
13154
13155 if (face == ScriptBaseClass.ALL_SIDES)
13156 {
13157 for (face = 0; face < 21; face++)
13158 {
13159 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13160 }
13161 }
13162 else
13163 {
13164 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13165 }
13166 break;
13167
13168 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13169 res.Add(new LSL_Integer(0));
13170 res.Add(new LSL_Integer(0));// softness
13171 res.Add(new LSL_Float(0.0f)); // gravity
13172 res.Add(new LSL_Float(0.0f)); // friction
13173 res.Add(new LSL_Float(0.0f)); // wind
13174 res.Add(new LSL_Float(0.0f)); // tension
13175 res.Add(new LSL_Vector(0f,0f,0f));
13176 break;
13177
13178 case (int)ScriptBaseClass.PRIM_TEXGEN:
13179 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
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.PRIM_TEXGEN_DEFAULT));
13189 }
13190 }
13191 else
13192 {
13193 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13194 }
13195 break;
13196
13197 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13198 res.Add(new LSL_Integer(0));
13199 res.Add(new LSL_Vector(0f,0f,0f));
13200 res.Add(new LSL_Float(0f)); // intensity
13201 res.Add(new LSL_Float(0f)); // radius
13202 res.Add(new LSL_Float(0f)); // falloff
13203 break;
13204
13205 case (int)ScriptBaseClass.PRIM_GLOW:
13206 if (remain < 1)
13207 return null;
13208 face = (int)rules.GetLSLIntegerItem(idx++);
13209
13210 if (face == ScriptBaseClass.ALL_SIDES)
13211 {
13212 for (face = 0; face < 21; face++)
13213 {
13214 res.Add(new LSL_Float(0f));
13215 }
13216 }
13217 else
13218 {
13219 res.Add(new LSL_Float(0f));
13220 }
13221 break;
13222
13223 case (int)ScriptBaseClass.PRIM_TEXT:
13224 res.Add(new LSL_String(""));
13225 res.Add(new LSL_Vector(0f,0f,0f));
13226 res.Add(new LSL_Float(1.0f));
13227 break;
13228
13229 case (int)ScriptBaseClass.PRIM_NAME:
13230 res.Add(new LSL_String(avatar.Name));
13231 break;
13232
13233 case (int)ScriptBaseClass.PRIM_DESC:
13234 res.Add(new LSL_String(""));
13235 break;
13236
13237 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13238 Quaternion lrot = avatar.Rotation;
13239
13240 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13241 {
13242 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13243 }
13244 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13245 break;
13246
13247 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13248 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13249 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13250 lpos -= lsitOffset;
13251
13252 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13253 {
13254 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13255 }
13256 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13257 break;
13258
13259 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13260 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13261 return null;
13262
13263 return rules.GetSublist(idx, -1);
13264 }
13265 }
13266
13267 return null;
13268 }
11669 } 13269 }
11670 13270
11671 public class NotecardCache 13271 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 1426070..6ff6b00 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);
@@ -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.
@@ -2342,7 +2377,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2342 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2377 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2343 m_host.AddScriptLPS(1); 2378 m_host.AddScriptLPS(1);
2344 2379
2345 return NpcCreate(firstname, lastname, position, notecard, false, false); 2380 return NpcCreate(firstname, lastname, position, notecard, true, false);
2346 } 2381 }
2347 2382
2348 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2383 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2353,24 +2388,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2353 return NpcCreate( 2388 return NpcCreate(
2354 firstname, lastname, position, notecard, 2389 firstname, lastname, position, notecard,
2355 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2390 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2356 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2391 false);
2392// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2357 } 2393 }
2358 2394
2359 private LSL_Key NpcCreate( 2395 private LSL_Key NpcCreate(
2360 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2396 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2361 { 2397 {
2398 if (!owned)
2399 OSSLError("Unowned NPCs are unsupported");
2400
2401 string groupTitle = String.Empty;
2402
2403 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2404 return new LSL_Key(UUID.Zero.ToString());
2405
2406 if (firstname != String.Empty || lastname != String.Empty)
2407 {
2408 if (firstname != "Shown outfit:")
2409 groupTitle = "- NPC -";
2410 }
2411
2362 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2412 INPCModule module = World.RequestModuleInterface<INPCModule>();
2363 if (module != null) 2413 if (module != null)
2364 { 2414 {
2365 AvatarAppearance appearance = null; 2415 AvatarAppearance appearance = null;
2366 2416
2367 UUID id; 2417// UUID id;
2368 if (UUID.TryParse(notecard, out id)) 2418// if (UUID.TryParse(notecard, out id))
2369 { 2419// {
2370 ScenePresence clonePresence = World.GetScenePresence(id); 2420// ScenePresence clonePresence = World.GetScenePresence(id);
2371 if (clonePresence != null) 2421// if (clonePresence != null)
2372 appearance = clonePresence.Appearance; 2422// appearance = clonePresence.Appearance;
2373 } 2423// }
2374 2424
2375 if (appearance == null) 2425 if (appearance == null)
2376 { 2426 {
@@ -2378,9 +2428,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2378 2428
2379 if (appearanceSerialized != null) 2429 if (appearanceSerialized != null)
2380 { 2430 {
2381 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2431 try
2382 appearance = new AvatarAppearance(); 2432 {
2383 appearance.Unpack(appearanceOsd); 2433 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2434 appearance = new AvatarAppearance();
2435 appearance.Unpack(appearanceOsd);
2436 }
2437 catch
2438 {
2439 return UUID.Zero.ToString();
2440 }
2384 } 2441 }
2385 else 2442 else
2386 { 2443 {
@@ -2399,6 +2456,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2399 World, 2456 World,
2400 appearance); 2457 appearance);
2401 2458
2459 ScenePresence sp;
2460 if (World.TryGetScenePresence(x, out sp))
2461 {
2462 sp.Grouptitle = groupTitle;
2463 sp.SendAvatarDataToAllAgents();
2464 }
2402 return new LSL_Key(x.ToString()); 2465 return new LSL_Key(x.ToString());
2403 } 2466 }
2404 2467
@@ -2702,16 +2765,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2702 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2765 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2703 m_host.AddScriptLPS(1); 2766 m_host.AddScriptLPS(1);
2704 2767
2705 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2768 ManualResetEvent ev = new ManualResetEvent(false);
2706 if (module != null)
2707 {
2708 UUID npcId = new UUID(npc.m_string);
2709 2769
2710 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2770 Util.FireAndForget(delegate(object x) {
2711 return; 2771 try
2772 {
2773 INPCModule module = World.RequestModuleInterface<INPCModule>();
2774 if (module != null)
2775 {
2776 UUID npcId = new UUID(npc.m_string);
2712 2777
2713 module.DeleteNPC(npcId, World); 2778 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2714 } 2779 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2780 {
2781 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2782 return;
2783 }
2784
2785 module.DeleteNPC(npcId, World);
2786 }
2787 }
2788 finally
2789 {
2790 ev.Set();
2791 }
2792 });
2793 ev.WaitOne();
2715 } 2794 }
2716 2795
2717 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2796 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 dd45406..d3ef378 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.Rotation * 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.Rotation * 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)
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..7eb347e 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);
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/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 {